Skip to content

Commit 3307274

Browse files
committedJun 29, 2023
Auto merge of rust-lang#112682 - spastorino:new-rpitit-21, r=compiler-errors
Add bidirectional where clauses on RPITIT synthesized GATs Given the following: ```rust struct MyStruct<'a, T>(&'a T); trait MyTrait<'a, T> { fn my_fn<'b, 'c, 'd, V>(item: &'c String) -> impl Sized + 'a + 'b + 'c where V: 'b, V: 'd; } impl<'a, T> MyTrait<'a, T> for MyStruct<'a, T> { fn my_fn<'b, 'c, 'd, V>(_: &'c String) -> impl Sized + 'a + 'b + 'c where V: 'b, V: 'd, { unimplemented!(); } } ``` We need the desugaring to be: ```rust trait MyTrait<'a, T> { type MyFn<'bf, 'df, Vf, 'a2, 'b2, 'c2>: Sized + 'a2 + 'b2 + 'c2 where Vf: 'b2, 'a2: 'a, 'a: 'a2, 'b2: 'bf, 'bf: 'b2; fn my_fn<'b, 'c, 'd, V>(item: &'c String) -> MyStruct<'a>::MyFn<'b, 'd, V, 'a, 'b, 'c> where V: 'b, V: 'd { type opaque<'a3, 'b3, 'c3>; }; } impl<'a, T> MyIter<'a, T> for MyStruct<'a, T> { type MyFn<'bf, 'df, Vf, 'a2, 'b2, 'c2> = impl Sized + 'a2 + 'b2 + 'c2 where Vf: b2, 'a2: 'a, 'a: 'a2, 'b2: 'bf, 'bf: 'b2; fn my_fn<'b, 'c, 'd, V>(_: &'c String) -> MyStruct<'a>::MyFn<'a, 'b, 'c, V> where V: 'b, V: 'd { type opaque<'a3, 'b3, 'c3>; unimplemented!(); } } ``` This PR adds the where clauses for the `MyFn` generated GATs. This is a draft with a very ugly solution so we can make comments over concrete code. r? `@compiler-errors`
2 parents b23a5ad + 6f4a51e commit 3307274

File tree

13 files changed

+207
-104
lines changed

13 files changed

+207
-104
lines changed
 

‎compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 83 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,9 +1539,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15391539
);
15401540
debug!(?opaque_ty_def_id);
15411541

1542-
// Contains the new lifetime definitions created for the TAIT (if any).
1543-
let mut collected_lifetimes = Vec::new();
1544-
15451542
// If this came from a TAIT (as opposed to a function that returns an RPIT), we only want
15461543
// to capture the lifetimes that appear in the bounds. So visit the bounds to find out
15471544
// exactly which ones those are.
@@ -1558,20 +1555,31 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15581555
};
15591556
debug!(?lifetimes_to_remap);
15601557

1561-
self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
1562-
let mut new_remapping = FxHashMap::default();
1558+
let mut new_remapping = FxHashMap::default();
15631559

1564-
// If this opaque type is only capturing a subset of the lifetimes (those that appear
1565-
// in bounds), then create the new lifetime parameters required and create a mapping
1566-
// from the old `'a` (on the function) to the new `'a` (on the opaque type).
1567-
collected_lifetimes = lctx.create_lifetime_defs(
1568-
opaque_ty_def_id,
1569-
&lifetimes_to_remap,
1570-
&mut new_remapping,
1571-
);
1572-
debug!(?collected_lifetimes);
1573-
debug!(?new_remapping);
1560+
// Contains the new lifetime definitions created for the TAIT (if any).
1561+
// If this opaque type is only capturing a subset of the lifetimes (those that appear in
1562+
// bounds), then create the new lifetime parameters required and create a mapping from the
1563+
// old `'a` (on the function) to the new `'a` (on the opaque type).
1564+
let collected_lifetimes =
1565+
self.create_lifetime_defs(opaque_ty_def_id, &lifetimes_to_remap, &mut new_remapping);
1566+
debug!(?collected_lifetimes);
1567+
debug!(?new_remapping);
1568+
1569+
// This creates HIR lifetime arguments as `hir::GenericArg`, in the given example `type
1570+
// TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection containing `&['x]`.
1571+
let collected_lifetime_mapping: Vec<_> = collected_lifetimes
1572+
.iter()
1573+
.map(|(node_id, lifetime)| {
1574+
let id = self.next_node_id();
1575+
let lifetime = self.new_named_lifetime(lifetime.id, id, lifetime.ident);
1576+
let def_id = self.local_def_id(*node_id);
1577+
(lifetime, def_id)
1578+
})
1579+
.collect();
1580+
debug!(?collected_lifetime_mapping);
15741581

