@@ -6,7 +6,6 @@ use super::{HigherRankedType, InferCtxt};
66use crate :: infer:: CombinedSnapshot ;
77use rustc_middle:: ty:: relate:: { Relate , RelateResult , TypeRelation } ;
88use rustc_middle:: ty:: { self , Binder , TypeFoldable } ;
9- use std:: cell:: Cell ;
109
1110impl < ' a , ' tcx > CombineFields < ' a , ' tcx > {
1211 /// Checks whether `for<..> sub <: for<..> sup` holds.
@@ -57,15 +56,17 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
5756
5857 debug ! ( "higher_ranked_sub: OK result={result:?}" ) ;
5958 // NOTE: returning the result here would be dangerous as it contains
60- // placeholders which **must not** be named after wards .
59+ // placeholders which **must not** be named afterwards .
6160 Ok ( ( ) )
6261 } )
6362 }
6463}
6564
6665impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
6766 /// Replaces all bound variables (lifetimes, types, and constants) bound by
68- /// `binder` with placeholder variables.
67+ /// `binder` with placeholder variables in a new universe. This means that the
68+ /// new placeholders can only be named by inference variables created after
69+ /// this method has been called.
6970 ///
7071 /// This is the first step of checking subtyping when higher-ranked things are involved.
7172 /// For more details visit the relevant sections of the [rustc dev guide].
@@ -74,34 +75,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
7475 #[ instrument( level = "debug" , skip( self ) ) ]
7576 pub fn replace_bound_vars_with_placeholders < T > ( & self , binder : ty:: Binder < ' tcx , T > ) -> T
7677 where
77- T : TypeFoldable < ' tcx > ,
78+ T : TypeFoldable < ' tcx > + Copy ,
7879 {
79- // Figure out what the next universe will be, but don't actually create
80- // it until after we've done the substitution (in particular there may
81- // be no bound variables). This is a performance optimization, since the
82- // leak check for example can be skipped if no new universes are created
83- // (i.e., if there are no placeholders).
84- let next_universe = self . universe ( ) . next_universe ( ) ;
80+ if let Some ( inner) = binder. no_bound_vars ( ) {
81+ return inner;
82+ }
83+
84+ let next_universe = self . create_next_universe ( ) ;
8585
86- let replaced_bound_var = Cell :: new ( false ) ;
8786 let fld_r = |br : ty:: BoundRegion | {
88- replaced_bound_var. set ( true ) ;
8987 self . tcx . mk_region ( ty:: RePlaceholder ( ty:: PlaceholderRegion {
9088 universe : next_universe,
9189 name : br. kind ,
9290 } ) )
9391 } ;
9492
9593 let fld_t = |bound_ty : ty:: BoundTy | {
96- replaced_bound_var. set ( true ) ;
9794 self . tcx . mk_ty ( ty:: Placeholder ( ty:: PlaceholderType {
9895 universe : next_universe,
9996 name : bound_ty. var ,
10097 } ) )
10198 } ;
10299
103100 let fld_c = |bound_var : ty:: BoundVar , ty| {
104- replaced_bound_var. set ( true ) ;
105101 self . tcx . mk_const ( ty:: ConstS {
106102 val : ty:: ConstKind :: Placeholder ( ty:: PlaceholderConst {
107103 universe : next_universe,
@@ -112,16 +108,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
112108 } ;
113109
114110 let result = self . tcx . replace_bound_vars_uncached ( binder, fld_r, fld_t, fld_c) ;
115-
116- // If there were higher-ranked regions to replace, then actually create
117- // the next universe (this avoids needlessly creating universes).
118- if replaced_bound_var. get ( ) {
119- let n_u = self . create_next_universe ( ) ;
120- assert_eq ! ( n_u, next_universe) ;
121- }
122-
123111 debug ! ( ?next_universe, ?result) ;
124-
125112 result
126113 }
127114
0 commit comments