Skip to content

Commit dbb6b1a

Browse files
authored
Rollup merge of #113754 - cjgillot:simplify-foreign, r=petrochenkov
Simplify native_libs query Drive-by cleanup I saw while implementing #113734
2 parents c1d6d32 + 09743b9 commit dbb6b1a

File tree

7 files changed

+54
-57
lines changed

7 files changed

+54
-57
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
1+
use rustc_data_structures::fx::FxIndexMap;
12
use rustc_hir as hir;
23
use rustc_hir::def::DefKind;
4+
use rustc_hir::def_id::DefId;
5+
use rustc_middle::query::LocalCrate;
36
use rustc_middle::ty::TyCtxt;
47
use rustc_session::cstore::ForeignModule;
58

6-
pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<ForeignModule> {
7-
let mut modules = Vec::new();
9+
pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> FxIndexMap<DefId, ForeignModule> {
10+
let mut modules = FxIndexMap::default();
11+
12+
// We need to collect all the `ForeignMod`, even if they are empty.
813
for id in tcx.hir().items() {
914
if !matches!(tcx.def_kind(id.owner_id), DefKind::ForeignMod) {
1015
continue;
1116
}
17+
18+
let def_id = id.owner_id.to_def_id();
1219
let item = tcx.hir().item(id);
13-
if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
20+
21+
if let hir::ItemKind::ForeignMod { abi, items } = item.kind {
1422
let foreign_items = items.iter().map(|it| it.id.owner_id.to_def_id()).collect();
15-
modules.push(ForeignModule { foreign_items, def_id: id.owner_id.to_def_id() });
23+
modules.insert(def_id, ForeignModule { def_id, abi, foreign_items });
1624
}
1725
}
26+
1827
modules
1928
}

compiler/rustc_metadata/src/native_libs.rs

+34-46
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
use rustc_ast::{NestedMetaItem, CRATE_NODE_ID};
22
use rustc_attr as attr;
33
use rustc_data_structures::fx::FxHashSet;
4-
use rustc_hir as hir;
5-
use rustc_hir::def::DefKind;
4+
use rustc_middle::query::LocalCrate;
65
use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
76
use rustc_session::config::CrateType;
8-
use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib, PeImportNameType};
7+
use rustc_session::cstore::{
8+
DllCallingConvention, DllImport, ForeignModule, NativeLib, PeImportNameType,
9+
};
910
use rustc_session::parse::feature_err;
1011
use rustc_session::search_paths::PathKind;
1112
use rustc_session::utils::NativeLibKind;
1213
use rustc_session::Session;
14+
use rustc_span::def_id::{DefId, LOCAL_CRATE};
1315
use rustc_span::symbol::{sym, Symbol};
1416
use rustc_target::spec::abi::Abi;
1517

@@ -66,10 +68,12 @@ fn find_bundled_library(
6668
None
6769
}
6870

