rustc_infer::infer::relate::generalize

Struct Generalizer

source
struct Generalizer<'me, 'tcx> {
    infcx: &'me InferCtxt<'tcx>,
    span: Span,
    structurally_relate_aliases: StructurallyRelateAliases,
    root_vid: TermVid,
    for_universe: UniverseIndex,
    root_term: Term<'tcx>,
    ambient_variance: Variance,
    in_alias: bool,
    cache: SsoHashMap<(Ty<'tcx>, Variance, bool), Ty<'tcx>>,
    has_unconstrained_ty_var: bool,
}
Expand description

The “generalizer” is used when handling inference variables.

The basic strategy for handling a constraint like ?A <: B is to apply a “generalization strategy” to the term B – this replaces all the lifetimes in the term B with fresh inference variables. (You can read more about the strategy in this blog post.)

As an example, if we had ?A <: &'x u32, we would generalize &'x u32 to &'0 u32 where '0 is a fresh variable. This becomes the value of A. Finally, we relate &'0 u32 <: &'x u32, which establishes '0: 'x as a constraint.

Fields§

§infcx: &'me InferCtxt<'tcx>§span: Span§structurally_relate_aliases: StructurallyRelateAliases

Whether aliases should be related structurally. If not, we have to be careful when generalizing aliases.

§root_vid: TermVid

The vid of the type variable that is in the process of being instantiated. If we find this within the value we are folding, that means we would have created a cyclic value.

§for_universe: UniverseIndex

The universe of the type variable that is in the process of being instantiated. If we find anything that this universe cannot name, we reject the relation.

§root_term: Term<'tcx>

The root term (const or type) we’re generalizing. Used for cycle errors.

§ambient_variance: Variance

After we generalize this type, we are going to relate it to some other type. What will be the variance at this point?

§in_alias: bool

This is set once we’re generalizing the arguments of an alias.

This is necessary to correctly handle <T as Bar<<?0 as Foo>::Assoc>::Assoc == ?0. This equality can hold by either normalizing the outer or the inner associated type.

§cache: SsoHashMap<(Ty<'tcx>, Variance, bool), Ty<'tcx>>§has_unconstrained_ty_var: bool

See the field has_unconstrained_ty_var in Generalization.

Implementations§

source§

impl<'tcx> Generalizer<'_, 'tcx>

source

fn cyclic_term_error(&self) -> TypeError<'tcx>

Create an error that corresponds to the term kind in root_term

source

fn next_ty_var_for_alias(&mut self) -> Ty<'tcx>

Create a new type variable in the universe of the target when generalizing an alias. This has to set has_unconstrained_ty_var if we’re currently in a bivariant context.

source

fn generalize_alias_ty( &mut self, alias: AliasTy<'tcx>, ) -> Result<Ty<'tcx>, TypeError<'tcx>>

An occurs check failure inside of an alias does not mean that the types definitely don’t unify. We may be able to normalize the alias after all.

We handle this by lazily equating the alias and generalizing it to an inference variable. In the new solver, we always generalize to an infer var unless the alias contains escaping bound variables.

Correctly handling aliases with escaping bound variables is difficult and currently incomplete in two opposite ways:

  • if we get an occurs check failure in the alias, replace it with a new infer var. This causes us to later emit an alias-relate goal and is incomplete in case the alias normalizes to type containing one of the bound variables.
  • if the alias contains an inference variable not nameable by for_universe, we continue generalizing the alias. This ends up pulling down the universe of the inference variable and is incomplete in case the alias would normalize to a type which does not mention that inference variable.

Trait Implementations§

source§

impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx>

source§

fn cx(&self) -> TyCtxt<'tcx>

source§

fn relate_item_args( &mut self, item_def_id: DefId, a_arg: GenericArgsRef<'tcx>, b_arg: GenericArgsRef<'tcx>, ) -> RelateResult<'tcx, GenericArgsRef<'tcx>>

Relate the two args for the given item. The default is to look up the variance for the item and proceed accordingly.
source§

fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>( &mut self, variance: Variance, _info: VarianceDiagInfo<TyCtxt<'tcx>>, a: T, b: T, ) -> RelateResult<'tcx, T>

Switch variance for the purpose of relating a and b.
source§

fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>>

source§

fn regions( &mut self, r: Region<'tcx>, r2: Region<'tcx>, ) -> RelateResult<'tcx, Region<'tcx>>

source§

fn consts( &mut self, c: Const<'tcx>, c2: Const<'tcx>, ) -> RelateResult<'tcx, Const<'tcx>>

source§

fn binders<T>( &mut self, a: Binder<'tcx, T>, _: Binder<'tcx, T>, ) -> RelateResult<'tcx, Binder<'tcx, T>>
where T: Relate<TyCtxt<'tcx>>,

source§

fn relate<T>(&mut self, a: T, b: T) -> Result<T, TypeError<I>>
where T: Relate<I>,

Generic relation routine suitable for most anything.

Auto Trait Implementations§

§

impl<'me, 'tcx> Freeze for Generalizer<'me, 'tcx>

§

impl<'me, 'tcx> !RefUnwindSafe for Generalizer<'me, 'tcx>

§

impl<'me, 'tcx> !Send for Generalizer<'me, 'tcx>

§

impl<'me, 'tcx> !Sync for Generalizer<'me, 'tcx>

§

impl<'me, 'tcx> Unpin for Generalizer<'me, 'tcx>

§

impl<'me, 'tcx> !UnwindSafe for Generalizer<'me, 'tcx>

Blanket Implementations§

source§

impl<T> Aligned for T

source§

const ALIGN: Alignment = _

Alignment of Self.
source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T, R> CollectAndApply<T, R> for T

source§

fn collect_and_apply<I, F>(iter: I, f: F) -> R
where I: Iterator<Item = T>, F: FnOnce(&[T]) -> R,

Equivalent to f(&iter.collect::<Vec<_>>()).

source§

type Output = R

source§

impl<T> Filterable for T

source§

fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>

Creates a filterable data provider with the given name for debugging. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

impl<P> IntoQueryParam<P> for P

source§

impl<T> MaybeResult<T> for T

source§

type Error = !

source§

fn from(_: Result<T, <T as MaybeResult<T>>::Error>) -> T

source§

fn to_result(self) -> Result<T, <T as MaybeResult<T>>::Error>

source§

impl<T> Same for T

source§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<I, T, U> Upcast<I, U> for T
where U: UpcastFrom<I, T>,

source§

fn upcast(self, interner: I) -> U

source§

impl<I, T> UpcastFrom<I, T> for T

source§

fn upcast_from(from: T, _tcx: I) -> T

source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

source§

fn vzip(self) -> V

source§

impl<Tcx, T> Value<Tcx> for T
where Tcx: DepContext,

source§

default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<'a, T> Captures<'a> for T
where T: ?Sized,

source§

impl<T> ErasedDestructor for T
where T: 'static,

source§

impl<T> MaybeSendSync for T

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 248 bytes