Auto merge of #102164 - compiler-errors:rpitit-foreign, r=TaKO8Ki
Serialize return-position `impl Trait` in trait hidden values in foreign libraries Fixes #101630
This commit is contained in:
commit
b3aa4997d4
6 changed files with 70 additions and 0 deletions
|
@ -223,6 +223,15 @@ provide! { tcx, def_id, other, cdata,
|
||||||
fn_arg_names => { table }
|
fn_arg_names => { table }
|
||||||
generator_kind => { table }
|
generator_kind => { table }
|
||||||
trait_def => { 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) }
|
visibility => { cdata.get_visibility(def_id.index) }
|
||||||
adt_def => { cdata.get_adt_def(def_id.index, tcx) }
|
adt_def => { cdata.get_adt_def(def_id.index, tcx) }
|
||||||
|
|
|
@ -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> {
|
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
fn encode_attrs(&mut self, def_id: LocalDefId) {
|
fn encode_attrs(&mut self, def_id: LocalDefId) {
|
||||||
let mut attrs = self
|
let mut attrs = self
|
||||||
|
@ -1128,6 +1156,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
if let DefKind::Trait | DefKind::TraitAlias = def_kind {
|
if let DefKind::Trait | DefKind::TraitAlias = def_kind {
|
||||||
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
|
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(());
|
let inherent_impls = tcx.crate_inherent_impls(());
|
||||||
for (def_id, implementations) in inherent_impls.inherent_impls.iter() {
|
for (def_id, implementations) in inherent_impls.inherent_impls.iter() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::creader::CrateMetadataRef;
|
use crate::creader::CrateMetadataRef;
|
||||||
use decoder::Metadata;
|
use decoder::Metadata;
|
||||||
use def_path_hash_map::DefPathHashMapRef;
|
use def_path_hash_map::DefPathHashMapRef;
|
||||||
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use table::TableBuilder;
|
use table::TableBuilder;
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
|
@ -399,6 +400,8 @@ define_tables! {
|
||||||
macro_definition: Table<DefIndex, LazyValue<ast::MacArgs>>,
|
macro_definition: Table<DefIndex, LazyValue<ast::MacArgs>>,
|
||||||
proc_macro: Table<DefIndex, MacroKind>,
|
proc_macro: Table<DefIndex, MacroKind>,
|
||||||
module_reexports: Table<DefIndex, LazyArray<ModChild>>,
|
module_reexports: Table<DefIndex, LazyArray<ModChild>>,
|
||||||
|
|
||||||
|
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TyEncodable, TyDecodable)]
|
#[derive(TyEncodable, TyDecodable)]
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir::def_id::{DefId, DefIndex};
|
use rustc_hir::def_id::{DefId, DefIndex};
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
|
|
||||||
|
@ -29,6 +30,10 @@ impl<I: Idx + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for IndexVe
|
||||||
type Value<'tcx> = IndexVec<I, T::Value<'tcx>>;
|
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> {
|
impl<T: ParameterizedOverTcx> ParameterizedOverTcx for ty::Binder<'static, T> {
|
||||||
type Value<'tcx> = ty::Binder<'tcx, T::Value<'tcx>>;
|
type Value<'tcx> = ty::Binder<'tcx, T::Value<'tcx>>;
|
||||||
}
|
}
|
||||||
|
|
11
src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs
Normal file
11
src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs
Normal file
|
@ -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
src/test/ui/impl-trait/in-trait/foreign.rs
Normal file
9
src/test/ui/impl-trait/in-trait/foreign.rs
Normal file
|
@ -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();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue