Skip to main content

## contains_illegal_self_type_reference

# Function contains_illegal_self_type_reference

Source

    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

Check if the given value contains illegal `Self` references.

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 trait object type itself.

The same thing holds for associated consts under feature `min_generic_const_args`.

ⓘ

    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.