1582+
self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
15751583
// Install the remapping from old to new (if any):
15761584
lctx.with_remapping(new_remapping, |lctx| {
15771585
// This creates HIR lifetime definitions as `hir::GenericParam`, in the given
@@ -1610,6 +1618,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16101618
let hir_bounds = lctx.lower_param_bounds(bounds, itctx);
16111619
debug!(?hir_bounds);
16121620

1621+
let lifetime_mapping = if in_trait {
1622+
self.arena.alloc_from_iter(
1623+
collected_lifetime_mapping
1624+
.iter()
1625+
.map(|(lifetime, def_id)| (**lifetime, *def_id)),
1626+
)
1627+
} else {
1628+
&mut []
1629+
};
1630+
16131631
let opaque_ty_item = hir::OpaqueTy {
16141632
generics: self.arena.alloc(hir::Generics {
16151633
params: lifetime_defs,
@@ -1620,6 +1638,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16201638
}),
16211639
bounds: hir_bounds,
16221640
origin,
1641+
lifetime_mapping,
16231642
in_trait,
16241643
};
16251644
debug!(?opaque_ty_item);
@@ -1628,20 +1647,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16281647
})
16291648
});
16301649

1631-
// This creates HIR lifetime arguments as `hir::GenericArg`, in the given example `type
1632-
// TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection containing `&['x]`.
1633-
let lifetimes =
1634-
self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| {
1635-
let id = self.next_node_id();
1636-
let l = self.new_named_lifetime(lifetime.id, id, lifetime.ident);
1637-
hir::GenericArg::Lifetime(l)
1638-
}));
1639-
debug!(?lifetimes);
1640-
16411650
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
16421651
hir::TyKind::OpaqueDef(
16431652
hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
1644-
lifetimes,
1653+
self.arena.alloc_from_iter(
1654+
collected_lifetime_mapping
1655+
.iter()
1656+
.map(|(lifetime, _)| hir::GenericArg::Lifetime(*lifetime)),
1657+
),
16451658
in_trait,
16461659
)
16471660
}
@@ -1655,7 +1668,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16551668
span: Span,
16561669
opaque_ty_span: Span,
16571670
) -> hir::OwnerNode<'hir> {
1658-
let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(opaque_ty_item);
1671+
let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(self.arena.alloc(opaque_ty_item));
16591672
// Generate an `type Foo = impl Trait;` declaration.
16601673
trace!("registering opaque type with id {:#?}", opaque_ty_id);
16611674
let opaque_ty_item = hir::Item {
@@ -1983,7 +1996,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19831996
let lifetime = Lifetime { id: outer_node_id, ident };
19841997
collected_lifetimes.push((inner_node_id, lifetime, Some(inner_res)));
19851998
}
1986-
19871999
debug!(?collected_lifetimes);
19882000

19892001
// 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> {
19932005
let lifetimes_to_remap = lifetime_collector::lifetimes_in_ret_ty(&self.resolver, output);
19942006
debug!(?lifetimes_to_remap);
19952007

