Skip to content

Commit f32f7e2

Browse files
committed
EII collection queries
EII collection queries
1 parent 9156bef commit f32f7e2

File tree

14 files changed

+320
-2
lines changed

14 files changed

+320
-2
lines changed

compiler/rustc_interface/src/passes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,9 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
10531053
parallel!(
10541054
{
10551055
sess.time("looking_for_entry_point", || tcx.ensure_ok().entry_fn(()));
1056+
sess.time("check_externally_implementable_items", || {
1057+
tcx.ensure_ok().check_externally_implementable_items(())
1058+
});
10561059

10571060
sess.time("looking_for_derive_registrar", || {
10581061
tcx.ensure_ok().proc_macro_decls_static(())

compiler/rustc_metadata/src/eii.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use rustc_data_structures::fx::FxIndexMap;
2+
use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl};
3+
use rustc_hir::def_id::DefId;
4+
use rustc_hir::find_attr;
5+
use rustc_middle::query::LocalCrate;
6+
use rustc_middle::ty::TyCtxt;
7+
8+
// basically the map below but flattened out
9+
pub(crate) type EiiMapEncodedKeyValue = (DefId, (EiiDecl, Vec<(DefId, EiiImpl)>));
10+
11+
pub(crate) type EiiMap = FxIndexMap<
12+
DefId, // the defid of the macro that declared the eii
13+
(
14+
// the corresponding declaration
15+
EiiDecl,
16+
// all the given implementations, indexed by defid.
17+
// We expect there to be only one, but collect them all to give errors if there are more
18+
// (or if there are none) in the final crate we build.
19+
FxIndexMap<DefId, EiiImpl>,
20+
),
21+
>;
22+
23+
pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap {
24+
let mut eiis = EiiMap::default();
25+
26+
// iterate over all items in the current crate
27+
// FIXME(speed up)
28+
for id in tcx.hir_crate_items(()).definitions() {
29+
for i in
30+
find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiImpls(e) => e).into_iter().flatten()
31+
{
32+
eiis.entry(i.eii_macro)
33+
.or_insert_with(|| {
34+
// find the decl for this one if it wasn't in yet (maybe it's from the local crate? not very useful but not illegal)
35+
(find_attr!(tcx.get_all_attrs(i.eii_macro), AttributeKind::EiiExternTarget(d) => *d).unwrap(), Default::default())
36+
}).1.insert(id.into(), *i);
37+
}
38+
39+
// if we find a new declaration, add it to the list without a known implementation
40+
if let Some(decl) =
41+
find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiExternTarget(d) => *d)
42+
{
43+
eiis.entry(id.into()).or_insert((decl, Default::default()));
44+
}
45+
}
46+
47+
eiis
48+
}

compiler/rustc_metadata/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
pub use rmeta::provide;
1919

2020
mod dependency_format;
21+
mod eii;
2122
mod foreign_modules;
2223
mod native_libs;
2324
mod rmeta;

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use rustc_span::{
3838
use tracing::debug;
3939

4040
use crate::creader::CStore;
41+
use crate::eii::EiiMapEncodedKeyValue;
4142
use crate::rmeta::table::IsDefault;
4243
use crate::rmeta::*;
4344

@@ -1486,6 +1487,13 @@ impl<'a> CrateMetadataRef<'a> {
14861487
)
14871488
}
14881489

1490+
fn get_externally_implementable_items(
1491+
self,
1492+
sess: &'a Session,
1493+
) -> impl Iterator<Item = EiiMapEncodedKeyValue> {
1494+
self.root.externally_implementable_items.decode((self, sess))
1495+
}
1496+
14891497
fn get_missing_lang_items<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] {
14901498
tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self))
14911499
}

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use super::{Decodable, DecodeContext, DecodeIterator};
2424
use crate::creader::{CStore, LoadedMacro};
2525
use crate::rmeta::AttrFlags;
2626
use crate::rmeta::table::IsDefault;
27-
use crate::{foreign_modules, native_libs};
27+
use crate::{eii, foreign_modules, native_libs};
2828

