@@ -116,7 +116,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
116116}
117117
118118/// 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 < ' _ > {
120120 // Compute the bounds on Self and the type parameters.
121121 let ty:: InstantiatedPredicates { mut predicates, .. } =
122122 tcx. predicates_of ( def_id) . instantiate_identity ( tcx) ;
@@ -138,17 +138,8 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
138138 predicates. extend ( environment) ;
139139 }
140140
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) )
152143 }
153144
154145 let local_did = def_id. as_local ( ) ;
@@ -237,19 +228,83 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
237228 traits:: normalize_param_env_or_error ( tcx, unnormalized_env, cause)
238229}
239230
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+
240291/// Walk through a function type, gathering all RPITITs and installing a
241292/// `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))` predicate into the
242293/// predicates list. This allows us to observe that an RPITIT projects to
243294/// 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 > > {
245296 tcx : TyCtxt < ' tcx > ,
246297 predicates : & ' a mut Vec < Predicate < ' tcx > > ,
247298 fn_def_id : DefId ,
248299 bound_vars : & ' tcx ty:: List < ty:: BoundVariableKind > ,
249300 seen : FxHashSet < DefId > ,
301+ hidden_ty : F ,
250302}
251303
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+ {
253308 fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> std:: ops:: ControlFlow < Self :: BreakTy > {
254309 if let ty:: Alias ( ty:: Projection , alias_ty) = * ty. kind ( )
255310 && self . tcx . def_kind ( alias_ty. def_id ) == DefKind :: ImplTraitPlaceholder
@@ -260,7 +315,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
260315 ty:: Binder :: bind_with_vars (
261316 ty:: ProjectionPredicate {
262317 projection_ty : alias_ty,
263- term : self . tcx . mk_alias ( ty :: Opaque , alias_ty) . into ( ) ,
318+ term : ( self . hidden_ty ) ( alias_ty) . into ( ) ,
264319 } ,
265320 self . bound_vars ,
266321 )
@@ -514,7 +569,9 @@ pub fn provide(providers: &mut ty::query::Providers) {
514569 * providers = ty:: query:: Providers {
515570 asyncness,
516571 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,
518575 param_env_reveal_all_normalized,
519576 instance_def_size_estimate,
520577 issue33140_self_ty,
0 commit comments