1996-
self.with_hir_id_owner(opaque_ty_node_id, |this| {
1997-
// If this opaque type is only capturing a subset of the lifetimes (those that appear
1998-
// in bounds), then create the new lifetime parameters required and create a mapping
1999-
// from the old `'a` (on the function) to the new `'a` (on the opaque type).
2000-
collected_lifetimes.extend(
2001-
this.create_lifetime_defs(
2002-
opaque_ty_def_id,
2003-
&lifetimes_to_remap,
2004-
&mut new_remapping,
2005-
)
2008+
// If this opaque type is only capturing a subset of the lifetimes (those that appear in
2009+
// bounds), then create the new lifetime parameters required and create a mapping from the
2010+
// old `'a` (on the function) to the new `'a` (on the opaque type).
2011+
collected_lifetimes.extend(
2012+
self.create_lifetime_defs(opaque_ty_def_id, &lifetimes_to_remap, &mut new_remapping)
20062013
.into_iter()
20072014
.map(|(new_node_id, lifetime)| (new_node_id, lifetime, None)),
2008-
);
2009-
debug!(?collected_lifetimes);
2010-
debug!(?new_remapping);
2015+
);
2016+
debug!(?collected_lifetimes);
2017+
debug!(?new_remapping);
2018+
2019+
// This creates pairs of HIR lifetimes and def_ids. In the given example `type
2020+
// TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection containing the
2021+
// new lifetime of the RPIT 'x and the def_id of the lifetime 'x corresponding to
2022+
// `TestReturn`.
2023+
let collected_lifetime_mapping: Vec<_> = collected_lifetimes
2024+
.iter()
2025+
.map(|(node_id, lifetime, res)| {
2026+
let id = self.next_node_id();
2027+
let res = res.unwrap_or(
2028+
self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error),
2029+
);
2030+
let lifetime = self.new_named_lifetime_with_res(id, lifetime.ident, res);
2031+
let def_id = self.local_def_id(*node_id);
2032+
(lifetime, def_id)
2033+
})
2034+
.collect();
2035+
debug!(?collected_lifetime_mapping);
20112036

2037+
self.with_hir_id_owner(opaque_ty_node_id, |this| {
20122038
// Install the remapping from old to new (if any):
20132039
this.with_remapping(new_remapping, |this| {
20142040
// We have to be careful to get elision right here. The
@@ -2063,6 +2089,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20632089
));
20642090
debug!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params);
20652091

2092+
let lifetime_mapping = if in_trait {
2093+
self.arena.alloc_from_iter(
2094+
collected_lifetime_mapping
2095+
.iter()
2096+
.map(|(lifetime, def_id)| (**lifetime, *def_id)),
2097+
)
2098+
} else {
2099+
&mut []
2100+
};
2101+
20662102
let opaque_ty_item = hir::OpaqueTy {
20672103
generics: this.arena.alloc(hir::Generics {
20682104
params: generic_params,
@@ -2073,6 +2109,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20732109
}),
20742110
bounds: arena_vec![this; future_bound],
20752111
origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
2112+
lifetime_mapping,
20762113
in_trait,
20772114
};
20782115

@@ -2096,15 +2133,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20962133
//
20972134
// For the "output" lifetime parameters, we just want to
20982135
// generate `'_`.
2099-
let generic_args = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(
2100-
|(_, lifetime, res)| {
2101-
let id = self.next_node_id();
2102-
let res = res.unwrap_or(
2103-
self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error),
2104-
);
2105-
hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, lifetime.ident, res))
2106-
},
2107-
));
2136+
let generic_args = self.arena.alloc_from_iter(
2137+
collected_lifetime_mapping
2138+
.iter()
2139+
.map(|(lifetime, _)| hir::GenericArg::Lifetime(*lifetime)),
2140+
);
21082141

21092142
// Create the `Foo<...>` reference itself. Note that the `type
21102143
// Foo = impl Trait` is, internally, created as a child of the

‎compiler/rustc_hir/src/hir.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2664,6 +2664,10 @@ pub struct OpaqueTy<'hir> {
26642664
pub generics: &'hir Generics<'hir>,
26652665
pub bounds: GenericBounds<'hir>,
26662666
pub origin: OpaqueTyOrigin,
2667+
// Opaques have duplicated lifetimes, this mapping connects the original lifetime with the copy
2668+
// so we can later generate bidirectional outlives predicates to enforce that these lifetimes
2669+
// stay in sync.
2670+
pub lifetime_mapping: &'hir [(Lifetime, LocalDefId)],
26672671
pub in_trait: bool,
26682672
}
26692673

