# Struct rustc_infer::infer::relate::generalize::Generalization

source ·

    pub struct Generalization<T> {
        pub value_may_be_infer: T,
        pub needs_wf: bool,
    }

Expand description

Result from a generalization operation. This includes not only the generalized type, but also a bool flag indicating whether further WF checks are needed.

## Fields§

§`value_may_be_infer: T`

When generalizing `<?0 as Trait>::Assoc` or `<T as Bar<<?0 as Foo>::Assoc>>::Assoc` for `?0` generalization returns an inference variable.

This has to be handled wotj care as it can otherwise very easily result in infinite recursion.

§`needs_wf: bool`

If true, then the generalized type may not be well-formed, even if the source type is well-formed, so we should add an additional check to enforce that it is. This arises in particular around ‘bivariant’ type parameters that are only constrained by a where-clause. As an example, imagine a type:

    struct Foo<A, B> where A: Iterator<Item = B> {
        data: A
    }

here, `A` will be covariant, but `B` is unconstrained. However, whatever it is, for `Foo` to be WF, it must be equal to `A::Item`. If we have an input `Foo<?A, ?B>`, then after generalization we will wind up with a type like `Foo<?C, ?D>`. When we enforce that `Foo<?A, ?B> <: Foo<?C, ?D>` (or `>:`), we will wind up with the requirement that `?A <: ?C`, but no particular relationship between `?B` and `?D` (after all, we do not know the variance of the normalized form of `A::Item` with respect to `A`). If we do nothing else, this may mean that `?D` goes unconstrained (as in #41677). So, in this scenario where we create a new type variable in a bivariant context, we set the `needs_wf` flag to true. This will force the calling code to check that `WF(Foo<?C, ?D>)` holds, which in turn implies that `?C::Item == ?D`. So once `?C` is constrained, that should suffice to restrict `?D`.

## Trait Implementations§

source§

### impl<T: Debug> Debug for Generalization<T>

source§

#### fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

## Auto Trait Implementations§

§

### impl<T> RefUnwindSafe for Generalization<T>
where T: RefUnwindSafe,

§

### impl<T> Send for Generalization<T>
where T: Send,

§

### impl<T> Sync for Generalization<T>
where T: Sync,

§

### impl<T> Unpin for Generalization<T>
where T: Unpin,

§

### impl<T> UnwindSafe for Generalization<T>
where T: UnwindSafe,

## Blanket Implementations§

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> From<T> for T

source§

#### fn from(t: T) -> T

Returns the argument unchanged.

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, U> TryFrom<U> for T
where U: Into<T>,

§

#### 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>,

§

#### 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.

## Layout§

Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.