RFC: Towards unified semantic for casts

Hi everyone,

I have an idea that should allow reducing code duplication in Casting.h while making llvm::isa, llvm::cast, llvm::dyn_cast, etc more generic. Since we added unique pointers support for these template functions (see ab480f45cd23c08cb9aa3f427aad072df249135f) I propose to generalize their semantics to deal with any pointer-like type (i.e. dereferenceable and implicitly convertible to bool) so that:

  • for each fancy_pointer t: isa(t) returns true iff current implementation of isa(nonfancy_t) returns true where decltype(nonfancy_t) is T*
  • all old cast operations should return a raw pointer of type typename std::pointer_traits<fancy_pointer>::element_type * and do not perform ownership transfer.
  • move_[dyn_]cast should do what unique_dyn_cast is currently doing in a more generic manner: it moves to an object of type typename std::pointer_traits<fancy_pointer>::rebind

N.B. std::pointer_traits is a conception that I use to explain the behaviour - not necessary the way I plan to implement it.

An example implementation of the proposal for llvm::isa : https://reviews.llvm.org/D42027

Looks pretty reasonable to me - with test cases. (not sure if dereferenced_type should be defined for a type that’s not dereferenceable, though?)

Agreed, it probably shouldn’t. Then we can use the detection idiom (e.g. std::experimental::detected_or) with it in future. I updated the review.