@@ -3315,7 +3319,7 @@ pub enum ItemKind<'hir> {
33153319
/// A type alias, e.g., `type Foo = Bar<u8>`.
33163320
TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
33173321
/// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
3318-
OpaqueTy(OpaqueTy<'hir>),
3322+
OpaqueTy(&'hir OpaqueTy<'hir>),
33193323
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
33203324
Enum(EnumDef<'hir>, &'hir Generics<'hir>),
33213325
/// A struct definition, e.g., `struct Foo<A> {x: A}`.

‎compiler/rustc_hir/src/intravisit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
502502
visitor.visit_ty(ty);
503503
visitor.visit_generics(generics)
504504
}
505-
ItemKind::OpaqueTy(OpaqueTy { ref generics, bounds, .. }) => {
505+
ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, .. }) => {
506506
visitor.visit_id(item.hir_id());
507507
walk_generics(visitor, generics);
508508
walk_list!(visitor, visit_param_bound, bounds);

‎compiler/rustc_hir_analysis/src/astconv/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2809,7 +2809,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
28092809
let opaque_ty = tcx.hir().item(item_id);
28102810

28112811
match opaque_ty.kind {
2812-
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
2812+
hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => {
28132813
let local_def_id = item_id.owner_id.def_id;
28142814
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we
28152815
// generate the def_id of an associated type for the trait and return as

‎compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
299299
}
300300
}
301301

302-
if let ItemKind::OpaqueTy(hir::OpaqueTy {
302+
if let ItemKind::OpaqueTy(&hir::OpaqueTy {
303303
origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
304304
in_trait,
305305
..

‎compiler/rustc_hir_analysis/src/collect/generics_of.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
144144
Some(tcx.typeck_root_def_id(def_id.to_def_id()))
145145
}
146146
Node::Item(item) => match item.kind {
147-
ItemKind::OpaqueTy(hir::OpaqueTy {
147+
ItemKind::OpaqueTy(&hir::OpaqueTy {
148148
origin:
149149
hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
150150
in_trait,

‎compiler/rustc_hir_analysis/src/collect/predicates_of.rs

Lines changed: 106 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
22
use crate::bounds::Bounds;
33
use crate::collect::ItemCtxt;
44
use crate::constrained_generic_params as cgp;
5-
use hir::{HirId, Node};
5+
use hir::{HirId, Lifetime, Node};
66
use rustc_data_structures::fx::FxIndexSet;
77
use rustc_hir as hir;
88
use rustc_hir::def::DefKind;
99
use rustc_hir::def_id::{DefId, LocalDefId};
1010
use rustc_hir::intravisit::{self, Visitor};
1111
use rustc_middle::ty::subst::InternalSubsts;
1212
use rustc_middle::ty::{self, Ty, TyCtxt};
13-
use rustc_middle::ty::{GenericPredicates, ToPredicate};
13+
use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate};
1414
use rustc_span::symbol::{sym, Ident};
15-
use rustc_span::{Span, DUMMY_SP};
15+
use rustc_span::{Span, Symbol, DUMMY_SP};
1616

1717
/// Returns a list of all type predicates (explicit and implicit) for the definition with
1818
/// 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
6262
fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> {
6363
use rustc_hir::*;
6464

65+
match tcx.opt_rpitit_info(def_id.to_def_id()) {
66+
Some(ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
67+
let opaque_ty_id = tcx.hir().local_def_id_to_hir_id(opaque_def_id.expect_local());
68+
let opaque_ty_node = tcx.hir().get(opaque_ty_id);
69+
let Node::Item(&Item { kind: ItemKind::OpaqueTy(OpaqueTy { lifetime_mapping, .. }), .. }) = opaque_ty_node else {
70+
bug!("unexpected {opaque_ty_node:?}")
71+
};
72+
73+
let mut predicates = Vec::new();
74+
compute_bidirectional_outlives_predicates(
75+
tcx,
76+
def_id,
77+
lifetime_mapping.iter().map(|(lifetime, def_id)| {
78+
(*lifetime, (*def_id, lifetime.ident.name, lifetime.ident.span))
79+
}),
80+
tcx.generics_of(def_id.to_def_id()),
81+
&mut predicates,
82+
);
83+
84+
return ty::GenericPredicates {
85+
parent: Some(tcx.parent(def_id.to_def_id())),
86+
predicates: tcx.arena.alloc_from_iter(predicates),
87+
};
88+
}
89+
90+
Some(ImplTraitInTraitData::Impl { fn_def_id }) => {
91+
let assoc_item = tcx.associated_item(def_id);
92+
let trait_assoc_predicates = tcx.predicates_of(assoc_item.trait_item_def_id.unwrap());
93+
94+
let impl_assoc_identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
95+
let impl_def_id = tcx.parent(fn_def_id);
96+
let impl_trait_ref_substs =
97+
tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder().substs;
98+
99+
let impl_assoc_substs =
100+
impl_assoc_identity_substs.rebase_onto(tcx, impl_def_id, impl_trait_ref_substs);
101+
102+
let impl_predicates = trait_assoc_predicates.instantiate_own(tcx, impl_assoc_substs);
103+
104+
return ty::GenericPredicates {
105+
parent: Some(impl_def_id),
106+
predicates: tcx.arena.alloc_from_iter(impl_predicates),
107+
};
108+
}
109+
110+
None => {}
111+
}
112+
65113
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
66114
let node = tcx.hir().get(hir_id);
67115

@@ -289,38 +337,22 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
289337
bug!("unexpected {opaque_ty_node:?}")
290338
};
291339
debug!(?lifetimes);
292-
for (arg, duplicate) in std::iter::zip(lifetimes, ast_generics.params) {
293-
let hir::GenericArg::Lifetime(arg) = arg else { bug!() };
294-
let orig_region = icx.astconv().ast_region_to_region(&arg, None);
295-
if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) {
296-
// Only early-bound regions can point to the original generic parameter.
297-
continue;
298-
}
299-
300-
let hir::GenericParamKind::Lifetime { .. } = duplicate.kind else { continue };
301-
let dup_def = duplicate.def_id.to_def_id();
302340

303-
let Some(dup_index) = generics.param_def_id_to_index(tcx, dup_def) else { bug!() };
341+
let lifetime_mapping = std::iter::zip(lifetimes, ast_generics.params)
342+
.map(|(arg, dup)| {
343+
let hir::GenericArg::Lifetime(arg) = arg else { bug!() };
344+
(**arg, dup)
345+
})
346+
.filter(|(_, dup)| matches!(dup.kind, hir::GenericParamKind::Lifetime { .. }))
347+
.map(|(lifetime, dup)| (lifetime, (dup.def_id, dup.name.ident().name, dup.span)));
304348

305-
let dup_region = ty::Region::new_early_bound(
306-
tcx,
307-
ty::EarlyBoundRegion {
308-
def_id: dup_def,
309-
index: dup_index,
310-
name: duplicate.name.ident().name,
311-
},
312-
);
313-
predicates.push((
314-
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_region, dup_region))
315-
.to_predicate(icx.tcx),
316-
duplicate.span,
317-
));
318-
predicates.push((
319-
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_region, orig_region))
320-
.to_predicate(icx.tcx),
321-
duplicate.span,
322-
));
323-
}
349+
compute_bidirectional_outlives_predicates(
350+
tcx,
351+
def_id,
352+
lifetime_mapping,
353+
generics,
354+
&mut predicates,
355+
);
324356
debug!(?predicates);
325357
}
326358

@@ -330,6 +362,46 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
330362
}
331363
}
332364

