mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
cleanup: extract a helper for coercion from inference variables
This commit is contained in:
parent
5eca626e40
commit
5a8edc0b76
@ -146,6 +146,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
}
|
||||
|
||||
fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
|
||||
// First, remove any resolved type variables (at the top level, at least):
|
||||
let a = self.shallow_resolve(a);
|
||||
let b = self.shallow_resolve(b);
|
||||
debug!("Coerce.tys({:?} => {:?})", a, b);
|
||||
@ -155,6 +156,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
return success(vec![], self.fcx.tcx.ty_error(), vec![]);
|
||||
}
|
||||
|
||||
// Coercing from `!` to any type is allowed:
|
||||
if a.is_never() {
|
||||
// Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
|
||||
// type variable, we want `?T` to fallback to `!` if not
|
||||
@ -176,6 +178,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
};
|
||||
}
|
||||
|
||||
// Coercing *from* an unresolved inference variable means that
|
||||
// we have no information about the source type. This will always
|
||||
// ultimately fall back to some form of subtyping.
|
||||
if a.is_ty_var() {
|
||||
return self.coerce_from_inference_variable(a, b);
|
||||
}
|
||||
|
||||
// Consider coercing the subtype to a DST
|
||||
//
|
||||
// NOTE: this is wrapped in a `commit_if_ok` because it creates
|
||||
@ -233,6 +242,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Coercing *from* an inference variable. In this case, we have no information
|
||||
/// about the source type, so we can't really do a true coercion and we always
|
||||
/// fall back to subtyping (`unify_and`).
|
||||
fn coerce_from_inference_variable(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
|
||||
assert!(a.is_ty_var() && self.infcx.shallow_resolve(a) == a);
|
||||
assert!(self.infcx.shallow_resolve(b) == b);
|
||||
|
||||
self.unify_and(a, b, identity)
|
||||
}
|
||||
|
||||
/// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
|
||||
/// To match `A` with `B`, autoderef will be performed,
|
||||
/// calling `deref`/`deref_mut` where necessary.
|
||||
|
Loading…
Reference in New Issue
Block a user