diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 8d4f96639efbd..429e62c4a1c63 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1539,9 +1539,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); debug!(?opaque_ty_def_id); - // Contains the new lifetime definitions created for the TAIT (if any). - let mut collected_lifetimes = Vec::new(); - // If this came from a TAIT (as opposed to a function that returns an RPIT), we only want // to capture the lifetimes that appear in the bounds. So visit the bounds to find out // exactly which ones those are. @@ -1558,20 +1555,31 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; debug!(?lifetimes_to_remap); - self.with_hir_id_owner(opaque_ty_node_id, |lctx| { - let mut new_remapping = FxHashMap::default(); + let mut new_remapping = FxHashMap::default(); - // If this opaque type is only capturing a subset of the lifetimes (those that appear - // in bounds), then create the new lifetime parameters required and create a mapping - // from the old `'a` (on the function) to the new `'a` (on the opaque type). - collected_lifetimes = lctx.create_lifetime_defs( - opaque_ty_def_id, - &lifetimes_to_remap, - &mut new_remapping, - ); - debug!(?collected_lifetimes); - debug!(?new_remapping); + // Contains the new lifetime definitions created for the TAIT (if any). + // If this opaque type is only capturing a subset of the lifetimes (those that appear in + // bounds), then create the new lifetime parameters required and create a mapping from the + // old `'a` (on the function) to the new `'a` (on the opaque type). + let collected_lifetimes = + self.create_lifetime_defs(opaque_ty_def_id, &lifetimes_to_remap, &mut new_remapping); + debug!(?collected_lifetimes); + debug!(?new_remapping); + + // This creates HIR lifetime arguments as `hir::GenericArg`, in the given example `type + // TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection containing `&['x]`. + let collected_lifetime_mapping: Vec<_> = collected_lifetimes + .iter() + .map(|(node_id, lifetime)| { + let id = self.next_node_id(); + let lifetime = self.new_named_lifetime(lifetime.id, id, lifetime.ident); + let def_id = self.local_def_id(*node_id); + (lifetime, def_id) + }) + .collect(); + debug!(?collected_lifetime_mapping); + self.with_hir_id_owner(opaque_ty_node_id, |lctx| { // Install the remapping from old to new (if any): lctx.with_remapping(new_remapping, |lctx| { // This creates HIR lifetime definitions as `hir::GenericParam`, in the given @@ -1610,6 +1618,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let hir_bounds = lctx.lower_param_bounds(bounds, itctx); debug!(?hir_bounds); + let lifetime_mapping = if in_trait { + self.arena.alloc_from_iter( + collected_lifetime_mapping + .iter() + .map(|(lifetime, def_id)| (**lifetime, *def_id)), + ) + } else { + &mut [] + }; + let opaque_ty_item = hir::OpaqueTy { generics: self.arena.alloc(hir::Generics { params: lifetime_defs, @@ -1620,6 +1638,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }), bounds: hir_bounds, origin, + lifetime_mapping, in_trait, }; debug!(?opaque_ty_item); @@ -1628,20 +1647,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) }); - // This creates HIR lifetime arguments as `hir::GenericArg`, in the given example `type - // TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection containing `&['x]`. - let lifetimes = - self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| { - let id = self.next_node_id(); - let l = self.new_named_lifetime(lifetime.id, id, lifetime.ident); - hir::GenericArg::Lifetime(l) - })); - debug!(?lifetimes); - // `impl Trait` now just becomes `Foo<'a, 'b, ..>`. hir::TyKind::OpaqueDef( hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } }, - lifetimes, + self.arena.alloc_from_iter( + collected_lifetime_mapping + .iter() + .map(|(lifetime, _)| hir::GenericArg::Lifetime(*lifetime)), + ), in_trait, ) } @@ -1655,7 +1668,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: Span, opaque_ty_span: Span, ) -> hir::OwnerNode<'hir> { - let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(opaque_ty_item); + let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(self.arena.alloc(opaque_ty_item)); // Generate an `type Foo = impl Trait;` declaration. trace!("registering opaque type with id {:#?}", opaque_ty_id); let opaque_ty_item = hir::Item { @@ -1983,7 +1996,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let lifetime = Lifetime { id: outer_node_id, ident }; collected_lifetimes.push((inner_node_id, lifetime, Some(inner_res))); } - debug!(?collected_lifetimes); // We only want to capture the lifetimes that appear in the bounds. So visit the bounds to @@ -1993,22 +2005,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let lifetimes_to_remap = lifetime_collector::lifetimes_in_ret_ty(&self.resolver, output); debug!(?lifetimes_to_remap); - self.with_hir_id_owner(opaque_ty_node_id, |this| { - // If this opaque type is only capturing a subset of the lifetimes (those that appear - // in bounds), then create the new lifetime parameters required and create a mapping - // from the old `'a` (on the function) to the new `'a` (on the opaque type). - collected_lifetimes.extend( - this.create_lifetime_defs( - opaque_ty_def_id, - &lifetimes_to_remap, - &mut new_remapping, - ) + // If this opaque type is only capturing a subset of the lifetimes (those that appear in + // bounds), then create the new lifetime parameters required and create a mapping from the + // old `'a` (on the function) to the new `'a` (on the opaque type). + collected_lifetimes.extend( + self.create_lifetime_defs(opaque_ty_def_id, &lifetimes_to_remap, &mut new_remapping) .into_iter() .map(|(new_node_id, lifetime)| (new_node_id, lifetime, None)), - ); - debug!(?collected_lifetimes); - debug!(?new_remapping); + ); + debug!(?collected_lifetimes); + debug!(?new_remapping); + + // This creates pairs of HIR lifetimes and def_ids. In the given example `type + // TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection containing the + // new lifetime of the RPIT 'x and the def_id of the lifetime 'x corresponding to + // `TestReturn`. + let collected_lifetime_mapping: Vec<_> = collected_lifetimes + .iter() + .map(|(node_id, lifetime, res)| { + let id = self.next_node_id(); + let res = res.unwrap_or( + self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error), + ); + let lifetime = self.new_named_lifetime_with_res(id, lifetime.ident, res); + let def_id = self.local_def_id(*node_id); + (lifetime, def_id) + }) + .collect(); + debug!(?collected_lifetime_mapping); + self.with_hir_id_owner(opaque_ty_node_id, |this| { // Install the remapping from old to new (if any): this.with_remapping(new_remapping, |this| { // We have to be careful to get elision right here. The @@ -2063,6 +2089,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { )); debug!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params); + let lifetime_mapping = if in_trait { + self.arena.alloc_from_iter( + collected_lifetime_mapping + .iter() + .map(|(lifetime, def_id)| (**lifetime, *def_id)), + ) + } else { + &mut [] + }; + let opaque_ty_item = hir::OpaqueTy { generics: this.arena.alloc(hir::Generics { params: generic_params, @@ -2073,6 +2109,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }), bounds: arena_vec![this; future_bound], origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id), + lifetime_mapping, in_trait, }; @@ -2096,15 +2133,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // For the "output" lifetime parameters, we just want to // generate `'_`. - let generic_args = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map( - |(_, lifetime, res)| { - let id = self.next_node_id(); - let res = res.unwrap_or( - self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error), - ); - hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, lifetime.ident, res)) - }, - )); + let generic_args = self.arena.alloc_from_iter( + collected_lifetime_mapping + .iter() + .map(|(lifetime, _)| hir::GenericArg::Lifetime(*lifetime)), + ); // Create the `Foo<...>` reference itself. Note that the `type // Foo = impl Trait` is, internally, created as a child of the diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 591831b59a1a4..6c419471de1b4 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2664,6 +2664,10 @@ pub struct OpaqueTy<'hir> { pub generics: &'hir Generics<'hir>, pub bounds: GenericBounds<'hir>, pub origin: OpaqueTyOrigin, + // Opaques have duplicated lifetimes, this mapping connects the original lifetime with the copy + // so we can later generate bidirectional outlives predicates to enforce that these lifetimes + // stay in sync. + pub lifetime_mapping: &'hir [(Lifetime, LocalDefId)], pub in_trait: bool, } @@ -3315,7 +3319,7 @@ pub enum ItemKind<'hir> { /// A type alias, e.g., `type Foo = Bar`. TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>), /// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`. - OpaqueTy(OpaqueTy<'hir>), + OpaqueTy(&'hir OpaqueTy<'hir>), /// An enum definition, e.g., `enum Foo {C, D}`. Enum(EnumDef<'hir>, &'hir Generics<'hir>), /// A struct definition, e.g., `struct Foo {x: A}`. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 1886a91bda838..347c1f4637f17 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -502,7 +502,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { visitor.visit_ty(ty); visitor.visit_generics(generics) } - ItemKind::OpaqueTy(OpaqueTy { ref generics, bounds, .. }) => { + ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, .. }) => { visitor.visit_id(item.hir_id()); walk_generics(visitor, generics); walk_list!(visitor, visit_param_bound, bounds); diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 5032378923b79..924f6e723e843 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2809,7 +2809,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let opaque_ty = tcx.hir().item(item_id); match opaque_ty.kind { - hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => { + hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => { let local_def_id = item_id.owner_id.def_id; // If this is an RPITIT and we are using the new RPITIT lowering scheme, we // generate the def_id of an associated type for the trait and return as diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index a7e81f41c6996..346e153a69d02 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -299,7 +299,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( } } - if let ItemKind::OpaqueTy(hir::OpaqueTy { + if let ItemKind::OpaqueTy(&hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..), in_trait, .. diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index e92a0dcc1fb1f..2206f640529ca 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -144,7 +144,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { Some(tcx.typeck_root_def_id(def_id.to_def_id())) } Node::Item(item) => match item.kind { - ItemKind::OpaqueTy(hir::OpaqueTy { + ItemKind::OpaqueTy(&hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id), in_trait, diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index d9b2aacab9d66..b9e71aaa00402 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -2,7 +2,7 @@ use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter}; use crate::bounds::Bounds; use crate::collect::ItemCtxt; use crate::constrained_generic_params as cgp; -use hir::{HirId, Node}; +use hir::{HirId, Lifetime, Node}; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -10,9 +10,9 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{GenericPredicates, ToPredicate}; +use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate}; use rustc_span::symbol::{sym, Ident}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::{Span, Symbol, DUMMY_SP}; /// Returns a list of all type predicates (explicit and implicit) for the definition with /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus @@ -62,6 +62,54 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> { use rustc_hir::*; + match tcx.opt_rpitit_info(def_id.to_def_id()) { + Some(ImplTraitInTraitData::Trait { opaque_def_id, .. }) => { + let opaque_ty_id = tcx.hir().local_def_id_to_hir_id(opaque_def_id.expect_local()); + let opaque_ty_node = tcx.hir().get(opaque_ty_id); + let Node::Item(&Item { kind: ItemKind::OpaqueTy(OpaqueTy { lifetime_mapping, .. }), .. }) = opaque_ty_node else { + bug!("unexpected {opaque_ty_node:?}") + }; + + let mut predicates = Vec::new(); + compute_bidirectional_outlives_predicates( + tcx, + def_id, + lifetime_mapping.iter().map(|(lifetime, def_id)| { + (*lifetime, (*def_id, lifetime.ident.name, lifetime.ident.span)) + }), + tcx.generics_of(def_id.to_def_id()), + &mut predicates, + ); + + return ty::GenericPredicates { + parent: Some(tcx.parent(def_id.to_def_id())), + predicates: tcx.arena.alloc_from_iter(predicates), + }; + } + + Some(ImplTraitInTraitData::Impl { fn_def_id }) => { + let assoc_item = tcx.associated_item(def_id); + let trait_assoc_predicates = tcx.predicates_of(assoc_item.trait_item_def_id.unwrap()); + + let impl_assoc_identity_substs = InternalSubsts::identity_for_item(tcx, def_id); + let impl_def_id = tcx.parent(fn_def_id); + let impl_trait_ref_substs = + tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder().substs; + + let impl_assoc_substs = + impl_assoc_identity_substs.rebase_onto(tcx, impl_def_id, impl_trait_ref_substs); + + let impl_predicates = trait_assoc_predicates.instantiate_own(tcx, impl_assoc_substs); + + return ty::GenericPredicates { + parent: Some(impl_def_id), + predicates: tcx.arena.alloc_from_iter(impl_predicates), + }; + } + + None => {} + } + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let node = tcx.hir().get(hir_id); @@ -289,38 +337,22 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen bug!("unexpected {opaque_ty_node:?}") }; debug!(?lifetimes); - for (arg, duplicate) in std::iter::zip(lifetimes, ast_generics.params) { - let hir::GenericArg::Lifetime(arg) = arg else { bug!() }; - let orig_region = icx.astconv().ast_region_to_region(&arg, None); - if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) { - // Only early-bound regions can point to the original generic parameter. - continue; - } - - let hir::GenericParamKind::Lifetime { .. } = duplicate.kind else { continue }; - let dup_def = duplicate.def_id.to_def_id(); - let Some(dup_index) = generics.param_def_id_to_index(tcx, dup_def) else { bug!() }; + let lifetime_mapping = std::iter::zip(lifetimes, ast_generics.params) + .map(|(arg, dup)| { + let hir::GenericArg::Lifetime(arg) = arg else { bug!() }; + (**arg, dup) + }) + .filter(|(_, dup)| matches!(dup.kind, hir::GenericParamKind::Lifetime { .. })) + .map(|(lifetime, dup)| (lifetime, (dup.def_id, dup.name.ident().name, dup.span))); - let dup_region = ty::Region::new_early_bound( - tcx, - ty::EarlyBoundRegion { - def_id: dup_def, - index: dup_index, - name: duplicate.name.ident().name, - }, - ); - predicates.push(( - ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_region, dup_region)) - .to_predicate(icx.tcx), - duplicate.span, - )); - predicates.push(( - ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_region, orig_region)) - .to_predicate(icx.tcx), - duplicate.span, - )); - } + compute_bidirectional_outlives_predicates( + tcx, + def_id, + lifetime_mapping, + generics, + &mut predicates, + ); debug!(?predicates); } @@ -330,6 +362,46 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } } +/// Opaques have duplicated lifetimes and we need to compute bidirectional outlives predicates to +/// enforce that these lifetimes stay in sync. +fn compute_bidirectional_outlives_predicates<'tcx>( + tcx: TyCtxt<'tcx>, + item_def_id: LocalDefId, + lifetime_mapping: impl Iterator, + generics: &Generics, + predicates: &mut Vec<(ty::Clause<'tcx>, Span)>, +) { + let icx = ItemCtxt::new(tcx, item_def_id); + + for (arg, (dup_def, name, span)) in lifetime_mapping { + let orig_region = icx.astconv().ast_region_to_region(&arg, None); + if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) { + // There is no late-bound lifetime to actually match up here, since the lifetime doesn't + // show up in the opaque's parent's substs. + continue; + } + + let Some(dup_index) = generics.param_def_id_to_index(icx.tcx, dup_def.to_def_id()) else { bug!() }; + + let dup_region = ty::Region::new_early_bound( + tcx, + ty::EarlyBoundRegion { def_id: dup_def.to_def_id(), index: dup_index, name }, + ); + + predicates.push(( + ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_region, dup_region)) + .to_predicate(tcx), + span, + )); + + predicates.push(( + ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_region, orig_region)) + .to_predicate(tcx), + span, + )); + } +} + fn const_evaluatable_predicates_of( tcx: TyCtxt<'_>, def_id: LocalDefId, @@ -668,7 +740,7 @@ pub(super) fn type_param_predicates( ItemKind::Fn(.., generics, _) | ItemKind::Impl(&hir::Impl { generics, .. }) | ItemKind::TyAlias(_, generics) - | ItemKind::OpaqueTy(OpaqueTy { + | ItemKind::OpaqueTy(&OpaqueTy { generics, origin: hir::OpaqueTyOrigin::TyAlias { .. }, .. diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 3d75df8c69f07..c8b405228a56f 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -556,7 +556,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { }); } } - hir::ItemKind::OpaqueTy(hir::OpaqueTy { + hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent), generics, .. diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 318d0d0c22397..bd92ee4b550a3 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -435,7 +435,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder opaque::find_opaque_ty_constraints_for_tait(tcx, def_id), // Opaque types desugared from `impl Trait`. - ItemKind::OpaqueTy(OpaqueTy { + ItemKind::OpaqueTy(&OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), in_trait, diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 5b731641e9d53..b59458bbf35cc 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -340,12 +340,6 @@ fn associated_type_for_impl_trait_in_trait( } }); - // There are no predicates for the synthesized associated type. - trait_assoc_ty.explicit_predicates_of(ty::GenericPredicates { - parent: Some(trait_def_id.to_def_id()), - predicates: &[], - }); - // There are no inferred outlives for the synthesized associated type. trait_assoc_ty.inferred_outlives_of(&[]); @@ -424,12 +418,6 @@ fn associated_type_for_impl_trait_in_impl( } }); - // There are no predicates for the synthesized associated type. - impl_assoc_ty.explicit_predicates_of(ty::GenericPredicates { - parent: Some(impl_local_def_id.to_def_id()), - predicates: &[], - }); - // There are no inferred outlives for the synthesized associated type. impl_assoc_ty.inferred_outlives_of(&[]); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 2daab520a2f73..2b391f94a6335 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -131,7 +131,9 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) | Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) { - predicates = tcx.predicates_of(fn_def_id).instantiate_identity(tcx).predicates; + // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): Should not need to add the predicates + // from the parent fn to our assumptions + predicates.extend(tcx.predicates_of(fn_def_id).instantiate_identity(tcx).predicates); } // Finally, we have to normalize the bounds in the environment, in diff --git a/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs b/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs index d5481d277e40a..9869a8d71c278 100644 --- a/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs +++ b/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs @@ -1,5 +1,7 @@ // check-pass // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/in-trait/async-lifetimes.rs b/tests/ui/async-await/in-trait/async-lifetimes.rs index f298e45d2390b..ecbd1910ac4ba 100644 --- a/tests/ui/async-await/in-trait/async-lifetimes.rs +++ b/tests/ui/async-await/in-trait/async-lifetimes.rs @@ -1,5 +1,7 @@ // check-pass // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)]