@@ -8,11 +8,7 @@ use tracing::debug;
88use super :: explicit:: ExplicitPredicatesMap ;
99use super :: utils:: * ;
1010
11- /// Infer predicates for the items in the crate.
12- ///
13- /// `global_inferred_outlives`: this is initially the empty map that
14- /// was generated by walking the items in the crate. This will
15- /// now be filled with inferred predicates.
11+ /// Infer outlives-predicates for the items in the local crate.
1612pub ( super ) fn infer_predicates (
1713 tcx : TyCtxt < ' _ > ,
1814) -> FxIndexMap < DefId , ty:: EarlyBinder < ' _ , RequiredPredicates < ' _ > > > {
@@ -154,7 +150,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
154150 args,
155151 required_predicates,
156152 explicit_map,
157- None ,
153+ IgnorePredicatesReferencingSelf :: No ,
158154 ) ;
159155 }
160156
@@ -175,31 +171,35 @@ fn insert_required_predicates_to_be_wf<'tcx>(
175171 args,
176172 required_predicates,
177173 explicit_map,
178- None ,
174+ IgnorePredicatesReferencingSelf :: No ,
179175 ) ;
180176 }
181177
182178 ty:: Dynamic ( obj, ..) => {
183179 // This corresponds to `dyn Trait<..>`. In this case, we should
184180 // use the explicit predicates as well.
185181 debug ! ( "Dynamic" ) ;
186- if let Some ( ex_trait_ref) = obj. principal ( ) {
187- // Here, we are passing the type `usize` as a
188- // placeholder value with the function
189- // `with_self_ty`, since there is no concrete type
190- // `Self` for a `dyn Trait` at this
191- // stage. Therefore when checking explicit
192- // predicates in `check_explicit_predicates` we
193- // need to ignore checking the explicit_map for
194- // Self type.
195- let args = ex_trait_ref. with_self_ty ( tcx, tcx. types . usize ) . skip_binder ( ) . args ;
182+ if let Some ( trait_ref) = obj. principal ( ) {
183+ let args = trait_ref
184+ . with_self_ty ( tcx, tcx. types . trait_object_dummy_self )
185+ . skip_binder ( )
186+ . args ;
187+ // We skip predicates that reference the `Self` type parameter since we don't
188+ // want to leak the dummy Self to the predicates map.
189+ //
190+ // While filtering out bounds like `Self: 'a` as in `trait Trait<'a, T>: 'a {}`
191+ // doesn't matter since they can't affect the lifetime / type parameters anyway,
192+ // for bounds like `Self::AssocTy: 'b` which we of course currently also ignore
193+ // (see also #54467) it might conceivably be better to extract the binding
194+ // `AssocTy = U` from the trait object type (which must exist) and thus infer
195+ // an outlives requirement that `U: 'b`.
196196 check_explicit_predicates (
197197 tcx,
198- ex_trait_ref . skip_binder ( ) . def_id ,
198+ trait_ref . def_id ( ) ,
199199 args,
200200 required_predicates,
201201 explicit_map,
202- Some ( tcx . types . self_param ) ,
202+ IgnorePredicatesReferencingSelf :: Yes ,
203203 ) ;
204204 }
205205 }
@@ -215,7 +215,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
215215 args,
216216 required_predicates,
217217 explicit_map,
218- None ,
218+ IgnorePredicatesReferencingSelf :: No ,
219219 ) ;
220220 }
221221
@@ -244,77 +244,44 @@ fn insert_required_predicates_to_be_wf<'tcx>(
244244/// will give us `U: 'static` and `U: Outer`. The latter we
245245/// can ignore, but we will want to process `U: 'static`,
246246/// applying the instantiation as above.
247+ #[ tracing:: instrument( level = "debug" , skip( tcx) ) ]
247248fn check_explicit_predicates < ' tcx > (
248249 tcx : TyCtxt < ' tcx > ,
249250 def_id : DefId ,
250251 args : & [ GenericArg < ' tcx > ] ,
251252 required_predicates : & mut RequiredPredicates < ' tcx > ,
252253 explicit_map : & mut ExplicitPredicatesMap < ' tcx > ,
253- ignored_self_ty : Option < Ty < ' tcx > > ,
254+ ignore_preds_refing_self : IgnorePredicatesReferencingSelf ,
254255) {
255- debug ! (
256- "check_explicit_predicates(def_id={:?}, \
257- args={:?}, \
258- explicit_map={:?}, \
259- required_predicates={:?}, \
260- ignored_self_ty={:?})",
261- def_id, args, explicit_map, required_predicates, ignored_self_ty,
262- ) ;
263256 let explicit_predicates = explicit_map. explicit_predicates_of ( tcx, def_id) ;
264257
265- for ( outlives_predicate, & span) in explicit_predicates. as_ref ( ) . skip_binder ( ) {
266- debug ! ( "outlives_predicate = {outlives_predicate:?}" ) ;
267-
268- // Careful: If we are inferring the effects of a `dyn Trait<..>`
269- // type, then when we look up the predicates for `Trait`,
270- // we may find some that reference `Self`. e.g., perhaps the
271- // definition of `Trait` was:
272- //
273- // ```
274- // trait Trait<'a, T> where Self: 'a { .. }
275- // ```
276- //
277- // we want to ignore such predicates here, because
278- // there is no type parameter for them to affect. Consider
279- // a struct containing `dyn Trait`:
280- //
281- // ```
282- // struct MyStruct<'x, X> { field: Box<dyn Trait<'x, X>> }
283- // ```
284- //
285- // The `where Self: 'a` predicate refers to the *existential, hidden type*
286- // that is represented by the `dyn Trait`, not to the `X` type parameter
287- // (or any other generic parameter) declared on `MyStruct`.
288- //
289- // Note that we do this check for self **before** applying `args`. In the
290- // case that `args` come from a `dyn Trait` type, our caller will have
291- // included `Self = usize` as the value for `Self`. If we were
292- // to apply the args, and not filter this predicate, we might then falsely
293- // conclude that e.g., `X: 'x` was a reasonable inferred requirement.
294- //
295- // Another similar case is where we have an inferred
296- // requirement like `<Self as Trait>::Foo: 'b`. We presently
297- // ignore such requirements as well (cc #54467)-- though
298- // conceivably it might be better if we could extract the `Foo
299- // = X` binding from the object type (there must be such a
300- // binding) and thus infer an outlives requirement that `X:
301- // 'b`.
302- if let Some ( self_ty) = ignored_self_ty
303- && let GenericArgKind :: Type ( ty) = outlives_predicate. 0 . kind ( )
304- && ty. walk ( ) . any ( |arg| arg == self_ty. into ( ) )
258+ for ( & predicate @ ty:: OutlivesPredicate ( arg, _) , & span) in
259+ explicit_predicates. as_ref ( ) . skip_binder ( )
260+ {
261+ debug ! ( ?predicate) ;
262+
263+ if let IgnorePredicatesReferencingSelf :: Yes = ignore_preds_refing_self
264+ && arg. walk ( ) . any ( |arg| arg == tcx. types . self_param . into ( ) )
305265 {
306- debug ! ( "skipping self ty = {ty:?} " ) ;
266+ debug ! ( "ignoring predicate since it references `Self` " ) ;
307267 continue ;
308268 }
309269
310- let predicate =
311- explicit_predicates. rebind ( * outlives_predicate) . instantiate ( tcx, args) . skip_norm_wip ( ) ;
312- debug ! ( "predicate = {predicate:?}" ) ;
313- insert_outlives_predicate ( tcx, predicate. 0 , predicate. 1 , span, required_predicates) ;
270+ let predicate @ ty:: OutlivesPredicate ( arg, region) =
271+ explicit_predicates. rebind ( predicate) . instantiate ( tcx, args) . skip_norm_wip ( ) ;
272+ debug ! ( ?predicate) ;
273+
274+ insert_outlives_predicate ( tcx, arg, region, span, required_predicates) ;
314275 }
315276}
316277
317- /// Check the inferred predicates declared on the type.
278+ #[ derive( Debug ) ]
279+ enum IgnorePredicatesReferencingSelf {
280+ Yes ,
281+ No ,
282+ }
283+
284+ /// Check the inferred predicates of the type.
318285///
319286/// ### Example
320287///
0 commit comments