struct Generalization<T> {
pub value_may_be_infer: T,
pub has_unconstrained_ty_var: 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: TWhen 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.
has_unconstrained_ty_var: boolIn general, we do not check whether all types which occur during type checking are well-formed. We only check wf of user-provided types and when actually using a type, e.g. for method calls.
This means that when subtyping, we may end up with unconstrained inference variables if a generalized type has bivariant parameters. A parameter may only be bivariant if it is constrained by a projection bound in 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 Foo<?A, ?B> <: Foo<?C, ?D>,
we will wind up with the requirement that ?A <: ?C, but no particular
relationship between ?B and ?D (after all, these types may be completely
different). If we do nothing else, this may mean that ?D goes unconstrained
(as in #41677). To avoid this we emit a WellFormed obligation in these cases.
Trait Implementations§
Auto Trait Implementations§
impl<T> Freeze for Generalization<T>where
T: Freeze,
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> UnsafeUnpin for Generalization<T>where
T: UnsafeUnpin,
impl<T> UnwindSafe for Generalization<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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