@@ -6,7 +6,6 @@ use super::{HigherRankedType, InferCtxt};
6
6
use crate :: infer:: CombinedSnapshot ;
7
7
use rustc_middle:: ty:: relate:: { Relate , RelateResult , TypeRelation } ;
8
8
use rustc_middle:: ty:: { self , Binder , TypeFoldable } ;
9
- use std:: cell:: Cell ;
10
9
11
10
impl < ' a , ' tcx > CombineFields < ' a , ' tcx > {
12
11
/// Checks whether `for<..> sub <: for<..> sup` holds.
@@ -57,15 +56,17 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
57
56
58
57
debug ! ( "higher_ranked_sub: OK result={result:?}" ) ;
59
58
// 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 .
61
60
Ok ( ( ) )
62
61
} )
63
62
}
64
63
}
65
64
66
65
impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
67
66
/// 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.
69
70
///
70
71
/// This is the first step of checking subtyping when higher-ranked things are involved.
71
72
/// For more details visit the relevant sections of the [rustc dev guide].
@@ -74,34 +75,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
74
75
#[ instrument( level = "debug" , skip( self ) ) ]
75
76
pub fn replace_bound_vars_with_placeholders < T > ( & self , binder : ty:: Binder < ' tcx , T > ) -> T
76
77
where
77
- T : TypeFoldable < ' tcx > ,
78
+ T : TypeFoldable < ' tcx > + Copy ,
78
79
{
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 ( ) ;
85
85
86
- let replaced_bound_var = Cell :: new ( false ) ;
87
86
let fld_r = |br : ty:: BoundRegion | {
88
- replaced_bound_var. set ( true ) ;
89
87
self . tcx . mk_region ( ty:: RePlaceholder ( ty:: PlaceholderRegion {
90
88
universe : next_universe,
91
89
name : br. kind ,
92
90
} ) )
93
91
} ;
94
92
95
93
let fld_t = |bound_ty : ty:: BoundTy | {
96
- replaced_bound_var. set ( true ) ;
97
94
self . tcx . mk_ty ( ty:: Placeholder ( ty:: PlaceholderType {
98
95
universe : next_universe,
99
96
name : bound_ty. var ,
100
97
} ) )
101
98
} ;
102
99
103
100
let fld_c = |bound_var : ty:: BoundVar , ty| {
104
- replaced_bound_var. set ( true ) ;
105
101
self . tcx . mk_const ( ty:: ConstS {
106
102
val : ty:: ConstKind :: Placeholder ( ty:: PlaceholderConst {
107
103
universe : next_universe,
@@ -112,16 +108,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
112
108
} ;
113
109
114
110
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
-
123
111
debug ! ( ?next_universe, ?result) ;
124
-
125
112
result
126
113
}
127
114
0 commit comments