Auto merge of #108006 - cjgillot:def-impl, r=oli-obk
Avoid accessing HIR when it can be avoided Experiment to see if it helps some incremental cases. Will be rebased once https://github.com/rust-lang/rust/pull/107942 gets merged. r? `@ghost`
This commit is contained in:
commit
2d14db321b
43 changed files with 316 additions and 777 deletions
|
@ -2,9 +2,8 @@ use std::collections::hash_map::Entry::*;
|
|||
|
||||
use rustc_ast::expand::allocator::ALLOCATOR_METHODS;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::Node;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::middle::exported_symbols::{
|
||||
metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
|
||||
|
@ -12,7 +11,7 @@ use rustc_middle::middle::exported_symbols::{
|
|||
use rustc_middle::ty::query::{ExternProviders, Providers};
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::Instance;
|
||||
use rustc_middle::ty::{self, SymbolName, TyCtxt};
|
||||
use rustc_middle::ty::{self, DefIdTree, SymbolName, TyCtxt};
|
||||
use rustc_session::config::{CrateType, OomStrategy};
|
||||
use rustc_target::spec::SanitizerSet;
|
||||
|
||||
|
@ -74,32 +73,34 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
|
|||
//
|
||||
// As a result, if this id is an FFI item (foreign item) then we only
|
||||
// let it through if it's included statically.
|
||||
match tcx.hir().get_by_def_id(def_id) {
|
||||
Node::ForeignItem(..) => {
|
||||
tcx.native_library(def_id).map_or(false, |library| library.kind.is_statically_included()).then_some(def_id)
|
||||
}
|
||||
if let Some(parent_id) = tcx.opt_local_parent(def_id)
|
||||
&& let DefKind::ForeignMod = tcx.def_kind(parent_id)
|
||||
{
|
||||
let library = tcx.native_library(def_id)?;
|
||||
return library.kind.is_statically_included().then_some(def_id);
|
||||
}
|
||||
|
||||
// Only consider nodes that actually have exported symbols.
|
||||
Node::Item(&hir::Item {
|
||||
kind: hir::ItemKind::Static(..) | hir::ItemKind::Fn(..),
|
||||
..
|
||||
})
|
||||
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
|
||||
let generics = tcx.generics_of(def_id);
|
||||
if !generics.requires_monomorphization(tcx)
|
||||
// Functions marked with #[inline] are codegened with "internal"
|
||||
// linkage and are not exported unless marked with an extern
|
||||
// indicator
|
||||
&& (!Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx)
|
||||
|| tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator())
|
||||
{
|
||||
Some(def_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
// Only consider nodes that actually have exported symbols.
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::Fn | DefKind::Static(_) => {}
|
||||
DefKind::AssocFn if tcx.impl_of_method(def_id.to_def_id()).is_some() => {}
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
_ => None,
|
||||
let generics = tcx.generics_of(def_id);
|
||||
if generics.requires_monomorphization(tcx) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Functions marked with #[inline] are codegened with "internal"
|
||||
// linkage and are not exported unless marked with an extern
|
||||
// indicator
|
||||
if !Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx)
|
||||
|| tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator()
|
||||
{
|
||||
Some(def_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|def_id| {
|
||||
|
@ -118,7 +119,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
|
|||
tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())),
|
||||
export_level
|
||||
);
|
||||
(def_id.to_def_id(), SymbolExportInfo {
|
||||
let info = SymbolExportInfo {
|
||||
level: export_level,
|
||||
kind: if tcx.is_static(def_id.to_def_id()) {
|
||||
if codegen_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
|
||||
|
@ -130,8 +131,10 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
|
|||
SymbolExportKind::Text
|
||||
},
|
||||
used: codegen_attrs.flags.contains(CodegenFnAttrFlags::USED)
|
||||
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) || used,
|
||||
})
|
||||
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
|
||||
|| used,
|
||||
};
|
||||
(def_id.to_def_id(), info)
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
@ -457,9 +460,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel
|
|||
let target = &tcx.sess.target.llvm_target;
|
||||
// WebAssembly cannot export data symbols, so reduce their export level
|
||||
if target.contains("emscripten") {
|
||||
if let Some(Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. })) =
|
||||
tcx.hir().get_if_local(sym_def_id)
|
||||
{
|
||||
if let DefKind::Static(_) = tcx.def_kind(sym_def_id) {
|
||||
return SymbolExportLevel::Rust;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@ use rustc_attr::InstructionSetAttr;
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::ty::{DefIdTree, TyCtxt};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -440,12 +440,9 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxHashSet<Symbol> {
|
|||
/// Checks the function annotated with `#[target_feature]` is not a safe
|
||||
/// trait method implementation, reporting an error if it is.
|
||||
pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) {
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(id);
|
||||
let node = tcx.hir().get(hir_id);
|
||||
if let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) = node {
|
||||
let parent_id = tcx.hir().get_parent_item(hir_id);
|
||||
let parent_item = tcx.hir().expect_item(parent_id.def_id);
|
||||
if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = parent_item.kind {
|
||||
if let DefKind::AssocFn = tcx.def_kind(id) {
|
||||
let parent_id = tcx.local_parent(id);
|
||||
if let DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) {
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
attr_span,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue