@@ -18,7 +18,7 @@ use crate::mir::interpret::ConstValue;
18
18
use crate :: session:: config:: BorrowckMode ;
19
19
use crate :: traits:: { self , ObligationCause , PredicateObligations , TraitEngine } ;
20
20
use crate :: ty:: error:: { ExpectedFound , TypeError , UnconstrainedNumeric } ;
21
- use crate :: ty:: fold:: TypeFoldable ;
21
+ use crate :: ty:: fold:: { TypeFolder , TypeFoldable } ;
22
22
use crate :: ty:: relate:: RelateResult ;
23
23
use crate :: ty:: subst:: { Kind , InternalSubsts , SubstsRef } ;
24
24
use crate :: ty:: { self , GenericParamDefKind , Ty , TyCtxt , CtxtInterners , InferConst } ;
@@ -919,17 +919,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
919
919
predicate : & ty:: PolySubtypePredicate < ' tcx > ,
920
920
) -> Option < InferResult < ' tcx , ( ) > > {
921
921
// 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
923
923
// variable, and because type variable's can't (at present, at
924
924
// least) capture any of the things bound by this binder.
925
925
//
926
926
// Really, there is no *particular* reason to do this
927
- // `shallow_resolve_type ` here except as a
927
+ // `shallow_resolve ` here except as a
928
928
// micro-optimization. Naturally I could not
929
929
// resist. -nmatsakis
930
930
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 ) ;
933
933
a. is_ty_var ( ) && b. is_ty_var ( )
934
934
} ;
935
935
@@ -1274,46 +1274,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1274
1274
self . resolve_type_vars_if_possible ( t) . to_string ( )
1275
1275
}
1276
1276
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
-
1317
1277
/// If `TyVar(vid)` resolves to a type, return that type. Else, return the
1318
1278
/// universe index of `TyVar(vid)`.
1319
1279
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> {
1325
1285
}
1326
1286
}
1327
1287
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)
1330
1294
}
1331
1295
1332
1296
pub fn root_var ( & self , var : ty:: TyVid ) -> ty:: TyVid {
@@ -1391,24 +1355,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1391
1355
}
1392
1356
}
1393
1357
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
-
1412
1358
pub fn fully_resolve < T : TypeFoldable < ' tcx > > ( & self , value : & T ) -> FixupResult < ' tcx , T > {
1413
1359
/*!
1414
1360
* Attempts to resolve all type/region/const variables in
@@ -1528,7 +1474,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1528
1474
closure_substs : ty:: ClosureSubsts < ' tcx > ,
1529
1475
) -> Option < ty:: ClosureKind > {
1530
1476
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) ;
1532
1478
closure_kind_ty. to_opt_closure_kind ( )
1533
1479
}
1534
1480
@@ -1542,7 +1488,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1542
1488
substs : ty:: ClosureSubsts < ' tcx > ,
1543
1489
) -> ty:: PolyFnSig < ' tcx > {
1544
1490
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) ;
1546
1492
closure_sig_ty. fn_sig ( self . tcx )
1547
1493
}
1548
1494
@@ -1598,6 +1544,82 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1598
1544
}
1599
1545
}
1600
1546
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
+
1601
1623
impl < ' a , ' gcx , ' tcx > TypeTrace < ' tcx > {
1602
1624
pub fn span ( & self ) -> Span {
1603
1625
self . cause . span
0 commit comments