Skip to content

Commit 541de81

Browse files
varkoryodaldevoid
andcommitted
Create ShallowResolver
Co-Authored-By: Gabriel Smith <[email protected]>
1 parent 1369132 commit 541de81

File tree

12 files changed

+128
-108
lines changed

12 files changed

+128
-108
lines changed

src/librustc/infer/canonical/canonicalizer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
684684
/// `ty_var`.
685685
fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo, ty_var: Ty<'tcx>) -> Ty<'tcx> {
686686
let infcx = self.infcx.expect("encountered ty-var without infcx");
687-
let bound_to = infcx.shallow_resolve_type(ty_var);
687+
let bound_to = infcx.shallow_resolve(ty_var);
688688
if bound_to != ty_var {
689689
self.fold_ty(bound_to)
690690
} else {

src/librustc/infer/mod.rs

+89-67
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::mir::interpret::ConstValue;
1818
use crate::session::config::BorrowckMode;
1919
use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
2020
use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
21-
use crate::ty::fold::TypeFoldable;
21+
use crate::ty::fold::{TypeFolder, TypeFoldable};
2222
use crate::ty::relate::RelateResult;
2323
use crate::ty::subst::{Kind, InternalSubsts, SubstsRef};
2424
use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners, InferConst};
@@ -919,17 +919,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
919919
predicate: &ty::PolySubtypePredicate<'tcx>,
920920
) -> Option<InferResult<'tcx, ()>> {
921921
// Subtle: it's ok to skip the binder here and resolve because
922-
// `shallow_resolve_type` just ignores anything that is not a type
922+
// `shallow_resolve` just ignores anything that is not a type
923923
// variable, and because type variable's can't (at present, at
924924
// least) capture any of the things bound by this binder.
925925
//
926926
// Really, there is no *particular* reason to do this
927-
// `shallow_resolve_type` here except as a
927+
// `shallow_resolve` here except as a
928928
// micro-optimization. Naturally I could not
929929
// resist. -nmatsakis
930930
let two_unbound_type_vars = {
931-
let a = self.shallow_resolve_type(predicate.skip_binder().a);
932-
let b = self.shallow_resolve_type(predicate.skip_binder().b);
931+
let a = self.shallow_resolve(predicate.skip_binder().a);
932+
let b = self.shallow_resolve(predicate.skip_binder().b);
933933
a.is_ty_var() && b.is_ty_var()
934934
};
935935

@@ -1274,46 +1274,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12741274
self.resolve_type_vars_if_possible(t).to_string()
12751275
}
12761276

1277-
// We have this force-inlined variant of `shallow_resolve_type` for the one
1278-
// callsite that is extremely hot. All other callsites use the normal
1279-
// variant.
1280-
#[inline(always)]
1281-
pub fn inlined_shallow_resolve_type(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
1282-
match typ.sty {
1283-
ty::Infer(ty::TyVar(v)) => {
1284-
// Not entirely obvious: if `typ` is a type variable,
1285-
// it can be resolved to an int/float variable, which
1286-
// can then be recursively resolved, hence the
1287-
// recursion. Note though that we prevent type
1288-
// variables from unifyxing to other type variables
1289-
// directly (though they may be embedded
1290-
// structurally), and we prevent cycles in any case,
1291-
// so this recursion should always be of very limited
1292-
// depth.
1293-
self.type_variables
1294-
.borrow_mut()
1295-
.probe(v)
1296-
.known()
1297-
.map(|t| self.shallow_resolve_type(t))
1298-
.unwrap_or(typ)
1299-
}
1300-
1301-
ty::Infer(ty::IntVar(v)) => self.int_unification_table
1302-
.borrow_mut()
1303-
.probe_value(v)
1304-
.map(|v| v.to_type(self.tcx))
1305-
.unwrap_or(typ),
1306-
1307-
ty::Infer(ty::FloatVar(v)) => self.float_unification_table
1308-
.borrow_mut()
1309-
.probe_value(v)
1310-
.map(|v| v.to_type(self.tcx))
1311-
.unwrap_or(typ),
1312-
1313-
_ => typ,
1314-
}
1315-
}
1316-
13171277
/// If `TyVar(vid)` resolves to a type, return that type. Else, return the
13181278
/// universe index of `TyVar(vid)`.
13191279
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> {
13251285
}
13261286
}
13271287

