fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
tcx: TyCtxt<'tcx>,
trait_def_id: DefId,
value: T,
allow_self_projections: AllowSelfProjections,
) -> bool
Expand description
This is somewhat subtle. In general, we want to forbid
references to Self
in the argument and return types,
since the value of Self
is erased. However, there is one
exception: it is ok to reference Self
in order to access
an associated type of the current trait, since we retain
the value of those associated types in the object type
itself.
ⓘ
trait SuperTrait {
type X;
}
trait Trait : SuperTrait {
type Y;
fn foo(&self, x: Self) // bad
fn foo(&self) -> Self // bad
fn foo(&self) -> Option<Self> // bad
fn foo(&self) -> Self::Y // OK, desugars to next example
fn foo(&self) -> <Self as Trait>::Y // OK
fn foo(&self) -> Self::X // OK, desugars to next example
fn foo(&self) -> <Self as SuperTrait>::X // OK
}
However, it is not as simple as allowing Self
in a projected
type, because there are illegal ways to use Self
as well:
ⓘ
trait Trait : SuperTrait {
...
fn foo(&self) -> <Self as SomeOtherTrait>::X;
}
Here we will not have the type of X
recorded in the
object type, and we cannot resolve Self as SomeOtherTrait
without knowing what Self
is.