cleanup: extract a helper for coercion from inference variables
This commit is contained in:
parent
5eca626e40
commit
5a8edc0b76
1 changed files with 19 additions and 0 deletions
|
@ -146,6 +146,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'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 a = self.shallow_resolve(a);
|
||||||
let b = self.shallow_resolve(b);
|
let b = self.shallow_resolve(b);
|
||||||
debug!("Coerce.tys({:?} => {:?})", a, 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![]);
|
return success(vec![], self.fcx.tcx.ty_error(), vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Coercing from `!` to any type is allowed:
|
||||||
if a.is_never() {
|
if a.is_never() {
|
||||||
// Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
|
// Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
|
||||||
// type variable, we want `?T` to fallback to `!` if not
|
// 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
|
// Consider coercing the subtype to a DST
|
||||||
//
|
//
|
||||||
// NOTE: this is wrapped in a `commit_if_ok` because it creates
|
// 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`.
|
/// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
|
||||||
/// To match `A` with `B`, autoderef will be performed,
|
/// To match `A` with `B`, autoderef will be performed,
|
||||||
/// calling `deref`/`deref_mut` where necessary.
|
/// calling `deref`/`deref_mut` where necessary.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue