Skip to content

Commit 50d2109

Browse files
Implement assumed_wf_types for RPITITs' implementations
1 parent 349a237 commit 50d2109

File tree

6 files changed

+102
-33
lines changed

6 files changed

+102
-33
lines changed

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ provide! { tcx, def_id, other, cdata,
246246
debug_assert_eq!(tcx.def_kind(def_id), DefKind::OpaqueTy);
247247
cdata.root.tables.is_type_alias_impl_trait.get(cdata, def_id.index)
248248
}
249+
assumed_wf_types_for_rpitit => { table }
249250
collect_return_position_impl_trait_in_trait_tys => {
250251
Ok(cdata
251252
.root

compiler/rustc_metadata/src/rmeta/encoder.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1560,6 +1560,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
15601560
}
15611561
if let Some(rpitit_info) = item.opt_rpitit_info {
15621562
record!(self.tables.opt_rpitit_info[def_id] <- rpitit_info);
1563+
if matches!(rpitit_info, ty::ImplTraitInTraitData::Trait { .. }) {
1564+
record_array!(
1565+
self.tables.assumed_wf_types_for_rpitit[def_id]
1566+
<- self.tcx.assumed_wf_types_for_rpitit(def_id)
1567+
);
1568+
}
15631569
}
15641570
}
15651571

compiler/rustc_metadata/src/rmeta/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ define_tables! {
457457
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, ty::EarlyBinder<Ty<'static>>>>>,
458458
doc_link_resolutions: Table<DefIndex, LazyValue<DocLinkResMap>>,
459459
doc_link_traits_in_scope: Table<DefIndex, LazyArray<DefId>>,
460+
assumed_wf_types_for_rpitit: Table<DefIndex, LazyArray<(Ty<'static>, Span)>>,
460461
}
461462

462463
#[derive(TyEncodable, TyDecodable)]

compiler/rustc_middle/src/query/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,13 @@ rustc_queries! {
885885
desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) }
886886
}
887887

888+
/// We need to store the assumed_wf_types for an RPITIT so that impls of foreign
889+
/// traits with return-position impl trait in traits can inherit the right wf types.
890+
query assumed_wf_types_for_rpitit(key: DefId) -> &'tcx [(Ty<'tcx>, Span)] {
891+
desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) }
892+
separate_provide_extern
893+
}
894+
888895
/// Computes the signature of the function.
889896
query fn_sig(key: DefId) -> ty::EarlyBinder<ty::PolyFnSig<'tcx>> {
890897
desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) }

compiler/rustc_ty_utils/src/implied_bounds.rs

+58-33
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ use rustc_span::Span;
99
use std::iter;
1010

1111
pub fn provide(providers: &mut Providers) {
12-
*providers = Providers { assumed_wf_types, ..*providers };
12+
*providers = Providers {
13+
assumed_wf_types,
14+
assumed_wf_types_for_rpitit: |tcx, def_id| tcx.assumed_wf_types(def_id),
15+
..*providers
16+
};
1317
}
1418

