Skip to content

Commit b3aa499

Browse files
committed
Auto merge of #102164 - compiler-errors:rpitit-foreign, r=TaKO8Ki
Serialize return-position `impl Trait` in trait hidden values in foreign libraries Fixes #101630
2 parents d45feb3 + 2fa31d3 commit b3aa499

File tree

6 files changed

+70
-0
lines changed

6 files changed

+70
-0
lines changed

Diff for: compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+9
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ provide! { tcx, def_id, other, cdata,
223223
fn_arg_names => { table }
224224
generator_kind => { table }
225225
trait_def => { table }
226+
collect_trait_impl_trait_tys => {
227+
Ok(cdata
228+
.root
229+
.tables
230+
.trait_impl_trait_tys
231+
.get(cdata, def_id.index)
232+
.map(|lazy| lazy.decode((cdata, tcx)))
233+
.process_decoded(tcx, || panic!("{:?} does not have trait_impl_trait_tys", def_id)))
234+
}
226235

227236
visibility => { cdata.get_visibility(def_id.index) }
228237
adt_def => { cdata.get_adt_def(def_id.index, tcx) }

Diff for: compiler/rustc_metadata/src/rmeta/encoder.rs

+33
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,34 @@ fn should_encode_const(def_kind: DefKind) -> bool {
10591059
}
10601060
}
10611061

1062+
fn should_encode_trait_impl_trait_tys<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
1063+
if tcx.def_kind(def_id) != DefKind::AssocFn {
1064+
return false;
1065+
}
1066+
1067+
let Some(item) = tcx.opt_associated_item(def_id) else { return false; };
1068+
if item.container != ty::AssocItemContainer::ImplContainer {
1069+
return false;
1070+
}
1071+
1072+
let Some(trait_item_def_id) = item.trait_item_def_id else { return false; };
1073+
1074+
// FIXME(RPITIT): This does a somewhat manual walk through the signature
1075+
// of the trait fn to look for any RPITITs, but that's kinda doing a lot
1076+
// of work. We can probably remove this when we refactor RPITITs to be
1077+
// associated types.
1078+
tcx.fn_sig(trait_item_def_id).skip_binder().output().walk().any(|arg| {
1079+
if let ty::GenericArgKind::Type(ty) = arg.unpack()
1080+
&& let ty::Projection(data) = ty.kind()
1081+
&& tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder
1082+
{
1083+
true
1084+
} else {
1085+
false
1086+
}
1087+
})
1088+
}
1089+
10621090
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
10631091
fn encode_attrs(&mut self, def_id: LocalDefId) {
10641092
let mut attrs = self
@@ -1128,6 +1156,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
11281156
if let DefKind::Trait | DefKind::TraitAlias = def_kind {
11291157
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
11301158
}
1159+
if should_encode_trait_impl_trait_tys(tcx, def_id)
1160+
&& let Ok(table) = self.tcx.collect_trait_impl_trait_tys(def_id)
1161+
{
1162+
record!(self.tables.trait_impl_trait_tys[def_id] <- table);
1163+
}
11311164
}
11321165
let inherent_impls = tcx.crate_inherent_impls(());
11331166
for (def_id, implementations) in inherent_impls.inherent_impls.iter() {

Diff for: compiler/rustc_metadata/src/rmeta/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::creader::CrateMetadataRef;
22
use decoder::Metadata;
33
use def_path_hash_map::DefPathHashMapRef;
4+
use rustc_data_structures::fx::FxHashMap;
45
use table::TableBuilder;
56

67
use rustc_ast as ast;
@@ -399,6 +400,8 @@ define_tables! {
399400
macro_definition: Table<DefIndex, LazyValue<ast::MacArgs>>,
400401
proc_macro: Table<DefIndex, MacroKind>,
401402
module_reexports: Table<DefIndex, LazyArray<ModChild>>,
403+
404+
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>,
402405
}
403406

404407
#[derive(TyEncodable, TyDecodable)]

Diff for: compiler/rustc_middle/src/ty/parameterized.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_data_structures::fx::FxHashMap;
12
use rustc_hir::def_id::{DefId, DefIndex};
23
use rustc_index::vec::{Idx, IndexVec};
34

@@ -29,6 +30,10 @@ impl<I: Idx + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for IndexVe
2930
type Value<'tcx> = IndexVec<I, T::Value<'tcx>>;
3031
}
3132

33+
impl<I: 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for FxHashMap<I, T> {
34+
type Value<'tcx> = FxHashMap<I, T::Value<'tcx>>;
35+
}
36+
3237
impl<T: ParameterizedOverTcx> ParameterizedOverTcx for ty::Binder<'static, T> {
3338
type Value<'tcx> = ty::Binder<'tcx, T::Value<'tcx>>;
3439
}

Diff for: src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(return_position_impl_trait_in_trait)]
2+
3+
pub trait Foo {
4+
fn bar() -> impl Sized;
5+
}
6+
7+
pub struct Foreign;
8+
9+
impl Foo for Foreign {
10+
fn bar() {}
11+
}

Diff for: src/test/ui/impl-trait/in-trait/foreign.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// check-pass
2+
// aux-build: rpitit.rs
3+
4+
extern crate rpitit;
5+
6+
fn main() {
7+
// Witness an RPITIT from another crate
8+
let () = <rpitit::Foreign as rpitit::Foo>::bar();
9+
}

0 commit comments

Comments
 (0)