Skip to content

Commit 1753196

Browse files
committed
EII collection queries
EII collection queries
1 parent 2e0174e commit 1753196

File tree

14 files changed

+331
-17
lines changed

14 files changed

+331
-17
lines changed

compiler/rustc_interface/src/passes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,9 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
10591059
parallel!(
10601060
{
10611061
sess.time("looking_for_entry_point", || tcx.ensure_ok().entry_fn(()));
1062+
sess.time("check_externally_implementable_items", || {
1063+
tcx.ensure_ok().check_externally_implementable_items(())
1064+
});
10621065

10631066
sess.time("looking_for_derive_registrar", || {
10641067
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;
@@ -329,9 +329,22 @@ provide! { tcx, def_id, other, cdata,
329329
is_private_dep => { cdata.private_dep }
330330
is_panic_runtime => { cdata.root.panic_runtime }
331331
is_compiler_builtins => { cdata.root.compiler_builtins }
332+
333+
// FIXME: to be replaced with externally_implementable_items below
332334
has_global_allocator => { cdata.root.has_global_allocator }
335+
// FIXME: to be replaced with externally_implementable_items below
333336
has_alloc_error_handler => { cdata.root.has_alloc_error_handler }
337+
// FIXME: to be replaced with externally_implementable_items below
334338
has_panic_handler => { cdata.root.has_panic_handler }
339+
340+
externally_implementable_items => {
341+
cdata.get_externally_implementable_items(tcx.sess)
342+
.map(|(decl_did, (decl, impls))| (
343+
decl_did,
344+
(decl, impls.into_iter().collect())
345+
)).collect()
346+
}
347+
335348
is_profiler_runtime => { cdata.root.profiler_runtime }
336349
required_panic_strategy => { cdata.root.required_panic_strategy }
337350
panic_in_drop_strategy => { cdata.root.panic_in_drop_strategy }
@@ -428,6 +441,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
428441
},
429442
native_libraries: native_libs::collect,
430443
foreign_modules: foreign_modules::collect,
444+
externally_implementable_items: eii::collect,
431445

432446
// Returns a map from a sufficiently visible external item (i.e., an
433447
// 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
@@ -44,6 +44,7 @@ use table::TableBuilder;
4444
use {rustc_ast as ast, rustc_hir as hir};
4545

4646
use crate::creader::CrateMetadataRef;
47+
use crate::eii::EiiMapEncodedKeyValue;
4748

4849
mod decoder;
4950
mod def_path_hash_map;
@@ -250,6 +251,7 @@ pub(crate) struct CrateRoot {
250251
has_alloc_error_handler: bool,
251252
has_panic_handler: bool,
252253
has_default_lib_allocator: bool,
254+
externally_implementable_items: LazyArray<EiiMapEncodedKeyValue>,
253255

254256
crate_deps: LazyArray<CrateDep>,
255257
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
@@ -296,6 +296,8 @@ trivial! {
296296
rustc_ast::expand::allocator::AllocatorKind,
297297
rustc_hir::DefaultBodyStability,
298298
rustc_hir::attrs::Deprecation,
299+
rustc_hir::attrs::EiiDecl,
300+
rustc_hir::attrs::EiiImpl,
299301
rustc_data_structures::svh::Svh,
300302
rustc_errors::ErrorGuaranteed,
301303
rustc_hir::Constness,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ use rustc_data_structures::steal::Steal;
7676
use rustc_data_structures::svh::Svh;
7777
use rustc_data_structures::unord::{UnordMap, UnordSet};
7878
use rustc_errors::ErrorGuaranteed;
79-
use rustc_hir::attrs::StrippedCfgItem;
79+
use rustc_hir::attrs::{EiiDecl, EiiImpl, StrippedCfgItem};
8080
use rustc_hir::def::{DefKind, DocLinkResMap};
8181
use rustc_hir::def_id::{
8282
CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId,
@@ -2740,6 +2740,17 @@ rustc_queries! {
27402740
desc { |tcx| "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) }
27412741
feedable
27422742
}
2743+
2744+
query check_externally_implementable_items(_: ()) {
2745+
desc { "check externally implementable items" }
2746+
}
2747+
2748+
/// Returns a list of all `externally implementable items` crate.
2749+
query externally_implementable_items(_: CrateNum) -> &'tcx FxIndexMap<DefId, (EiiDecl, FxIndexMap<DefId, EiiImpl>)> {
2750+
arena_cache
2751+
desc { "looking up the externally implementable items of a crate" }
2752+
separate_provide_extern
2753+
}
27432754
}
27442755

27452756
rustc_with_all_queries! { define_callbacks! }

0 commit comments

Comments
 (0)