Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialize return-position impl Trait in trait hidden values in foreign libraries #102164

Merged
merged 1 commit into from
Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ provide! { tcx, def_id, other, cdata,
fn_arg_names => { table }
generator_kind => { table }
trait_def => { table }
collect_trait_impl_trait_tys => {
Ok(cdata
.root
.tables
.trait_impl_trait_tys
.get(cdata, def_id.index)
.map(|lazy| lazy.decode((cdata, tcx)))
.process_decoded(tcx, || panic!("{:?} does not have trait_impl_trait_tys", def_id)))
}

visibility => { cdata.get_visibility(def_id.index) }
adt_def => { cdata.get_adt_def(def_id.index, tcx) }
Expand Down
33 changes: 33 additions & 0 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,34 @@ fn should_encode_const(def_kind: DefKind) -> bool {
}
}

fn should_encode_trait_impl_trait_tys<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
if tcx.def_kind(def_id) != DefKind::AssocFn {
return false;
}

let Some(item) = tcx.opt_associated_item(def_id) else { return false; };
if item.container != ty::AssocItemContainer::ImplContainer {
return false;
}

let Some(trait_item_def_id) = item.trait_item_def_id else { return false; };

// FIXME(RPITIT): This does a somewhat manual walk through the signature
// of the trait fn to look for any RPITITs, but that's kinda doing a lot
// of work. We can probably remove this when we refactor RPITITs to be
// associated types.
tcx.fn_sig(trait_item_def_id).skip_binder().output().walk().any(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(data) = ty.kind()
&& tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder
{
true
} else {
false
}
})
}

impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_attrs(&mut self, def_id: LocalDefId) {
let mut attrs = self
Expand Down Expand Up @@ -1128,6 +1156,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
if let DefKind::Trait | DefKind::TraitAlias = def_kind {
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
}
if should_encode_trait_impl_trait_tys(tcx, def_id)
&& let Ok(table) = self.tcx.collect_trait_impl_trait_tys(def_id)
{
record!(self.tables.trait_impl_trait_tys[def_id] <- table);
}
}
let inherent_impls = tcx.crate_inherent_impls(());
for (def_id, implementations) in inherent_impls.inherent_impls.iter() {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::creader::CrateMetadataRef;
use decoder::Metadata;
use def_path_hash_map::DefPathHashMapRef;
use rustc_data_structures::fx::FxHashMap;
use table::TableBuilder;

use rustc_ast as ast;
Expand Down Expand Up @@ -399,6 +400,8 @@ define_tables! {
macro_definition: Table<DefIndex, LazyValue<ast::MacArgs>>,
proc_macro: Table<DefIndex, MacroKind>,
module_reexports: Table<DefIndex, LazyArray<ModChild>>,

trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>,
}

#[derive(TyEncodable, TyDecodable)]
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/ty/parameterized.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::{DefId, DefIndex};
use rustc_index::vec::{Idx, IndexVec};

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

impl<I: 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for FxHashMap<I, T> {
type Value<'tcx> = FxHashMap<I, T::Value<'tcx>>;
}

impl<T: ParameterizedOverTcx> ParameterizedOverTcx for ty::Binder<'static, T> {
type Value<'tcx> = ty::Binder<'tcx, T::Value<'tcx>>;
}
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![feature(return_position_impl_trait_in_trait)]

pub trait Foo {
fn bar() -> impl Sized;
}

pub struct Foreign;

impl Foo for Foreign {
fn bar() {}
}
9 changes: 9 additions & 0 deletions src/test/ui/impl-trait/in-trait/foreign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// check-pass
// aux-build: rpitit.rs

extern crate rpitit;

fn main() {
// Witness an RPITIT from another crate
let () = <rpitit::Foreign as rpitit::Foo>::bar();
}