mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 03:38:29 +00:00
Create ShallowResolver
Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
This commit is contained in:
parent
1369132afa
commit
541de81f8e
@ -684,7 +684,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||||||
/// `ty_var`.
|
/// `ty_var`.
|
||||||
fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo, ty_var: Ty<'tcx>) -> Ty<'tcx> {
|
fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo, ty_var: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
let infcx = self.infcx.expect("encountered ty-var without infcx");
|
let infcx = self.infcx.expect("encountered ty-var without infcx");
|
||||||
let bound_to = infcx.shallow_resolve_type(ty_var);
|
let bound_to = infcx.shallow_resolve(ty_var);
|
||||||
if bound_to != ty_var {
|
if bound_to != ty_var {
|
||||||
self.fold_ty(bound_to)
|
self.fold_ty(bound_to)
|
||||||
} else {
|
} else {
|
||||||
|
@ -18,7 +18,7 @@ use crate::mir::interpret::ConstValue;
|
|||||||
use crate::session::config::BorrowckMode;
|
use crate::session::config::BorrowckMode;
|
||||||
use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
|
use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
|
||||||
use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
||||||
use crate::ty::fold::TypeFoldable;
|
use crate::ty::fold::{TypeFolder, TypeFoldable};
|
||||||
use crate::ty::relate::RelateResult;
|
use crate::ty::relate::RelateResult;
|
||||||
use crate::ty::subst::{Kind, InternalSubsts, SubstsRef};
|
use crate::ty::subst::{Kind, InternalSubsts, SubstsRef};
|
||||||
use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners, InferConst};
|
use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners, InferConst};
|
||||||
@ -919,17 +919,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
predicate: &ty::PolySubtypePredicate<'tcx>,
|
predicate: &ty::PolySubtypePredicate<'tcx>,
|
||||||
) -> Option<InferResult<'tcx, ()>> {
|
) -> Option<InferResult<'tcx, ()>> {
|
||||||
// Subtle: it's ok to skip the binder here and resolve because
|
// Subtle: it's ok to skip the binder here and resolve because
|
||||||
// `shallow_resolve_type` just ignores anything that is not a type
|
// `shallow_resolve` just ignores anything that is not a type
|
||||||
// variable, and because type variable's can't (at present, at
|
// variable, and because type variable's can't (at present, at
|
||||||
// least) capture any of the things bound by this binder.
|
// least) capture any of the things bound by this binder.
|
||||||
//
|
//
|
||||||
// Really, there is no *particular* reason to do this
|
// Really, there is no *particular* reason to do this
|
||||||
// `shallow_resolve_type` here except as a
|
// `shallow_resolve` here except as a
|
||||||
// micro-optimization. Naturally I could not
|
// micro-optimization. Naturally I could not
|
||||||
// resist. -nmatsakis
|
// resist. -nmatsakis
|
||||||
let two_unbound_type_vars = {
|
let two_unbound_type_vars = {
|
||||||
let a = self.shallow_resolve_type(predicate.skip_binder().a);
|
let a = self.shallow_resolve(predicate.skip_binder().a);
|
||||||
let b = self.shallow_resolve_type(predicate.skip_binder().b);
|
let b = self.shallow_resolve(predicate.skip_binder().b);
|
||||||
a.is_ty_var() && b.is_ty_var()
|
a.is_ty_var() && b.is_ty_var()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1274,46 +1274,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.resolve_type_vars_if_possible(t).to_string()
|
self.resolve_type_vars_if_possible(t).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have this force-inlined variant of `shallow_resolve_type` for the one
|
|
||||||
// callsite that is extremely hot. All other callsites use the normal
|
|
||||||
// variant.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn inlined_shallow_resolve_type(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
|
|
||||||
match typ.sty {
|
|
||||||
ty::Infer(ty::TyVar(v)) => {
|
|
||||||
// Not entirely obvious: if `typ` is a type variable,
|
|
||||||
// it can be resolved to an int/float variable, which
|
|
||||||
// can then be recursively resolved, hence the
|
|
||||||
// recursion. Note though that we prevent type
|
|
||||||
// variables from unifyxing to other type variables
|
|
||||||
// directly (though they may be embedded
|
|
||||||
// structurally), and we prevent cycles in any case,
|
|
||||||
// so this recursion should always be of very limited
|
|
||||||
// depth.
|
|
||||||
self.type_variables
|
|
||||||
.borrow_mut()
|
|
||||||
.probe(v)
|
|
||||||
.known()
|
|
||||||
.map(|t| self.shallow_resolve_type(t))
|
|
||||||
.unwrap_or(typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::Infer(ty::IntVar(v)) => self.int_unification_table
|
|
||||||
.borrow_mut()
|
|
||||||
.probe_value(v)
|
|
||||||
.map(|v| v.to_type(self.tcx))
|
|
||||||
.unwrap_or(typ),
|
|
||||||
|
|
||||||
ty::Infer(ty::FloatVar(v)) => self.float_unification_table
|
|
||||||
.borrow_mut()
|
|
||||||
.probe_value(v)
|
|
||||||
.map(|v| v.to_type(self.tcx))
|
|
||||||
.unwrap_or(typ),
|
|
||||||
|
|
||||||
_ => typ,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If `TyVar(vid)` resolves to a type, return that type. Else, return the
|
/// If `TyVar(vid)` resolves to a type, return that type. Else, return the
|
||||||
/// universe index of `TyVar(vid)`.
|
/// universe index of `TyVar(vid)`.
|
||||||
pub fn probe_ty_var(&self, vid: TyVid) -> Result<Ty<'tcx>, ty::UniverseIndex> {
|
pub fn probe_ty_var(&self, vid: TyVid) -> Result<Ty<'tcx>, ty::UniverseIndex> {
|
||||||
@ -1325,8 +1285,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shallow_resolve_type(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
|
pub fn shallow_resolve<T>(&self, value: T) -> T
|
||||||
self.inlined_shallow_resolve_type(typ)
|
where
|
||||||
|
T: TypeFoldable<'tcx>,
|
||||||
|
{
|
||||||
|
let mut r = ShallowResolver::new(self);
|
||||||
|
value.fold_with(&mut r)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
|
pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
|
||||||
@ -1391,24 +1355,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shallow_resolve_const(
|
|
||||||
&self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>
|
|
||||||
) -> &'tcx ty::Const<'tcx> {
|
|
||||||
match ct {
|
|
||||||
ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
|
|
||||||
self.const_unification_table
|
|
||||||
.borrow_mut()
|
|
||||||
.probe_value(*vid)
|
|
||||||
.val
|
|
||||||
.known()
|
|
||||||
.map(|c| self.shallow_resolve_const(c))
|
|
||||||
.unwrap_or(ct)
|
|
||||||
}
|
|
||||||
_ => ct,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fully_resolve<T: TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<'tcx, T> {
|
pub fn fully_resolve<T: TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<'tcx, T> {
|
||||||
/*!
|
/*!
|
||||||
* Attempts to resolve all type/region/const variables in
|
* Attempts to resolve all type/region/const variables in
|
||||||
@ -1528,7 +1474,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
closure_substs: ty::ClosureSubsts<'tcx>,
|
closure_substs: ty::ClosureSubsts<'tcx>,
|
||||||
) -> Option<ty::ClosureKind> {
|
) -> Option<ty::ClosureKind> {
|
||||||
let closure_kind_ty = closure_substs.closure_kind_ty(closure_def_id, self.tcx);
|
let closure_kind_ty = closure_substs.closure_kind_ty(closure_def_id, self.tcx);
|
||||||
let closure_kind_ty = self.shallow_resolve_type(&closure_kind_ty);
|
let closure_kind_ty = self.shallow_resolve(closure_kind_ty);
|
||||||
closure_kind_ty.to_opt_closure_kind()
|
closure_kind_ty.to_opt_closure_kind()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1542,7 +1488,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
substs: ty::ClosureSubsts<'tcx>,
|
substs: ty::ClosureSubsts<'tcx>,
|
||||||
) -> ty::PolyFnSig<'tcx> {
|
) -> ty::PolyFnSig<'tcx> {
|
||||||
let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx);
|
let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx);
|
||||||
let closure_sig_ty = self.shallow_resolve_type(&closure_sig_ty);
|
let closure_sig_ty = self.shallow_resolve(closure_sig_ty);
|
||||||
closure_sig_ty.fn_sig(self.tcx)
|
closure_sig_ty.fn_sig(self.tcx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1598,6 +1544,82 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ShallowResolver<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||||
|
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'gcx, 'tcx> ShallowResolver<'a, 'gcx, 'tcx> {
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
|
||||||
|
ShallowResolver { infcx }
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have this force-inlined variant of `shallow_resolve` for the one
|
||||||
|
// callsite that is extremely hot. All other callsites use the normal
|
||||||
|
// variant.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn inlined_shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
|
match typ.sty {
|
||||||
|
ty::Infer(ty::TyVar(v)) => {
|
||||||
|
// Not entirely obvious: if `typ` is a type variable,
|
||||||
|
// it can be resolved to an int/float variable, which
|
||||||
|
// can then be recursively resolved, hence the
|
||||||
|
// recursion. Note though that we prevent type
|
||||||
|
// variables from unifyxing to other type variables
|
||||||
|
// directly (though they may be embedded
|
||||||
|
// structurally), and we prevent cycles in any case,
|
||||||
|
// so this recursion should always be of very limited
|
||||||
|
// depth.
|
||||||
|
self.infcx.type_variables
|
||||||
|
.borrow_mut()
|
||||||
|
.probe(v)
|
||||||
|
.known()
|
||||||
|
.map(|t| self.fold_ty(t))
|
||||||
|
.unwrap_or(typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
ty::Infer(ty::IntVar(v)) => self.infcx.int_unification_table
|
||||||
|
.borrow_mut()
|
||||||
|
.probe_value(v)
|
||||||
|
.map(|v| v.to_type(self.infcx.tcx))
|
||||||
|
.unwrap_or(typ),
|
||||||
|
|
||||||
|
ty::Infer(ty::FloatVar(v)) => self.infcx.float_unification_table
|
||||||
|
.borrow_mut()
|
||||||
|
.probe_value(v)
|
||||||
|
.map(|v| v.to_type(self.infcx.tcx))
|
||||||
|
.unwrap_or(typ),
|
||||||
|
|
||||||
|
_ => typ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ShallowResolver<'a, 'gcx, 'tcx> {
|
||||||
|
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
|
||||||
|
self.infcx.tcx
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
|
self.inlined_shallow_resolve(ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
|
match ct {
|
||||||
|
ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
|
||||||
|
self.infcx.const_unification_table
|
||||||
|
.borrow_mut()
|
||||||
|
.probe_value(*vid)
|
||||||
|
.val
|
||||||
|
.known()
|
||||||
|
.map(|c| self.fold_const(c))
|
||||||
|
.unwrap_or(ct)
|
||||||
|
}
|
||||||
|
_ => ct,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
|
impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
|
||||||
pub fn span(&self) -> Span {
|
pub fn span(&self) -> Span {
|
||||||
self.cause.span
|
self.cause.span
|
||||||
|
@ -538,10 +538,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn tys(&mut self, a: Ty<'tcx>, mut b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
fn tys(&mut self, a: Ty<'tcx>, mut b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||||
let a = self.infcx.shallow_resolve_type(a);
|
let a = self.infcx.shallow_resolve(a);
|
||||||
|
|
||||||
if !D::forbid_inference_vars() {
|
if !D::forbid_inference_vars() {
|
||||||
b = self.infcx.shallow_resolve_type(b);
|
b = self.infcx.shallow_resolve(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
match (&a.sty, &b.sty) {
|
match (&a.sty, &b.sty) {
|
||||||
|
@ -8,7 +8,7 @@ use crate::ty::fold::{TypeFolder, TypeVisitor};
|
|||||||
|
|
||||||
/// The opportunistic type resolver can be used at any time. It simply replaces
|
/// The opportunistic type resolver can be used at any time. It simply replaces
|
||||||
/// type variables that have been unified with the things they have
|
/// type variables that have been unified with the things they have
|
||||||
/// been unified with (similar to `shallow_resolve_type`, but deep). This is
|
/// been unified with (similar to `shallow_resolve`, but deep). This is
|
||||||
/// useful for printing messages etc but also required at various
|
/// useful for printing messages etc but also required at various
|
||||||
/// points for correctness.
|
/// points for correctness.
|
||||||
pub struct OpportunisticTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
pub struct OpportunisticTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||||
@ -31,7 +31,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeResolver<'a, 'g
|
|||||||
if !t.has_infer_types() {
|
if !t.has_infer_types() {
|
||||||
t // micro-optimize -- if there is nothing in this type that this fold affects...
|
t // micro-optimize -- if there is nothing in this type that this fold affects...
|
||||||
} else {
|
} else {
|
||||||
let t0 = self.infcx.shallow_resolve_type(t);
|
let t0 = self.infcx.shallow_resolve(t);
|
||||||
t0.super_fold_with(self)
|
t0.super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
|
|||||||
if !t.needs_infer() {
|
if !t.needs_infer() {
|
||||||
t // micro-optimize -- if there is nothing in this type that this fold affects...
|
t // micro-optimize -- if there is nothing in this type that this fold affects...
|
||||||
} else {
|
} else {
|
||||||
let t0 = self.infcx.shallow_resolve_type(t);
|
let t0 = self.infcx.shallow_resolve(t);
|
||||||
t0.super_fold_with(self)
|
t0.super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
|
|||||||
if !ct.needs_infer() {
|
if !ct.needs_infer() {
|
||||||
ct // micro-optimize -- if there is nothing in this const that this fold affects...
|
ct // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||||
} else {
|
} else {
|
||||||
let c0 = self.infcx.shallow_resolve_const(ct);
|
let c0 = self.infcx.shallow_resolve(ct);
|
||||||
c0.super_fold_with(self)
|
c0.super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ impl<'a, 'gcx, 'tcx> UnresolvedTypeFinder<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'gcx, 'tcx> {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
|
||||||
let t = self.infcx.shallow_resolve_type(t);
|
let t = self.infcx.shallow_resolve(t);
|
||||||
if t.has_infer_types() {
|
if t.has_infer_types() {
|
||||||
if let ty::Infer(infer_ty) = t.sty {
|
if let ty::Infer(infer_ty) = t.sty {
|
||||||
// Since we called `shallow_resolve` above, this must
|
// Since we called `shallow_resolve` above, this must
|
||||||
@ -175,7 +175,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
|
|||||||
// ^ we need to have the `keep_local` check to un-default
|
// ^ we need to have the `keep_local` check to un-default
|
||||||
// defaulted tuples.
|
// defaulted tuples.
|
||||||
} else {
|
} else {
|
||||||
let t = self.infcx.shallow_resolve_type(t);
|
let t = self.infcx.shallow_resolve(t);
|
||||||
match t.sty {
|
match t.sty {
|
||||||
ty::Infer(ty::TyVar(vid)) => {
|
ty::Infer(ty::TyVar(vid)) => {
|
||||||
self.err = Some(FixupError::UnresolvedTy(vid));
|
self.err = Some(FixupError::UnresolvedTy(vid));
|
||||||
@ -216,7 +216,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
|
|||||||
// ^ we need to have the `keep_local` check to un-default
|
// ^ we need to have the `keep_local` check to un-default
|
||||||
// defaulted tuples.
|
// defaulted tuples.
|
||||||
} else {
|
} else {
|
||||||
let c = self.infcx.shallow_resolve_const(c);
|
let c = self.infcx.shallow_resolve(c);
|
||||||
match c.val {
|
match c.val {
|
||||||
ConstValue::Infer(InferConst::Var(vid)) => {
|
ConstValue::Infer(InferConst::Var(vid)) => {
|
||||||
self.err = Some(FixupError::UnresolvedConst(vid));
|
self.err = Some(FixupError::UnresolvedConst(vid));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::infer::InferCtxt;
|
use crate::infer::{InferCtxt, ShallowResolver};
|
||||||
use crate::mir::interpret::{GlobalId, ErrorHandled};
|
use crate::mir::interpret::{GlobalId, ErrorHandled};
|
||||||
use crate::ty::{self, Ty, TypeFoldable, ToPolyTraitRef};
|
use crate::ty::{self, Ty, TypeFoldable, ToPolyTraitRef};
|
||||||
use crate::ty::error::ExpectedFound;
|
use crate::ty::error::ExpectedFound;
|
||||||
@ -255,9 +255,9 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
|
|||||||
// doing more work yet
|
// doing more work yet
|
||||||
if !pending_obligation.stalled_on.is_empty() {
|
if !pending_obligation.stalled_on.is_empty() {
|
||||||
if pending_obligation.stalled_on.iter().all(|&ty| {
|
if pending_obligation.stalled_on.iter().all(|&ty| {
|
||||||
// Use the force-inlined variant of shallow_resolve_type() because this code is hot.
|
// Use the force-inlined variant of shallow_resolve() because this code is hot.
|
||||||
let resolved_ty = self.selcx.infcx().inlined_shallow_resolve_type(&ty);
|
let resolved = ShallowResolver::new(self.selcx.infcx()).inlined_shallow_resolve(ty);
|
||||||
resolved_ty == ty // nothing changed here
|
resolved == ty // nothing changed here
|
||||||
}) {
|
}) {
|
||||||
debug!("process_predicate: pending obligation {:?} still stalled on {:?}",
|
debug!("process_predicate: pending obligation {:?} still stalled on {:?}",
|
||||||
self.selcx.infcx()
|
self.selcx.infcx()
|
||||||
|
@ -1229,7 +1229,7 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
|
|||||||
-> Progress<'tcx>
|
-> Progress<'tcx>
|
||||||
{
|
{
|
||||||
let self_ty = obligation_trait_ref.self_ty();
|
let self_ty = obligation_trait_ref.self_ty();
|
||||||
let object_ty = selcx.infcx().shallow_resolve_type(self_ty);
|
let object_ty = selcx.infcx().shallow_resolve(self_ty);
|
||||||
debug!("confirm_object_candidate(object_ty={:?})",
|
debug!("confirm_object_candidate(object_ty={:?})",
|
||||||
object_ty);
|
object_ty);
|
||||||
let data = match object_ty.sty {
|
let data = match object_ty.sty {
|
||||||
@ -1346,7 +1346,7 @@ fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
|
|||||||
fn_pointer_vtable: VtableFnPointerData<'tcx, PredicateObligation<'tcx>>)
|
fn_pointer_vtable: VtableFnPointerData<'tcx, PredicateObligation<'tcx>>)
|
||||||
-> Progress<'tcx>
|
-> Progress<'tcx>
|
||||||
{
|
{
|
||||||
let fn_type = selcx.infcx().shallow_resolve_type(fn_pointer_vtable.fn_ty);
|
let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty);
|
||||||
let sig = fn_type.fn_sig(selcx.tcx());
|
let sig = fn_type.fn_sig(selcx.tcx());
|
||||||
let Normalized {
|
let Normalized {
|
||||||
value: sig,
|
value: sig,
|
||||||
@ -1371,7 +1371,7 @@ fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
|
|||||||
let tcx = selcx.tcx();
|
let tcx = selcx.tcx();
|
||||||
let infcx = selcx.infcx();
|
let infcx = selcx.infcx();
|
||||||
let closure_sig_ty = vtable.substs.closure_sig_ty(vtable.closure_def_id, tcx);
|
let closure_sig_ty = vtable.substs.closure_sig_ty(vtable.closure_def_id, tcx);
|
||||||
let closure_sig = infcx.shallow_resolve_type(&closure_sig_ty).fn_sig(tcx);
|
let closure_sig = infcx.shallow_resolve(closure_sig_ty).fn_sig(tcx);
|
||||||
let Normalized {
|
let Normalized {
|
||||||
value: closure_sig,
|
value: closure_sig,
|
||||||
obligations
|
obligations
|
||||||
|
@ -2403,7 +2403,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
// NOTE: binder moved to (*)
|
// NOTE: binder moved to (*)
|
||||||
let self_ty = self.infcx
|
let self_ty = self.infcx
|
||||||
.shallow_resolve_type(obligation.predicate.skip_binder().self_ty());
|
.shallow_resolve(obligation.predicate.skip_binder().self_ty());
|
||||||
|
|
||||||
match self_ty.sty {
|
match self_ty.sty {
|
||||||
ty::Infer(ty::IntVar(_))
|
ty::Infer(ty::IntVar(_))
|
||||||
@ -2467,7 +2467,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
) -> BuiltinImplConditions<'tcx> {
|
) -> BuiltinImplConditions<'tcx> {
|
||||||
// NOTE: binder moved to (*)
|
// NOTE: binder moved to (*)
|
||||||
let self_ty = self.infcx
|
let self_ty = self.infcx
|
||||||
.shallow_resolve_type(obligation.predicate.skip_binder().self_ty());
|
.shallow_resolve(obligation.predicate.skip_binder().self_ty());
|
||||||
|
|
||||||
use self::BuiltinImplConditions::{Ambiguous, None, Where};
|
use self::BuiltinImplConditions::{Ambiguous, None, Where};
|
||||||
|
|
||||||
@ -2866,7 +2866,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let types = obligation.predicate.map_bound(|inner| {
|
let types = obligation.predicate.map_bound(|inner| {
|
||||||
let self_ty = self.infcx.shallow_resolve_type(inner.self_ty());
|
let self_ty = self.infcx.shallow_resolve(inner.self_ty());
|
||||||
self.constituent_types_for_ty(self_ty)
|
self.constituent_types_for_ty(self_ty)
|
||||||
});
|
});
|
||||||
self.vtable_auto_impl(obligation, trait_def_id, types)
|
self.vtable_auto_impl(obligation, trait_def_id, types)
|
||||||
@ -2990,7 +2990,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
// from the object. Have to try to make a broken test case that
|
// from the object. Have to try to make a broken test case that
|
||||||
// results.
|
// results.
|
||||||
let self_ty = self.infcx
|
let self_ty = self.infcx
|
||||||
.shallow_resolve_type(*obligation.self_ty().skip_binder());
|
.shallow_resolve(*obligation.self_ty().skip_binder());
|
||||||
let poly_trait_ref = match self_ty.sty {
|
let poly_trait_ref = match self_ty.sty {
|
||||||
ty::Dynamic(ref data, ..) =>
|
ty::Dynamic(ref data, ..) =>
|
||||||
data.principal().unwrap_or_else(|| {
|
data.principal().unwrap_or_else(|| {
|
||||||
@ -3045,7 +3045,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
// OK to skip binder; it is reintroduced below
|
// OK to skip binder; it is reintroduced below
|
||||||
let self_ty = self.infcx
|
let self_ty = self.infcx
|
||||||
.shallow_resolve_type(*obligation.self_ty().skip_binder());
|
.shallow_resolve(*obligation.self_ty().skip_binder());
|
||||||
let sig = self_ty.fn_sig(self.tcx());
|
let sig = self_ty.fn_sig(self.tcx());
|
||||||
let trait_ref = self.tcx()
|
let trait_ref = self.tcx()
|
||||||
.closure_trait_ref_and_return_type(
|
.closure_trait_ref_and_return_type(
|
||||||
@ -3124,8 +3124,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
// OK to skip binder because the substs on generator types never
|
// OK to skip binder because the substs on generator types never
|
||||||
// touch bound regions, they just capture the in-scope
|
// touch bound regions, they just capture the in-scope
|
||||||
// type/region parameters
|
// type/region parameters
|
||||||
let self_ty = self.infcx
|
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
|
||||||
.shallow_resolve_type(obligation.self_ty().skip_binder());
|
|
||||||
let (generator_def_id, substs) = match self_ty.sty {
|
let (generator_def_id, substs) = match self_ty.sty {
|
||||||
ty::Generator(id, substs, _) => (id, substs),
|
ty::Generator(id, substs, _) => (id, substs),
|
||||||
_ => bug!("closure candidate for non-closure {:?}", obligation),
|
_ => bug!("closure candidate for non-closure {:?}", obligation),
|
||||||
@ -3182,8 +3181,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
// OK to skip binder because the substs on closure types never
|
// OK to skip binder because the substs on closure types never
|
||||||
// touch bound regions, they just capture the in-scope
|
// touch bound regions, they just capture the in-scope
|
||||||
// type/region parameters
|
// type/region parameters
|
||||||
let self_ty = self.infcx
|
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
|
||||||
.shallow_resolve_type(obligation.self_ty().skip_binder());
|
|
||||||
let (closure_def_id, substs) = match self_ty.sty {
|
let (closure_def_id, substs) = match self_ty.sty {
|
||||||
ty::Closure(id, substs) => (id, substs),
|
ty::Closure(id, substs) => (id, substs),
|
||||||
_ => bug!("closure candidate for non-closure {:?}", obligation),
|
_ => bug!("closure candidate for non-closure {:?}", obligation),
|
||||||
@ -3278,14 +3276,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
// assemble_candidates_for_unsizing should ensure there are no late bound
|
// assemble_candidates_for_unsizing should ensure there are no late bound
|
||||||
// regions here. See the comment there for more details.
|
// regions here. See the comment there for more details.
|
||||||
let source = self.infcx
|
let source = self.infcx
|
||||||
.shallow_resolve_type(obligation.self_ty().no_bound_vars().unwrap());
|
.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
|
||||||
let target = obligation
|
let target = obligation
|
||||||
.predicate
|
.predicate
|
||||||
.skip_binder()
|
.skip_binder()
|
||||||
.trait_ref
|
.trait_ref
|
||||||
.substs
|
.substs
|
||||||
.type_at(1);
|
.type_at(1);
|
||||||
let target = self.infcx.shallow_resolve_type(target);
|
let target = self.infcx.shallow_resolve(target);
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"confirm_builtin_unsize_candidate(source={:?}, target={:?})",
|
"confirm_builtin_unsize_candidate(source={:?}, target={:?})",
|
||||||
|
@ -406,7 +406,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||||||
// moving. (Goal is that an "inductive hypothesis"
|
// moving. (Goal is that an "inductive hypothesis"
|
||||||
// is satisfied to ensure termination.)
|
// is satisfied to ensure termination.)
|
||||||
ty::Infer(_) => {
|
ty::Infer(_) => {
|
||||||
let ty = self.infcx.shallow_resolve_type(ty);
|
let ty = self.infcx.shallow_resolve(ty);
|
||||||
if let ty::Infer(_) = ty.sty { // not yet resolved...
|
if let ty::Infer(_) = ty.sty { // not yet resolved...
|
||||||
if ty == ty0 { // ...this is the type we started from! no progress.
|
if ty == ty0 { // ...this is the type we started from! no progress.
|
||||||
return false;
|
return false;
|
||||||
|
@ -204,7 +204,7 @@ impl TypeRelation<'cx, 'gcx, 'tcx> for AnswerSubstitutor<'cx, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||||
let b = self.infcx.shallow_resolve_type(b);
|
let b = self.infcx.shallow_resolve(b);
|
||||||
debug!("AnswerSubstitutor::tys(a = {:?}, b = {:?})", a, b);
|
debug!("AnswerSubstitutor::tys(a = {:?}, b = {:?})", a, b);
|
||||||
|
|
||||||
if let &ty::Bound(debruijn, bound_ty) = &a.sty {
|
if let &ty::Bound(debruijn, bound_ty) = &a.sty {
|
||||||
|
@ -350,7 +350,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PatKind::Ref(ref inner, mutbl) => {
|
PatKind::Ref(ref inner, mutbl) => {
|
||||||
let expected = self.shallow_resolve_type(expected);
|
let expected = self.shallow_resolve(expected);
|
||||||
if self.check_dereferencable(pat.span, expected, &inner) {
|
if self.check_dereferencable(pat.span, expected, &inner) {
|
||||||
// `demand::subtype` would be good enough, but using
|
// `demand::subtype` would be good enough, but using
|
||||||
// `eqtype` turns out to be equally general. See (*)
|
// `eqtype` turns out to be equally general. See (*)
|
||||||
@ -519,7 +519,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
|
pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
|
||||||
if let PatKind::Binding(..) = inner.node {
|
if let PatKind::Binding(..) = inner.node {
|
||||||
if let Some(mt) = self.shallow_resolve_type(expected).builtin_deref(true) {
|
if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
|
||||||
if let ty::Dynamic(..) = mt.ty.sty {
|
if let ty::Dynamic(..) = mt.ty.sty {
|
||||||
// This is "x = SomeTrait" being reduced from
|
// This is "x = SomeTrait" being reduced from
|
||||||
// "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
|
// "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
|
||||||
|
@ -154,7 +154,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
|
fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
|
||||||
let a = self.shallow_resolve_type(a);
|
let a = self.shallow_resolve(a);
|
||||||
debug!("Coerce.tys({:?} => {:?})", a, b);
|
debug!("Coerce.tys({:?} => {:?})", a, b);
|
||||||
|
|
||||||
// Just ignore error types.
|
// Just ignore error types.
|
||||||
@ -170,8 +170,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||||||
// let _: Option<?T> = Some({ return; });
|
// let _: Option<?T> = Some({ return; });
|
||||||
//
|
//
|
||||||
// here, we would coerce from `!` to `?T`.
|
// here, we would coerce from `!` to `?T`.
|
||||||
let b = self.shallow_resolve_type(b);
|
let b = self.shallow_resolve(b);
|
||||||
return if self.shallow_resolve_type(b).is_ty_var() {
|
return if self.shallow_resolve(b).is_ty_var() {
|
||||||
// micro-optimization: no need for this if `b` is
|
// micro-optimization: no need for this if `b` is
|
||||||
// already resolved in some way.
|
// already resolved in some way.
|
||||||
let diverging_ty = self.next_diverging_ty_var(
|
let diverging_ty = self.next_diverging_ty_var(
|
||||||
@ -659,7 +659,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||||||
//! into a closure or a `proc`.
|
//! into a closure or a `proc`.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
let b = self.shallow_resolve_type(b);
|
let b = self.shallow_resolve(b);
|
||||||
debug!("coerce_from_fn_pointer(a={:?}, b={:?})", a, b);
|
debug!("coerce_from_fn_pointer(a={:?}, b={:?})", a, b);
|
||||||
|
|
||||||
self.coerce_from_safe_fn(a, fn_ty_a, b,
|
self.coerce_from_safe_fn(a, fn_ty_a, b,
|
||||||
@ -673,7 +673,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||||||
//! Attempts to coerce from the type of a Rust function item
|
//! Attempts to coerce from the type of a Rust function item
|
||||||
//! into a closure or a `proc`.
|
//! into a closure or a `proc`.
|
||||||
|
|
||||||
let b = self.shallow_resolve_type(b);
|
let b = self.shallow_resolve(b);
|
||||||
debug!("coerce_from_fn_item(a={:?}, b={:?})", a, b);
|
debug!("coerce_from_fn_item(a={:?}, b={:?})", a, b);
|
||||||
|
|
||||||
match b.sty {
|
match b.sty {
|
||||||
@ -719,7 +719,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||||||
//! into a function pointer.
|
//! into a function pointer.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
let b = self.shallow_resolve_type(b);
|
let b = self.shallow_resolve(b);
|
||||||
|
|
||||||
let hir_id_a = self.tcx.hir().as_local_hir_id(def_id_a).unwrap();
|
let hir_id_a = self.tcx.hir().as_local_hir_id(def_id_a).unwrap();
|
||||||
match b.sty {
|
match b.sty {
|
||||||
@ -1128,7 +1128,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
|||||||
// compatibility (hopefully that is true) by helping us
|
// compatibility (hopefully that is true) by helping us
|
||||||
// uncover never types better.
|
// uncover never types better.
|
||||||
if expression_ty.is_ty_var() {
|
if expression_ty.is_ty_var() {
|
||||||
expression_ty = fcx.infcx.shallow_resolve_type(expression_ty);
|
expression_ty = fcx.infcx.shallow_resolve(expression_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we see any error types, just propagate that error
|
// If we see any error types, just propagate that error
|
||||||
|
@ -281,7 +281,7 @@ impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
|
|||||||
fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
|
fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
|
||||||
match *self {
|
match *self {
|
||||||
ExpectHasType(ety) => {
|
ExpectHasType(ety) => {
|
||||||
let ety = fcx.shallow_resolve_type(ety);
|
let ety = fcx.shallow_resolve(ety);
|
||||||
if !ety.is_ty_var() {
|
if !ety.is_ty_var() {
|
||||||
ExpectHasType(ety)
|
ExpectHasType(ety)
|
||||||
} else {
|
} else {
|
||||||
@ -2792,7 +2792,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
expected_vid: ty::TyVid,
|
expected_vid: ty::TyVid,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let self_ty = self.shallow_resolve_type(trait_ref.self_ty());
|
let self_ty = self.shallow_resolve(trait_ref.self_ty());
|
||||||
debug!(
|
debug!(
|
||||||
"self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
|
"self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
|
||||||
trait_ref, self_ty, expected_vid
|
trait_ref, self_ty, expected_vid
|
||||||
|
Loading…
Reference in New Issue
Block a user