1328-
pub fn shallow_resolve_type(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
1329-
self.inlined_shallow_resolve_type(typ)
1288+
pub fn shallow_resolve<T>(&self, value: T) -> T
1289+
where
1290+
T: TypeFoldable<'tcx>,
1291+
{
1292+
let mut r = ShallowResolver::new(self);
1293+
value.fold_with(&mut r)
13301294
}
13311295

13321296
pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
@@ -1391,24 +1355,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
13911355
}
13921356
}
13931357

1394-
pub fn shallow_resolve_const(
1395-
&self,
1396-
ct: &'tcx ty::Const<'tcx>
1397-
) -> &'tcx ty::Const<'tcx> {
1398-
match ct {
1399-
ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
1400-
self.const_unification_table
1401-
.borrow_mut()
1402-
.probe_value(*vid)
1403-
.val
1404-
.known()
1405-
.map(|c| self.shallow_resolve_const(c))
1406-
.unwrap_or(ct)
1407-
}
1408-
_ => ct,
1409-
}
1410-
}
1411-
14121358
pub fn fully_resolve<T: TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<'tcx, T> {
14131359
/*!
14141360
* Attempts to resolve all type/region/const variables in
@@ -1528,7 +1474,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
15281474
closure_substs: ty::ClosureSubsts<'tcx>,
15291475
) -> Option<ty::ClosureKind> {
15301476
let closure_kind_ty = closure_substs.closure_kind_ty(closure_def_id, self.tcx);
1531-
let closure_kind_ty = self.shallow_resolve_type(&closure_kind_ty);
1477+
let closure_kind_ty = self.shallow_resolve(closure_kind_ty);
15321478
closure_kind_ty.to_opt_closure_kind()
15331479
}
15341480

@@ -1542,7 +1488,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
15421488
substs: ty::ClosureSubsts<'tcx>,
15431489
) -> ty::PolyFnSig<'tcx> {
15441490
let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx);
1545-
let closure_sig_ty = self.shallow_resolve_type(&closure_sig_ty);
1491+
let closure_sig_ty = self.shallow_resolve(closure_sig_ty);
15461492
closure_sig_ty.fn_sig(self.tcx)
15471493
}
15481494

@@ -1598,6 +1544,82 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
15981544
}
15991545
}
16001546

1547+
pub struct ShallowResolver<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
1548+
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
1549+
}
1550+
1551+
impl<'a, 'gcx, 'tcx> ShallowResolver<'a, 'gcx, 'tcx> {
1552+
#[inline(always)]
1553+
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
1554+
ShallowResolver { infcx }
1555+
}
1556+
1557+
// We have this force-inlined variant of `shallow_resolve` for the one
1558+
// callsite that is extremely hot. All other callsites use the normal
1559+
// variant.
1560+
#[inline(always)]
1561+
pub fn inlined_shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
1562+
match typ.sty {
1563+
ty::Infer(ty::TyVar(v)) => {
1564+
// Not entirely obvious: if `typ` is a type variable,
1565+
// it can be resolved to an int/float variable, which
1566+
// can then be recursively resolved, hence the
1567+
// recursion. Note though that we prevent type
1568+
// variables from unifyxing to other type variables
1569+
// directly (though they may be embedded
1570+
// structurally), and we prevent cycles in any case,
1571+
// so this recursion should always be of very limited
1572+
// depth.
1573+
self.infcx.type_variables
1574+
.borrow_mut()
1575+
.probe(v)
1576+
.known()
1577+
.map(|t| self.fold_ty(t))
1578+
.unwrap_or(typ)
1579+
}
1580+
1581+
ty::Infer(ty::IntVar(v)) => self.infcx.int_unification_table
1582+
.borrow_mut()
1583+
.probe_value(v)
1584+
.map(|v| v.to_type(self.infcx.tcx))
1585+
.unwrap_or(typ),
1586+
1587+
ty::Infer(ty::FloatVar(v)) => self.infcx.float_unification_table
1588+
.borrow_mut()
1589+
.probe_value(v)
1590+
.map(|v| v.to_type(self.infcx.tcx))
1591+
.unwrap_or(typ),
1592+
1593+
_ => typ,
1594+
}
1595+
}
1596+
}
1597+
1598+
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ShallowResolver<'a, 'gcx, 'tcx> {
1599+
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
1600+
self.infcx.tcx
1601+
}
1602+
1603+
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
1604+
self.inlined_shallow_resolve(ty)
1605+
}
1606+
1607+
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
1608+
match ct {
1609+
ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
1610+
self.infcx.const_unification_table
1611+
.borrow_mut()
1612+
.probe_value(*vid)
1613+
.val
1614+
.known()
1615+
.map(|c| self.fold_const(c))
1616+
.unwrap_or(ct)
1617+
}
1618+
_ => ct,
1619+
}
1620+
}
1621+
}
1622+
16011623
impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
16021624
pub fn span(&self) -> Span {
16031625
self.cause.span

src/librustc/infer/nll_relate/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -538,10 +538,10 @@ where
538538
}
539539

540540
fn tys(&mut self, a: Ty<'tcx>, mut b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
541-
let a = self.infcx.shallow_resolve_type(a);
541+
let a = self.infcx.shallow_resolve(a);
542542

543543
if !D::forbid_inference_vars() {
544-
b = self.infcx.shallow_resolve_type(b);
544+
b = self.infcx.shallow_resolve(b);
545545
}
546546

547547
match (&a.sty, &b.sty) {

src/librustc/infer/resolve.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::ty::fold::{TypeFolder, TypeVisitor};
88

99
/// The opportunistic type resolver can be used at any time. It simply replaces
1010
/// type variables that have been unified with the things they have
11-
/// been unified with (similar to `shallow_resolve_type`, but deep). This is
11+
/// been unified with (similar to `shallow_resolve`, but deep). This is
1212
/// useful for printing messages etc but also required at various
1313
/// points for correctness.
1414
pub struct OpportunisticTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
@@ -31,7 +31,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeResolver<'a, 'g
3131
if !t.has_infer_types() {
3232
t // micro-optimize -- if there is nothing in this type that this fold affects...
3333
} else {
34-
let t0 = self.infcx.shallow_resolve_type(t);
34+
let t0 = self.infcx.shallow_resolve(t);
3535
t0.super_fold_with(self)
3636
}
3737
}
@@ -59,7 +59,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
5959
if !t.needs_infer() {
6060
t // micro-optimize -- if there is nothing in this type that this fold affects...
6161
} else {
62-
let t0 = self.infcx.shallow_resolve_type(t);
62+
let t0 = self.infcx.shallow_resolve(t);
6363
t0.super_fold_with(self)
6464
}
6565
}
@@ -78,7 +78,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
7878
if !ct.needs_infer() {
7979
ct // micro-optimize -- if there is nothing in this const that this fold affects...
8080
} else {
81-
let c0 = self.infcx.shallow_resolve_const(ct);
81+
let c0 = self.infcx.shallow_resolve(ct);
8282
c0.super_fold_with(self)
8383
}
8484
}
@@ -106,7 +106,7 @@ impl<'a, 'gcx, 'tcx> UnresolvedTypeFinder<'a, 'gcx, 'tcx> {
106106

107107
impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'gcx, 'tcx> {
108108
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
109-
let t = self.infcx.shallow_resolve_type(t);
109+
let t = self.infcx.shallow_resolve(t);
110110
if t.has_infer_types() {
111111
if let ty::Infer(infer_ty) = t.sty {
112112
// Since we called `shallow_resolve` above, this must
@@ -175,7 +175,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
175175
// ^ we need to have the `keep_local` check to un-default
176176
// defaulted tuples.
177177
} else {
178-
let t = self.infcx.shallow_resolve_type(t);
178+
let t = self.infcx.shallow_resolve(t);
179179
match t.sty {
180180
ty::Infer(ty::TyVar(vid)) => {
181181
self.err = Some(FixupError::UnresolvedTy(vid));
@@ -216,7 +216,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
216216
// ^ we need to have the `keep_local` check to un-default
217217
// defaulted tuples.
218218
} else {
219-
let c = self.infcx.shallow_resolve_const(c);
219+
let c = self.infcx.shallow_resolve(c);
220220
match c.val {
221221
ConstValue::Infer(InferConst::Var(vid)) => {
222222
self.err = Some(FixupError::UnresolvedConst(vid));

src/librustc/traits/fulfill.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::infer::InferCtxt;
1+
use crate::infer::{InferCtxt, ShallowResolver};
22
use crate::mir::interpret::{GlobalId, ErrorHandled};
33
use crate::ty::{self, Ty, TypeFoldable, ToPolyTraitRef};
44
use crate::ty::error::ExpectedFound;
@@ -255,9 +255,9 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
255255
// doing more work yet
256256
if !pending_obligation.stalled_on.is_empty() {
257257
if pending_obligation.stalled_on.iter().all(|&ty| {
258-
// Use the force-inlined variant of shallow_resolve_type() because this code is hot.
259-
let resolved_ty = self.selcx.infcx().inlined_shallow_resolve_type(&ty);
260-
resolved_ty == ty // nothing changed here
258+
// Use the force-inlined variant of shallow_resolve() because this code is hot.
259+
let resolved = ShallowResolver::new(self.selcx.infcx()).inlined_shallow_resolve(ty);
260+
resolved == ty // nothing changed here
261261
}) {
262262
debug!("process_predicate: pending obligation {:?} still stalled on {:?}",
263263
self.selcx.infcx()

src/librustc/traits/project.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,7 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
12291229
-> Progress<'tcx>
12301230
{
12311231
let self_ty = obligation_trait_ref.self_ty();
1232-
let object_ty = selcx.infcx().shallow_resolve_type(self_ty);
1232+
let object_ty = selcx.infcx().shallow_resolve(self_ty);
12331233
debug!("confirm_object_candidate(object_ty={:?})",
12341234
object_ty);
12351235
let data = match object_ty.sty {
@@ -1346,7 +1346,7 @@ fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
13461346
fn_pointer_vtable: VtableFnPointerData<'tcx, PredicateObligation<'tcx>>)
13471347
-> Progress<'tcx>
13481348
{
1349-
let fn_type = selcx.infcx().shallow_resolve_type(fn_pointer_vtable.fn_ty);
1349+
let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty);
13501350
let sig = fn_type.fn_sig(selcx.tcx());
13511351
let Normalized {
13521352
value: sig,
@@ -1371,7 +1371,7 @@ fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
13711371
let tcx = selcx.tcx();
13721372
let infcx = selcx.infcx();
13731373
let closure_sig_ty = vtable.substs.closure_sig_ty(vtable.closure_def_id, tcx);
1374-
let closure_sig = infcx.shallow_resolve_type(&closure_sig_ty).fn_sig(tcx);
1374+
let closure_sig = infcx.shallow_resolve(closure_sig_ty).fn_sig(tcx);
13751375
let Normalized {
13761376
value: closure_sig,
13771377
obligations

0 commit comments

Comments
 (0)