365+
/// Opaques have duplicated lifetimes and we need to compute bidirectional outlives predicates to
366+
/// enforce that these lifetimes stay in sync.
367+
fn compute_bidirectional_outlives_predicates<'tcx>(
368+
tcx: TyCtxt<'tcx>,
369+
item_def_id: LocalDefId,
370+
lifetime_mapping: impl Iterator<Item = (Lifetime, (LocalDefId, Symbol, Span))>,
371+
generics: &Generics,
372+
predicates: &mut Vec<(ty::Clause<'tcx>, Span)>,
373+
) {
374+
let icx = ItemCtxt::new(tcx, item_def_id);
375+
376+
for (arg, (dup_def, name, span)) in lifetime_mapping {
377+
let orig_region = icx.astconv().ast_region_to_region(&arg, None);
378+
if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) {
379+
// There is no late-bound lifetime to actually match up here, since the lifetime doesn't
380+
// show up in the opaque's parent's substs.
381+
continue;
382+
}
383+
384+
let Some(dup_index) = generics.param_def_id_to_index(icx.tcx, dup_def.to_def_id()) else { bug!() };
385+
386+
let dup_region = ty::Region::new_early_bound(
387+
tcx,
388+
ty::EarlyBoundRegion { def_id: dup_def.to_def_id(), index: dup_index, name },
389+
);
390+
391+
predicates.push((
392+
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_region, dup_region))
393+
.to_predicate(tcx),
394+
span,
395+
));
396+
397+
predicates.push((
398+
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_region, orig_region))
399+
.to_predicate(tcx),
400+
span,
401+
));
402+
}
403+
}
404+
333405
fn const_evaluatable_predicates_of(
334406
tcx: TyCtxt<'_>,
335407
def_id: LocalDefId,
@@ -668,7 +740,7 @@ pub(super) fn type_param_predicates(
668740
ItemKind::Fn(.., generics, _)
669741
| ItemKind::Impl(&hir::Impl { generics, .. })
670742
| ItemKind::TyAlias(_, generics)
671-
| ItemKind::OpaqueTy(OpaqueTy {
743+
| ItemKind::OpaqueTy(&OpaqueTy {
672744
generics,
673745
origin: hir::OpaqueTyOrigin::TyAlias { .. },
674746
..

‎compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
556556
});
557557
}
558558
}
559-
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
559+
hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
560560
origin: hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent),
561561
generics,
562562
..

‎compiler/rustc_hir_analysis/src/collect/type_of.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
435435
..
436436
}) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
437437
// Opaque types desugared from `impl Trait`.
438-
ItemKind::OpaqueTy(OpaqueTy {
438+
ItemKind::OpaqueTy(&OpaqueTy {
439439
origin:
440440
hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner),
441441
in_trait,

‎compiler/rustc_ty_utils/src/assoc.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,6 @@ fn associated_type_for_impl_trait_in_trait(
340340
}
341341
});
342342

343-
// There are no predicates for the synthesized associated type.
344-
trait_assoc_ty.explicit_predicates_of(ty::GenericPredicates {
345-
parent: Some(trait_def_id.to_def_id()),
346-
predicates: &[],
347-
});
348-
349343
// There are no inferred outlives for the synthesized associated type.
350344
trait_assoc_ty.inferred_outlives_of(&[]);
351345

@@ -424,12 +418,6 @@ fn associated_type_for_impl_trait_in_impl(
424418
}
425419
});
426420