2929
trait ProcessQueryValue<'tcx, T> {
3030
fn process_decoded(self, _tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> T;
@@ -328,9 +328,22 @@ provide! { tcx, def_id, other, cdata,
328328
is_private_dep => { cdata.private_dep }
329329
is_panic_runtime => { cdata.root.panic_runtime }
330330
is_compiler_builtins => { cdata.root.compiler_builtins }
331+
332+
// FIXME: to be replaced with externally_implementable_items below
331333
has_global_allocator => { cdata.root.has_global_allocator }
334+
// FIXME: to be replaced with externally_implementable_items below
332335
has_alloc_error_handler => { cdata.root.has_alloc_error_handler }
336+
// FIXME: to be replaced with externally_implementable_items below
333337
has_panic_handler => { cdata.root.has_panic_handler }
338+
339+
externally_implementable_items => {
340+
cdata.get_externally_implementable_items(tcx.sess)
341+
.map(|(decl_did, (decl, impls))| (
342+
decl_did,
343+
(decl, impls.into_iter().collect())
344+
)).collect()
345+
}
346+
334347
is_profiler_runtime => { cdata.root.profiler_runtime }
335348
required_panic_strategy => { cdata.root.required_panic_strategy }
336349
panic_in_drop_strategy => { cdata.root.panic_in_drop_strategy }
@@ -427,6 +440,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
427440
},
428441
native_libraries: native_libs::collect,
429442
foreign_modules: foreign_modules::collect,
443+
externally_implementable_items: eii::collect,
430444

431445
// Returns a map from a sufficiently visible external item (i.e., an
432446
// external item that is visible from at least one local module) to a

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use rustc_span::{
3535
};
3636
use tracing::{debug, instrument, trace};
3737

38+
use crate::eii::EiiMapEncodedKeyValue;
3839
use crate::errors::{FailCreateFileEncoder, FailWriteFile};
3940
use crate::rmeta::*;
4041

@@ -620,6 +621,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
620621
// We have already encoded some things. Get their combined size from the current position.
621622
stats.push(("preamble", self.position()));
622623

624+
let externally_implementable_items = stat!("externally-implementable-items", || self
625+
.encode_externally_implementable_items());
626+
623627
let (crate_deps, dylib_dependency_formats) =
624628
stat!("dep", || (self.encode_crate_deps(), self.encode_dylib_dependency_formats()));
625629

@@ -738,6 +742,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
738742
attrs,
739743
sym::default_lib_allocator,
740744
),
745+
externally_implementable_items,
741746
proc_macro_data,
742747
debugger_visualizers,
743748
compiler_builtins: ast::attr::contains_name(attrs, sym::compiler_builtins),
@@ -1628,6 +1633,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
16281633
}
16291634
}
16301635

1636+
fn encode_externally_implementable_items(&mut self) -> LazyArray<EiiMapEncodedKeyValue> {
1637+
empty_proc_macro!(self);
1638+
let externally_implementable_items = self.tcx.externally_implementable_items(LOCAL_CRATE);
1639+
1640+
self.lazy_array(externally_implementable_items.iter().map(|(decl_did, (decl, impls))| {
1641+
(*decl_did, (decl.clone(), impls.iter().map(|(impl_did, i)| (*impl_did, *i)).collect()))
1642+
}))
1643+
}
1644+
16311645
#[instrument(level = "trace", skip(self))]
16321646
fn encode_info_for_adt(&mut self, local_def_id: LocalDefId) {
16331647
let def_id = local_def_id.to_def_id();

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ use table::TableBuilder;
4242
use {rustc_ast as ast, rustc_hir as hir};
4343

4444
use crate::creader::CrateMetadataRef;
45+
use crate::eii::EiiMapEncodedKeyValue;
4546

4647
mod decoder;
4748
mod def_path_hash_map;
@@ -248,6 +249,7 @@ pub(crate) struct CrateRoot {
248249
has_alloc_error_handler: bool,
249250
has_panic_handler: bool,
250251
has_default_lib_allocator: bool,
252+
externally_implementable_items: LazyArray<EiiMapEncodedKeyValue>,
251253

252254
crate_deps: LazyArray<CrateDep>,
253255
dylib_dependency_formats: LazyArray<Option<LinkagePreference>>,

compiler/rustc_metadata/src/rmeta/parameterized.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ trivially_parameterized_over_tcx! {
8787
rustc_hir::Safety,
8888
rustc_hir::Stability,
8989
rustc_hir::attrs::Deprecation,
90+
rustc_hir::attrs::EiiDecl,
91+
rustc_hir::attrs::EiiImpl,
9092
rustc_hir::attrs::StrippedCfgItem<rustc_hir::def_id::DefIndex>,
9193
rustc_hir::def::DefKind,
9294
rustc_hir::def::DocLinkResMap,

compiler/rustc_middle/src/query/erase.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ trivial! {
279279
rustc_ast::expand::allocator::AllocatorKind,
280280
rustc_hir::DefaultBodyStability,
281281
rustc_hir::attrs::Deprecation,
282+
rustc_hir::attrs::EiiDecl,
283+
rustc_hir::attrs::EiiImpl,
282284
rustc_data_structures::svh::Svh,
283285
rustc_errors::ErrorGuaranteed,
284286
rustc_hir::Constness,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use rustc_data_structures::steal::Steal;
7777
use rustc_data_structures::svh::Svh;
7878
use rustc_data_structures::unord::{UnordMap, UnordSet};
7979
use rustc_errors::ErrorGuaranteed;
80-
use rustc_hir::attrs::StrippedCfgItem;
80+
use rustc_hir::attrs::{EiiDecl, EiiImpl, StrippedCfgItem};
8181
use rustc_hir::def::{DefKind, DocLinkResMap};
8282
use rustc_hir::def_id::{
8383
CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId,
@@ -2728,6 +2728,17 @@ rustc_queries! {
27282728
desc { |tcx| "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) }
27292729
feedable
27302730
}
2731+
2732+
query check_externally_implementable_items(_: ()) {
2733+
desc { "check externally implementable items" }
2734+
}
2735+
2736+
/// Returns a list of all `externally implementable items` crate.
2737+
query externally_implementable_items(_: CrateNum) -> &'tcx FxIndexMap<DefId, (EiiDecl, FxIndexMap<DefId, EiiImpl>)> {
2738+
arena_cache
2739+
desc { "looking up the externally implementable items of a crate" }
2740+
separate_provide_extern
2741+
}
27312742
}
27322743

27332744
rustc_with_all_queries! { define_callbacks! }

0 commit comments

Comments
 (0)