Do not fetch HIR in native_libs.

This commit is contained in:
Camille GILLOT 2023-07-15 10:17:37 +00:00
parent 51e1f7a561
commit fdc93f307f
5 changed files with 43 additions and 56 deletions

View File

@ -1,4 +1,4 @@
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@ -6,11 +6,8 @@
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_session::cstore::ForeignModule; use rustc_session::cstore::ForeignModule;
pub(crate) fn collect( pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> FxIndexMap<DefId, ForeignModule> {
tcx: TyCtxt<'_>, let mut modules = FxIndexMap::default();
LocalCrate: LocalCrate,
) -> FxHashMap<DefId, ForeignModule> {
let mut modules = FxHashMap::default();
// We need to collect all the `ForeignMod`, even if they are empty. // We need to collect all the `ForeignMod`, even if they are empty.
for id in tcx.hir().items() { for id in tcx.hir().items() {
@ -21,9 +18,9 @@ pub(crate) fn collect(
let def_id = id.owner_id.to_def_id(); let def_id = id.owner_id.to_def_id();
let item = tcx.hir().item(id); let item = tcx.hir().item(id);
if let hir::ItemKind::ForeignMod { items, .. } = item.kind { if let hir::ItemKind::ForeignMod { abi, items } = item.kind {
let foreign_items = items.iter().map(|it| it.id.owner_id.to_def_id()).collect(); let foreign_items = items.iter().map(|it| it.id.owner_id.to_def_id()).collect();
modules.insert(def_id, ForeignModule { foreign_items, def_id }); modules.insert(def_id, ForeignModule { def_id, abi, foreign_items });
} }
} }

View File

@ -1,15 +1,17 @@
use rustc_ast::{NestedMetaItem, CRATE_NODE_ID}; use rustc_ast::{NestedMetaItem, CRATE_NODE_ID};
use rustc_attr as attr; use rustc_attr as attr;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir; use rustc_middle::query::LocalCrate;
use rustc_hir::def::DefKind;
use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
use rustc_session::config::CrateType; use rustc_session::config::CrateType;
use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib, PeImportNameType}; use rustc_session::cstore::{
DllCallingConvention, DllImport, ForeignModule, NativeLib, PeImportNameType,
};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_session::search_paths::PathKind; use rustc_session::search_paths::PathKind;
use rustc_session::utils::NativeLibKind; use rustc_session::utils::NativeLibKind;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
@ -66,10 +68,12 @@ fn find_bundled_library(
None None
} }
pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> { pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<NativeLib> {
let mut collector = Collector { tcx, libs: Vec::new() }; let mut collector = Collector { tcx, libs: Vec::new() };
for id in tcx.hir().items() { if tcx.sess.opts.unstable_opts.link_directives {
collector.process_item(id); for module in tcx.foreign_modules(LOCAL_CRATE).values() {
collector.process_module(module);
}
} }
collector.process_command_line(); collector.process_command_line();
collector.libs collector.libs
@ -88,29 +92,20 @@ struct Collector<'tcx> {
} }
impl<'tcx> Collector<'tcx> { impl<'tcx> Collector<'tcx> {
fn process_item(&mut self, id: rustc_hir::ItemId) { fn process_module(&mut self, module: &ForeignModule) {
if !matches!(self.tcx.def_kind(id.owner_id), DefKind::ForeignMod) { let ForeignModule { def_id, abi, ref foreign_items } = *module;
return; let def_id = def_id.expect_local();
}
let it = self.tcx.hir().item(id); let sess = self.tcx.sess;
let hir::ItemKind::ForeignMod { abi, items: foreign_mod_items } = it.kind else {
return;
};
if matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic) { if matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic) {
return; return;
} }
// Process all of the #[link(..)]-style arguments // Process all of the #[link(..)]-style arguments
let sess = self.tcx.sess;
let features = self.tcx.features(); let features = self.tcx.features();
if !sess.opts.unstable_opts.link_directives { for m in self.tcx.get_attrs(def_id, sym::link) {
return;
}
for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| a.has_name(sym::link)) {
let Some(items) = m.meta_item_list() else { let Some(items) = m.meta_item_list() else {
continue; continue;
}; };
@ -340,9 +335,9 @@ fn process_item(&mut self, id: rustc_hir::ItemId) {
if name.as_str().contains('\0') { if name.as_str().contains('\0') {
sess.emit_err(errors::RawDylibNoNul { span: name_span }); sess.emit_err(errors::RawDylibNoNul { span: name_span });
} }
foreign_mod_items foreign_items
.iter() .iter()
.map(|child_item| { .map(|&child_item| {
self.build_dll_import( self.build_dll_import(
abi, abi,
import_name_type.map(|(import_name_type, _)| import_name_type), import_name_type.map(|(import_name_type, _)| import_name_type),
@ -352,21 +347,12 @@ fn process_item(&mut self, id: rustc_hir::ItemId) {
.collect() .collect()
} }
_ => { _ => {
for child_item in foreign_mod_items { for &child_item in foreign_items {
if self.tcx.def_kind(child_item.id.owner_id).has_codegen_attrs() if self.tcx.def_kind(child_item).has_codegen_attrs()
&& self && self.tcx.codegen_fn_attrs(child_item).link_ordinal.is_some()
.tcx
.codegen_fn_attrs(child_item.id.owner_id)
.link_ordinal
.is_some()
{ {
let link_ordinal_attr = self let link_ordinal_attr =
.tcx self.tcx.get_attr(child_item, sym::link_ordinal).unwrap();
.hir()
.attrs(child_item.id.owner_id.into())
.iter()
.find(|a| a.has_name(sym::link_ordinal))
.unwrap();
sess.emit_err(errors::LinkOrdinalRawDylib { sess.emit_err(errors::LinkOrdinalRawDylib {
span: link_ordinal_attr.span, span: link_ordinal_attr.span,
}); });
@ -384,7 +370,7 @@ fn process_item(&mut self, id: rustc_hir::ItemId) {
filename, filename,
kind, kind,
cfg, cfg,
foreign_module: Some(it.owner_id.to_def_id()), foreign_module: Some(def_id.to_def_id()),
verbatim, verbatim,
dll_imports, dll_imports,
}); });
@ -476,10 +462,10 @@ fn process_command_line(&mut self) {
} }
} }
fn i686_arg_list_size(&self, item: &hir::ForeignItemRef) -> usize { fn i686_arg_list_size(&self, item: DefId) -> usize {
let argument_types: &List<Ty<'_>> = self.tcx.erase_late_bound_regions( let argument_types: &List<Ty<'_>> = self.tcx.erase_late_bound_regions(
self.tcx self.tcx
.type_of(item.id.owner_id) .type_of(item)
.instantiate_identity() .instantiate_identity()
.fn_sig(self.tcx) .fn_sig(self.tcx)
.inputs() .inputs()
@ -505,8 +491,10 @@ fn build_dll_import(
&self, &self,
abi: Abi, abi: Abi,
import_name_type: Option<PeImportNameType>, import_name_type: Option<PeImportNameType>,
item: &hir::ForeignItemRef, item: DefId,
) -> DllImport { ) -> DllImport {
let span = self.tcx.def_span(item);
let calling_convention = if self.tcx.sess.target.arch == "x86" { let calling_convention = if self.tcx.sess.target.arch == "x86" {
match abi { match abi {
Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C, Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C,
@ -520,29 +508,29 @@ fn build_dll_import(
DllCallingConvention::Vectorcall(self.i686_arg_list_size(item)) DllCallingConvention::Vectorcall(self.i686_arg_list_size(item))
} }
_ => { _ => {
self.tcx.sess.emit_fatal(errors::UnsupportedAbiI686 { span: item.span }); self.tcx.sess.emit_fatal(errors::UnsupportedAbiI686 { span });
} }
} }
} else { } else {
match abi { match abi {
Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C, Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C,
_ => { _ => {
self.tcx.sess.emit_fatal(errors::UnsupportedAbi { span: item.span }); self.tcx.sess.emit_fatal(errors::UnsupportedAbi { span });
} }
} }
}; };
let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item.id.owner_id); let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item);
let import_name_type = codegen_fn_attrs let import_name_type = codegen_fn_attrs
.link_ordinal .link_ordinal
.map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord))); .map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
DllImport { DllImport {
name: codegen_fn_attrs.link_name.unwrap_or(item.ident.name), name: codegen_fn_attrs.link_name.unwrap_or(self.tcx.item_name(item)),
import_name_type, import_name_type,
calling_convention, calling_convention,
span: item.span, span,
is_fn: self.tcx.def_kind(item.id.owner_id).is_fn_like(), is_fn: self.tcx.def_kind(item).is_fn_like(),
} }
} }
} }

View File

@ -403,7 +403,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
.contains(&id) .contains(&id)
}) })
}, },
native_libraries: |tcx, LocalCrate| native_libs::collect(tcx), native_libraries: native_libs::collect,
foreign_modules: foreign_modules::collect, foreign_modules: foreign_modules::collect,
// Returns a map from a sufficiently visible external item (i.e., an // Returns a map from a sufficiently visible external item (i.e., an

View File

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

View File

@ -13,6 +13,7 @@
use rustc_span::hygiene::{ExpnHash, ExpnId}; use rustc_span::hygiene::{ExpnHash, ExpnId};
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use rustc_span::Span; use rustc_span::Span;
use rustc_target::spec::abi::Abi;
use rustc_target::spec::Target; use rustc_target::spec::Target;
use std::any::Any; use std::any::Any;
@ -147,6 +148,7 @@ pub enum DllCallingConvention {
pub struct ForeignModule { pub struct ForeignModule {
pub foreign_items: Vec<DefId>, pub foreign_items: Vec<DefId>,
pub def_id: DefId, pub def_id: DefId,
pub abi: Abi,
} }
#[derive(Copy, Clone, Debug, HashStable_Generic)] #[derive(Copy, Clone, Debug, HashStable_Generic)]