@@ -18,7 +18,7 @@ use crate::mir::interpret::ConstValue;
1818use crate :: session:: config:: BorrowckMode ;
1919use crate :: traits:: { self , ObligationCause , PredicateObligations , TraitEngine } ;
2020use crate :: ty:: error:: { ExpectedFound , TypeError , UnconstrainedNumeric } ;
21- use crate :: ty:: fold:: TypeFoldable ;
21+ use crate :: ty:: fold:: { TypeFolder , TypeFoldable } ;
2222use crate :: ty:: relate:: RelateResult ;
2323use crate :: ty:: subst:: { Kind , InternalSubsts , SubstsRef } ;
2424use 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+
16011623impl < ' a , ' gcx , ' tcx > TypeTrace < ' tcx > {
16021624 pub fn span ( & self ) -> Span {
16031625 self . cause . span
0 commit comments