If you have e.g. expression templates, then the upcast to the implementing class needs to be done with unsafe_narrow.
Maybe an alias of unsafe_narrow like unsafe_cast, 'unsafe_pointer_cast` or something like that could be introduced.
Example: https://cpp2.godbolt.org/z/jb1MY3Mcq
Exp : <Impl> type = {
cast: (this) -> forward Impl = cpp2::unsafe_narrow<Impl>(this&)*; // unsafe_narrow does not really express what this cast is.
}
A : type = {
this: Exp<A> = ();
foo: (this) = std::cout << "foo" << std::endl;
}
main: () -> int = {
a: A = ();
e: *Exp<A> = a&;
e*.cast().foo();
return 0;
}