@@ -116,7 +116,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
116
116
}
117
117
118
118
/// See `ParamEnv` struct definition for details.
119
- fn param_env ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> ty:: ParamEnv < ' _ > {
119
+ fn param_env ( tcx : TyCtxt < ' _ > , def_id : DefId , add_assumptions : bool ) -> ty:: ParamEnv < ' _ > {
120
120
// Compute the bounds on Self and the type parameters.
121
121
let ty:: InstantiatedPredicates { mut predicates, .. } =
122
122
tcx. predicates_of ( def_id) . instantiate_identity ( tcx) ;
@@ -138,17 +138,8 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
138
138
predicates. extend ( environment) ;
139
139
}
140
140
141
- if tcx. def_kind ( def_id) == DefKind :: AssocFn
142
- && tcx. associated_item ( def_id) . container == ty:: AssocItemContainer :: TraitContainer
143
- {
144
- let sig = tcx. fn_sig ( def_id) . subst_identity ( ) ;
145
- sig. visit_with ( & mut ImplTraitInTraitFinder {
146
- tcx,
147
- fn_def_id : def_id,
148
- bound_vars : sig. bound_vars ( ) ,
149
- predicates : & mut predicates,
150
- seen : FxHashSet :: default ( ) ,
151
- } ) ;
141
+ if add_assumptions && tcx. def_kind ( def_id) == DefKind :: AssocFn {
142
+ predicates. extend ( tcx. additional_method_assumptions ( def_id) )
152
143
}
153
144
154
145
let local_did = def_id. as_local ( ) ;
@@ -237,19 +228,83 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
237
228
traits:: normalize_param_env_or_error ( tcx, unnormalized_env, cause)
238
229
}
239
230
231
+ fn additional_method_assumptions < ' tcx > (
232
+ tcx : TyCtxt < ' tcx > ,
233
+ def_id : DefId ,
234
+ ) -> & ' tcx ty:: List < Predicate < ' tcx > > {
235
+ let assoc_item = tcx. associated_item ( def_id) ;
236
+ let mut predicates = vec ! [ ] ;
237
+
238
+ match assoc_item. container {
239
+ ty:: AssocItemContainer :: TraitContainer => {
240
+ let sig = tcx. fn_sig ( def_id) . subst_identity ( ) ;
241
+ sig. visit_with ( & mut ImplTraitInTraitFinder {
242
+ tcx,
243
+ fn_def_id : def_id,
244
+ bound_vars : sig. bound_vars ( ) ,
245
+ predicates : & mut predicates,
246
+ seen : FxHashSet :: default ( ) ,
247
+ hidden_ty : |alias_ty| tcx. mk_alias ( ty:: Opaque , alias_ty) ,
248
+ } ) ;
249
+ }
250
+ ty:: AssocItemContainer :: ImplContainer => {
251
+ if tcx. impl_method_has_trait_impl_trait_tys ( def_id)
252
+ && let Ok ( table)
253
+ = tcx. collect_return_position_impl_trait_in_trait_tys ( def_id)
254
+ {
255
+ let impl_def_id = assoc_item. container_id ( tcx) ;
256
+ let trait_to_impl_substs =
257
+ tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) . subst_identity ( ) . substs ;
258
+ // Create mapping from impl to placeholder.
259
+ let impl_to_placeholder_substs = ty:: InternalSubsts :: identity_for_item ( tcx, def_id) ;
260
+ // Create mapping from trait to placeholder.
261
+ let trait_to_placeholder_substs =
262
+ impl_to_placeholder_substs. rebase_onto ( tcx, impl_def_id, trait_to_impl_substs) ;
263
+
264
+ let trait_fn_def_id = assoc_item. trait_item_def_id . unwrap ( ) ;
265
+ let trait_fn_sig =
266
+ tcx. fn_sig ( trait_fn_def_id) . subst ( tcx, trait_to_placeholder_substs) ;
267
+ trait_fn_sig. visit_with ( & mut ImplTraitInTraitFinder {
268
+ tcx,
269
+ fn_def_id : trait_fn_def_id,
270
+ bound_vars : trait_fn_sig. bound_vars ( ) ,
271
+ predicates : & mut predicates,
272
+ seen : FxHashSet :: default ( ) ,
273
+ hidden_ty : |alias_ty| {
274
+ EarlyBinder ( * table. get ( & alias_ty. def_id ) . unwrap ( ) ) . subst (
275
+ tcx,
276
+ alias_ty. substs . rebase_onto (
277
+ tcx,
278
+ trait_fn_def_id,
279
+ impl_to_placeholder_substs,
280
+ ) ,
281
+ )
282
+ } ,
283
+ } ) ;
284
+ }
285
+ }
286
+ }
287
+
288
+ tcx. intern_predicates ( & predicates)
289
+ }
290
+
240
291
/// Walk through a function type, gathering all RPITITs and installing a
241
292
/// `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))` predicate into the
242
293
/// predicates list. This allows us to observe that an RPITIT projects to
243
294
/// its corresponding opaque within the body of a default-body trait method.
244
- struct ImplTraitInTraitFinder < ' a , ' tcx > {
295
+ struct ImplTraitInTraitFinder < ' a , ' tcx , F : Fn ( ty :: AliasTy < ' tcx > ) -> Ty < ' tcx > > {
245
296
tcx : TyCtxt < ' tcx > ,
246
297
predicates : & ' a mut Vec < Predicate < ' tcx > > ,
247
298
fn_def_id : DefId ,
248
299
bound_vars : & ' tcx ty:: List < ty:: BoundVariableKind > ,
249
300
seen : FxHashSet < DefId > ,
301
+ hidden_ty : F ,
250
302
}
251
303
252
- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for ImplTraitInTraitFinder < ' _ , ' tcx > {
304
+ impl < ' tcx , F > TypeVisitor < TyCtxt < ' tcx > > for ImplTraitInTraitFinder < ' _ , ' tcx , F >
305
+ where
306
+ F : Fn ( ty:: AliasTy < ' tcx > ) -> Ty < ' tcx > ,
307
+ {
253
308
fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> std:: ops:: ControlFlow < Self :: BreakTy > {
254
309
if let ty:: Alias ( ty:: Projection , alias_ty) = * ty. kind ( )
255
310
&& self . tcx . def_kind ( alias_ty. def_id ) == DefKind :: ImplTraitPlaceholder
@@ -260,7 +315,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
260
315
ty:: Binder :: bind_with_vars (
261
316
ty:: ProjectionPredicate {
262
317
projection_ty : alias_ty,
263
- term : self . tcx . mk_alias ( ty :: Opaque , alias_ty) . into ( ) ,
318
+ term : ( self . hidden_ty ) ( alias_ty) . into ( ) ,
264
319
} ,
265
320
self . bound_vars ,
266
321
)
@@ -514,7 +569,9 @@ pub fn provide(providers: &mut ty::query::Providers) {
514
569
* providers = ty:: query:: Providers {
515
570
asyncness,
516
571
adt_sized_constraint,
517
- param_env,
572
+ param_env : |tcx, def_id| param_env ( tcx, def_id, true ) ,
573
+ param_env_no_assumptions : |tcx, def_id| param_env ( tcx, def_id, false ) ,
574
+ additional_method_assumptions,
518
575
param_env_reveal_all_normalized,
519
576
instance_def_size_estimate,
520
577
issue33140_self_ty,
0 commit comments