1519
fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'tcx>, Span)] {
@@ -44,41 +48,62 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
4448
let mut impl_spans = impl_spans(tcx, def_id);
4549
tcx.arena.alloc_from_iter(tys.into_iter().map(|ty| (ty, impl_spans.next().unwrap())))
4650
}
47-
DefKind::AssocTy if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) = tcx.opt_rpitit_info(def_id.to_def_id()) => {
48-
let hir::OpaqueTy { lifetime_mapping, .. } =
49-
*tcx.hir().expect_item(opaque_def_id.expect_local()).expect_opaque_ty();
50-
let mut mapping = FxHashMap::default();
51-
let generics = tcx.generics_of(def_id);
52-
for &(lifetime, new_early_bound_def_id) in lifetime_mapping {
53-
if let Some(rbv::ResolvedArg::LateBound(_, _, def_id)) =
54-
tcx.named_bound_var(lifetime.hir_id)
51+
DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => match data {
52+
ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id } => {
53+
let hir::OpaqueTy { lifetime_mapping, .. } =
54+
*tcx.hir().expect_item(opaque_def_id.expect_local()).expect_opaque_ty();
55+
let mut mapping = FxHashMap::default();
56+
let generics = tcx.generics_of(def_id);
57+
for &(lifetime, new_early_bound_def_id) in
58+
lifetime_mapping.expect("expected lifetime mapping for RPITIT")
5559
{
56-
let name = tcx.hir().name(lifetime.hir_id);
57-
let index = generics
58-
.param_def_id_to_index(tcx, new_early_bound_def_id.to_def_id())
59-
.unwrap();
60-
mapping.insert(
61-
ty::Region::new_free(
62-
tcx,
63-
fn_def_id,
64-
ty::BoundRegionKind::BrNamed(def_id, name),
65-
),
66-
ty::Region::new_early_bound(
67-
tcx,
68-
ty::EarlyBoundRegion {
69-
def_id: new_early_bound_def_id.to_def_id(),
70-
index,
71-
name,
72-
},
73-
),
74-
);
60+
if let Some(rbv::ResolvedArg::LateBound(_, _, def_id)) =
61+
tcx.named_bound_var(lifetime.hir_id)
62+
{
63+
let name = tcx.hir().name(lifetime.hir_id);
64+
let index = generics
65+
.param_def_id_to_index(tcx, new_early_bound_def_id.to_def_id())
66+
.unwrap();
67+
mapping.insert(
68+
ty::Region::new_free(
69+
tcx,
70+
fn_def_id,
71+
ty::BoundRegionKind::BrNamed(def_id, name),
72+
),
73+
ty::Region::new_early_bound(
74+
tcx,
75+
ty::EarlyBoundRegion {
76+
def_id: new_early_bound_def_id.to_def_id(),
77+
index,
78+
name,
79+
},
80+
),
81+
);
82+
}
7583
}
84+
let a = tcx.fold_regions(
85+
tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(),
86+
|re, _| {
87+
if let Some(re) = mapping.get(&re) { *re } else { re }
88+
},
89+
);
90+
tcx.arena.alloc_from_iter(a)
7691
}
77-
let a = tcx.fold_regions(tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(), |re, _| {
78-
if let Some(re) = mapping.get(&re) { *re } else { re }
79-
});
80-
tcx.arena.alloc_from_iter(a)
81-
}
92+
ty::ImplTraitInTraitData::Impl { .. } => {
93+
let impl_def_id = tcx.local_parent(def_id);
94+
let rpitit_def_id = tcx.associated_item(def_id).trait_item_def_id.unwrap();
95+
let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto(
96+
tcx,
97+
impl_def_id.to_def_id(),
98+
tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args,
99+
);
100+
tcx.arena.alloc_from_iter(
101+
ty::EarlyBinder::bind(tcx.assumed_wf_types_for_rpitit(rpitit_def_id))
102+
.iter_instantiated_copied(tcx, args)
103+
.chain(tcx.assumed_wf_types(impl_def_id).into_iter().copied()),
104+
)
105+
}
106+
},
82107
DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
83108
DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) {
84109
DefKind::TyAlias => ty::List::empty(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// check-pass
2+
// edition: 2021
3+
// issue: 113796
4+
5+
#![feature(async_fn_in_trait)]
6+
7+
trait AsyncLendingIterator {
8+
type Item<'a>
9+
where
10+
Self: 'a;
11+
12+
async fn next(&mut self) -> Option<Self::Item<'_>>;
13+
}
14+
15+
struct Lend<I>(I);
16+
impl<I> AsyncLendingIterator for Lend<I> {
17+
type Item<'a> = &'a I
18+
where
19+
Self: 'a;
20+
21+
// Checking that the synthetic `<Self as AsyncLendingIterator>::next()` GAT
22+
// is well-formed requires being able to assume the WF types of `next`.
23+
24+
async fn next(&mut self) -> Option<Self::Item<'_>> {
25+
todo!()
26+
}
27+
}
28+
29+
fn main() {}

0 commit comments

Comments
 (0)