pub(crate) enum Expectation<'db> {
None,
HasType(Ty<'db>),
Castable(Ty<'db>),
RValueLikeUnsized(Ty<'db>),
}Expand description
When inferring an expression, we propagate downward whatever type hint we
are able in the form of an Expectation.
Variants§
Implementations§
Source§impl<'db> Expectation<'db>
impl<'db> Expectation<'db>
Sourcefn has_type(ty: Ty<'db>) -> Self
fn has_type(ty: Ty<'db>) -> Self
The expectation that the type of the expression needs to equal the given type.
Sourcefn rvalue_hint(ctx: &mut InferenceContext<'db>, ty: Ty<'db>) -> Self
fn rvalue_hint(ctx: &mut InferenceContext<'db>, ty: Ty<'db>) -> Self
The following explanation is copied straight from rustc:
Provides an expectation for an rvalue expression given an optional
hint, which is not required for type safety (the resulting type might
be checked higher up, as is the case with &expr and box expr), but
is useful in determining the concrete type.
The primary use case is where the expected type is a fat pointer,
like &[isize]. For example, consider the following statement:
let it: &[isize] = &[1, 2, 3];In this case, the expected type for the &[1, 2, 3] expression is
&[isize]. If however we were to say that [1, 2, 3] has the
expectation ExpectHasType([isize]), that would be too strong –
[1, 2, 3] does not have the type [isize] but rather [isize; 3].
It is only the &[1, 2, 3] expression as a whole that can be coerced
to the type &[isize]. Therefore, we propagate this more limited hint,
which still is useful, because it informs integer literals and the like.
See the test case test/ui/coerce-expect-unsized.rs and #20169
for examples of where this comes up,.
fn resolve(&self, table: &InferenceTable<'db>) -> Expectation<'db>
fn to_option(&self, table: &InferenceTable<'db>) -> Option<Ty<'db>>
fn only_has_type(&self, table: &mut InferenceTable<'db>) -> Option<Ty<'db>>
fn coercion_target_type( &self, table: &mut InferenceTable<'db>, span: Span, ) -> Ty<'db>
Sourcefn adjust_for_branches(
&self,
table: &mut InferenceTable<'db>,
span: Span,
) -> Expectation<'db>
fn adjust_for_branches( &self, table: &mut InferenceTable<'db>, span: Span, ) -> Expectation<'db>
Comment copied from rustc:
Disregard “castable to” expectations because they
can lead us astray. Consider for example if cond {22} else {c} as u8 – if we propagate the
“castable to u8” constraint to 22, it will pick the
type 22u8, which is overly constrained (c might not
be a u8). In effect, the problem is that the
“castable to” expectation is not the tightest thing
we can say, so we want to drop it in this case.
The tightest thing we can say is “must unify with
else branch”. Note that in the case of a “has type”
constraint, this limitation does not hold.
If the expected type is just a type variable, then don’t use an expected type. Otherwise, we might write parts of the type when checking the ‘then’ block which are incompatible with the ‘else’ branch.
Trait Implementations§
Source§impl<'db> Clone for Expectation<'db>
impl<'db> Clone for Expectation<'db>
Source§fn clone(&self) -> Expectation<'db>
fn clone(&self) -> Expectation<'db>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<'db> Debug for Expectation<'db>
impl<'db> Debug for Expectation<'db>
Source§impl<'db> PartialEq for Expectation<'db>
impl<'db> PartialEq for Expectation<'db>
Source§fn eq(&self, other: &Expectation<'db>) -> bool
fn eq(&self, other: &Expectation<'db>) -> bool
self and other values to be equal, and is used by ==.impl<'db> Eq for Expectation<'db>
impl<'db> StructuralPartialEq for Expectation<'db>
Auto Trait Implementations§
impl<'db> Freeze for Expectation<'db>
impl<'db> RefUnwindSafe for Expectation<'db>
impl<'db> Send for Expectation<'db>
impl<'db> Sync for Expectation<'db>
impl<'db> Unpin for Expectation<'db>
impl<'db> UnsafeUnpin for Expectation<'db>
impl<'db> UnwindSafe for Expectation<'db>
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§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