69-
pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
71+
pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<NativeLib> {
7072
let mut collector = Collector { tcx, libs: Vec::new() };
71-
for id in tcx.hir().items() {
72-
collector.process_item(id);
73+
if tcx.sess.opts.unstable_opts.link_directives {
74+
for module in tcx.foreign_modules(LOCAL_CRATE).values() {
75+
collector.process_module(module);
76+
}
7377
}
7478
collector.process_command_line();
7579
collector.libs
@@ -88,29 +92,20 @@ struct Collector<'tcx> {
8892
}
8993

9094
impl<'tcx> Collector<'tcx> {
91-
fn process_item(&mut self, id: rustc_hir::ItemId) {
92-
if !matches!(self.tcx.def_kind(id.owner_id), DefKind::ForeignMod) {
93-
return;
94-
}
95+
fn process_module(&mut self, module: &ForeignModule) {
96+
let ForeignModule { def_id, abi, ref foreign_items } = *module;
97+
let def_id = def_id.expect_local();
9598

96-
let it = self.tcx.hir().item(id);
97-
let hir::ItemKind::ForeignMod { abi, items: foreign_mod_items } = it.kind else {
98-
return;
99-
};
99+
let sess = self.tcx.sess;
100100

101101
if matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic) {
102102
return;
103103
}
104104

105105
// Process all of the #[link(..)]-style arguments
106-
let sess = self.tcx.sess;
107106
let features = self.tcx.features();
108107

109-
if !sess.opts.unstable_opts.link_directives {
110-
return;
111-
}
112-
113-
for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| a.has_name(sym::link)) {
108+
for m in self.tcx.get_attrs(def_id, sym::link) {
114109
let Some(items) = m.meta_item_list() else {
115110
continue;
116111
};
@@ -340,9 +335,9 @@ impl<'tcx> Collector<'tcx> {
340335
if name.as_str().contains('\0') {
341336
sess.emit_err(errors::RawDylibNoNul { span: name_span });
342337
}
343-
foreign_mod_items
338+
foreign_items
344339
.iter()
345-
.map(|child_item| {
340+
.map(|&child_item| {
346341
self.build_dll_import(
347342
abi,
348343
import_name_type.map(|(import_name_type, _)| import_name_type),
@@ -352,21 +347,12 @@ impl<'tcx> Collector<'tcx> {
352347
.collect()
353348
}
354349
_ => {
355-
for child_item in foreign_mod_items {
356-
if self.tcx.def_kind(child_item.id.owner_id).has_codegen_attrs()
357-
&& self
358-
.tcx
359-
.codegen_fn_attrs(child_item.id.owner_id)
360-
.link_ordinal
361-
.is_some()
350+
for &child_item in foreign_items {
351+
if self.tcx.def_kind(child_item).has_codegen_attrs()
352+
&& self.tcx.codegen_fn_attrs(child_item).link_ordinal.is_some()
362353
{
363-
let link_ordinal_attr = self
364-
.tcx
365-
.hir()
366-
.attrs(child_item.id.owner_id.into())
367-
.iter()
368-
.find(|a| a.has_name(sym::link_ordinal))
369-
.unwrap();
354+
let link_ordinal_attr =
355+
self.tcx.get_attr(child_item, sym::link_ordinal).unwrap();
370356
sess.emit_err(errors::LinkOrdinalRawDylib {
371357
span: link_ordinal_attr.span,
372358
});
@@ -384,7 +370,7 @@ impl<'tcx> Collector<'tcx> {
384370
filename,
385371
kind,
386372
cfg,
387-
foreign_module: Some(it.owner_id.to_def_id()),
373+
foreign_module: Some(def_id.to_def_id()),
388374
verbatim,
389375
dll_imports,
390376
});
@@ -476,10 +462,10 @@ impl<'tcx> Collector<'tcx> {
476462
}
477463
}
478464

479-
fn i686_arg_list_size(&self, item: &hir::ForeignItemRef) -> usize {
465+
fn i686_arg_list_size(&self, item: DefId) -> usize {
480466
let argument_types: &List<Ty<'_>> = self.tcx.erase_late_bound_regions(
481467
self.tcx
482-
.type_of(item.id.owner_id)
468+
.type_of(item)
483469
.instantiate_identity()
484470
.fn_sig(self.tcx)
485471
.inputs()
@@ -505,8 +491,10 @@ impl<'tcx> Collector<'tcx> {
505491
&self,
506492
abi: Abi,
507493
import_name_type: Option<PeImportNameType>,
508-
item: &hir::ForeignItemRef,
494+
item: DefId,
509495
) -> DllImport {
496+
let span = self.tcx.def_span(item);
497+
510498
let calling_convention = if self.tcx.sess.target.arch == "x86" {
511499
match abi {
512500
Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C,
@@ -520,29 +508,29 @@ impl<'tcx> Collector<'tcx> {
520508
DllCallingConvention::Vectorcall(self.i686_arg_list_size(item))
521509
}
522510
_ => {
523-
self.tcx.sess.emit_fatal(errors::UnsupportedAbiI686 { span: item.span });
511+
self.tcx.sess.emit_fatal(errors::UnsupportedAbiI686 { span });
524512
}
525513
}
526514
} else {
527515
match abi {
528516
Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C,
529517
_ => {
530-
self.tcx.sess.emit_fatal(errors::UnsupportedAbi { span: item.span });
518+
self.tcx.sess.emit_fatal(errors::UnsupportedAbi { span });
531519
}
532520
}
533521
};
534522

535-
let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item.id.owner_id);
523+
let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item);
536524
let import_name_type = codegen_fn_attrs
537525
.link_ordinal
538526
.map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
539527

540528
DllImport {
541-
name: codegen_fn_attrs.link_name.unwrap_or(item.ident.name),
529+
name: codegen_fn_attrs.link_name.unwrap_or(self.tcx.item_name(item)),
542530
import_name_type,
543531
calling_convention,
544-
span: item.span,
545-
is_fn: self.tcx.def_kind(item.id.owner_id).is_fn_like(),
532+
span,
533+
is_fn: self.tcx.def_kind(item).is_fn_like(),
546534
}
547535
}
548536
}

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

+2-4
Original file line numberDiff line numberDiff line change
@@ -403,10 +403,8 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
403403
.contains(&id)
404404
})
405405
},
406-
native_libraries: |tcx, LocalCrate| native_libs::collect(tcx),
407-
foreign_modules: |tcx, LocalCrate| {
408-
foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect()
409-
},
406+
native_libraries: native_libs::collect,
407+
foreign_modules: foreign_modules::collect,
410408

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

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1579,7 +1579,7 @@ rustc_queries! {
15791579
}
15801580

15811581
/// Returns a list of all `extern` blocks of a crate.
1582-
query foreign_modules(_: CrateNum) -> &'tcx FxHashMap<DefId, ForeignModule> {
1582+
query foreign_modules(_: CrateNum) -> &'tcx FxIndexMap<DefId, ForeignModule> {
15831583
arena_cache
15841584
desc { "looking up the foreign modules of a linked crate" }
15851585
separate_provide_extern

compiler/rustc_session/src/cstore.rs

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
1313
use rustc_span::hygiene::{ExpnHash, ExpnId};
1414
use rustc_span::symbol::Symbol;
1515
use rustc_span::Span;
16+
use rustc_target::spec::abi::Abi;
1617
use rustc_target::spec::Target;
1718

1819
use std::any::Any;
@@ -147,6 +148,7 @@ pub enum DllCallingConvention {
147148
pub struct ForeignModule {
148149
pub foreign_items: Vec<DefId>,
149150
pub def_id: DefId,
151+
pub abi: Abi,
150152
}
151153

152154
#[derive(Copy, Clone, Debug, HashStable_Generic)]

tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: multiple declarations of external function `f` from library `foo.dll` hav
22
--> $DIR/multiple-declarations.rs:13:9
33
|
44
LL | fn f(x: i32);
5-
| ^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^
66

77
error: aborting due to previous error
88

tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
22
--> $DIR/unsupported-abi.rs:6:5
33
|
44
LL | fn f(x: i32);
5-
| ^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^
66

77
error: aborting due to previous error
88

0 commit comments

Comments
 (0)