427-
// There are no predicates for the synthesized associated type.
428-
impl_assoc_ty.explicit_predicates_of(ty::GenericPredicates {
429-
parent: Some(impl_local_def_id.to_def_id()),
430-
predicates: &[],
431-
});
432-
433421
// There are no inferred outlives for the synthesized associated type.
434422
impl_assoc_ty.inferred_outlives_of(&[]);
435423

‎compiler/rustc_ty_utils/src/ty.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
131131
if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. })
132132
| Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id)
133133
{
134-
predicates = tcx.predicates_of(fn_def_id).instantiate_identity(tcx).predicates;
134+
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): Should not need to add the predicates
135+
// from the parent fn to our assumptions
136+
predicates.extend(tcx.predicates_of(fn_def_id).instantiate_identity(tcx).predicates);
135137
}
136138

137139
// Finally, we have to normalize the bounds in the environment, in

‎tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// check-pass
22
// edition: 2021
3+
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
4+
// revisions: current next
35

46
#![feature(async_fn_in_trait)]
57
#![allow(incomplete_features)]

‎tests/ui/async-await/in-trait/async-lifetimes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// check-pass
22
// edition: 2021
3+
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
4+
// revisions: current next
35

46
#![feature(async_fn_in_trait)]
57
#![allow(incomplete_features)]

0 commit comments

Comments
 (0)
Please sign in to comment.