@@ -108,6 +108,55 @@ impl<'tcx> InferCtxt<'tcx> {
108
108
self . tcx . replace_bound_vars_uncached ( binder, delegate)
109
109
}
110
110
111
+ /// Replaces all bound variables (lifetimes, types, and constants) bound by
112
+ /// `binder` with placeholder variables in a new universe. This means that the
113
+ /// new placeholders can only be named by inference variables created after
114
+ /// this method has been called.
115
+ ///
116
+ /// This is the first step of checking subtyping when higher-ranked things are involved.
117
+ /// For more details visit the relevant sections of the [rustc dev guide].
118
+ ///
119
+ /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
120
+ #[ instrument( level = "debug" , skip( self ) , ret) ]
121
+ pub fn instantiate_binder_and_assumptions_with_placeholders < T > (
122
+ & self ,
123
+ binder : ty:: Binder < ' tcx , T > ,
124
+ ) -> ( T , & ' tcx ty:: List < ty:: Clause < ' tcx > > )
125
+ where
126
+ T : TypeFoldable < TyCtxt < ' tcx > > + Copy ,
127
+ {
128
+ if let Some ( inner) = binder. no_bound_vars ( ) {
129
+ return ( inner, ty:: List :: empty ( ) ) ;
130
+ }
131
+
132
+ let next_universe = self . create_next_universe ( ) ;
133
+
134
+ let delegate = FnMutDelegate {
135
+ regions : & mut |br : ty:: BoundRegion | {
136
+ ty:: Region :: new_placeholder (
137
+ self . tcx ,
138
+ ty:: PlaceholderRegion { universe : next_universe, bound : br } ,
139
+ )
140
+ } ,
141
+ types : & mut |bound_ty : ty:: BoundTy | {
142
+ Ty :: new_placeholder (
143
+ self . tcx ,
144
+ ty:: PlaceholderType { universe : next_universe, bound : bound_ty } ,
145
+ )
146
+ } ,
147
+ consts : & mut |bound_var : ty:: BoundVar , ty| {
148
+ ty:: Const :: new_placeholder (
149
+ self . tcx ,
150
+ ty:: PlaceholderConst { universe : next_universe, bound : bound_var } ,
151
+ ty,
152
+ )
153
+ } ,
154
+ } ;
155
+
156
+ debug ! ( ?next_universe) ;
157
+ self . tcx . replace_bound_vars_and_predicates_uncached ( binder, delegate)
158
+ }
159
+
111
160
/// See [RegionConstraintCollector::leak_check][1]. We only check placeholder
112
161
/// leaking into `outer_universe`, i.e. placeholders which cannot be named by that
113
162
/// universe.
0 commit comments