Skip to content

Commit 4ecba94

Browse files
committed
Move weak lang items to librustc_lang_items.
1 parent c04195d commit 4ecba94

File tree

3 files changed

+80
-68
lines changed

3 files changed

+80
-68
lines changed

src/librustc/middle/weak_lang_items.rs

Lines changed: 31 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@ use rustc_errors::struct_span_err;
1010
use rustc_hir as hir;
1111
use rustc_hir::def_id::DefId;
1212
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
13-
use rustc_span::symbol::{sym, Symbol};
13+
use rustc_lang_items::weak_lang_items::WEAK_ITEMS_REFS;
14+
use rustc_span::symbol::Symbol;
1415
use rustc_span::Span;
1516
use rustc_target::spec::PanicStrategy;
16-
use syntax::ast;
1717

18-
macro_rules! weak_lang_items {
19-
($($name:ident, $item:ident, $sym:ident;)*) => (
18+
pub use rustc_lang_items::weak_lang_items::link_name;
2019

2120
struct Context<'a, 'tcx> {
2221
tcx: TyCtxt<'tcx>,
@@ -25,16 +24,14 @@ struct Context<'a, 'tcx> {
2524

2625
/// Checks the crate for usage of weak lang items, returning a vector of all the
2726
/// language items required by this crate, but not defined yet.
28-
pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>,
29-
items: &mut lang_items::LanguageItems) {
27+
pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>, items: &mut lang_items::LanguageItems) {
3028
// These are never called by user code, they're generated by the compiler.
3129
// They will never implicitly be added to the `missing` array unless we do
3230
// so here.
3331
if items.eh_personality().is_none() {
3432
items.missing.push(lang_items::EhPersonalityLangItem);
3533
}
36-
if tcx.sess.target.target.options.custom_unwind_resume &
37-
items.eh_unwind_resume().is_none() {
34+
if tcx.sess.target.target.options.custom_unwind_resume & items.eh_unwind_resume().is_none() {
3835
items.missing.push(lang_items::EhUnwindResumeLangItem);
3936
}
4037

@@ -45,16 +42,6 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>,
4542
verify(tcx, items);
4643
}
4744

48-
pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
49-
rustc_lang_items::lang_items::extract(attrs).and_then(|(name, _)| {
50-
$(if name == sym::$name {
51-
Some(sym::$sym)
52-
} else)* {
53-
None
54-
}
55-
})
56-
}
57-
5845
/// Returns `true` if the specified `lang_item` doesn't actually need to be
5946
/// present for this compilation.
6047
///
@@ -66,29 +53,26 @@ pub fn whitelisted(tcx: TyCtxt<'_>, lang_item: lang_items::LangItem) -> bool {
6653
// symbols. Other panic runtimes ensure that the relevant symbols are
6754
// available to link things together, but they're never exercised.
6855
if tcx.sess.panic_strategy() != PanicStrategy::Unwind {
69-
return lang_item == lang_items::EhPersonalityLangItem ||
70-
lang_item == lang_items::EhUnwindResumeLangItem
56+
return lang_item == lang_items::EhPersonalityLangItem
57+
|| lang_item == lang_items::EhUnwindResumeLangItem;
7158
}
7259

7360
false
7461
}
7562

76-
fn verify<'tcx>(tcx: TyCtxt<'tcx>,
77-
items: &lang_items::LanguageItems) {
63+
fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) {
7864
// We only need to check for the presence of weak lang items if we're
7965
// emitting something that's not an rlib.
80-
let needs_check = tcx.sess.crate_types.borrow().iter().any(|kind| {
81-
match *kind {
82-
config::CrateType::Dylib |
83-
config::CrateType::ProcMacro |
84-
config::CrateType::Cdylib |
85-
config::CrateType::Executable |
86-
config::CrateType::Staticlib => true,
87-
config::CrateType::Rlib => false,
88-
}
66+
let needs_check = tcx.sess.crate_types.borrow().iter().any(|kind| match *kind {
67+
config::CrateType::Dylib
68+
| config::CrateType::ProcMacro
69+
| config::CrateType::Cdylib
70+
| config::CrateType::Executable
71+
| config::CrateType::Staticlib => true,
72+
config::CrateType::Rlib => false,
8973
});
9074
if !needs_check {
91-
return
75+
return;
9276
}
9377

9478
let mut missing = FxHashSet::default();
@@ -98,37 +82,28 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>,
9882
}
9983
}
10084

101-
$(
102-
if missing.contains(&lang_items::$item) &&
103-
!whitelisted(tcx, lang_items::$item) &&
104-
items.$name().is_none() {
105-
if lang_items::$item == lang_items::PanicImplLangItem {
106-
tcx.sess.err(&format!("`#[panic_handler]` function required, \
107-
but not found"));
108-
} else if lang_items::$item == lang_items::OomLangItem {
109-
tcx.sess.err(&format!("`#[alloc_error_handler]` function required, \
110-
but not found"));
85+
for (name, &item) in WEAK_ITEMS_REFS.iter() {
86+
if missing.contains(&item) && !whitelisted(tcx, item) && items.require(item).is_err() {
87+
if item == lang_items::PanicImplLangItem {
88+
tcx.sess.err(&format!("`#[panic_handler]` function required, but not found"));
89+
} else if item == lang_items::OomLangItem {
90+
tcx.sess.err(&format!("`#[alloc_error_handler]` function required, but not found"));
11191
} else {
112-
tcx.sess.err(&format!("language item required, but not found: `{}`",
113-
stringify!($name)));
92+
tcx.sess.err(&format!("language item required, but not found: `{}`", name));
11493
}
11594
}
116-
)*
95+
}
11796
}
11897

11998
impl<'a, 'tcx> Context<'a, 'tcx> {
12099
fn register(&mut self, name: Symbol, span: Span) {
121-
$(if name == sym::$name {
122-
if self.items.$name().is_none() {
123-
self.items.missing.push(lang_items::$item);
100+
if let Some(&item) = WEAK_ITEMS_REFS.get(&name) {
101+
if self.items.require(item).is_err() {
102+
self.items.missing.push(item);
124103
}
125-
} else)* {
126-
struct_span_err!(
127-
self.tcx.sess, span, E0264,
128-
"unknown external lang item: `{}`",
129-
name
130-
)
131-
.emit();
104+
} else {
105+
struct_span_err!(self.tcx.sess, span, E0264, "unknown external lang item: `{}`", name)
106+
.emit();
132107
}
133108
}
134109
}
@@ -150,18 +125,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
150125

151126
impl<'tcx> TyCtxt<'tcx> {
152127
pub fn is_weak_lang_item(&self, item_def_id: DefId) -> bool {
153-
let lang_items = self.lang_items();
154-
let did = Some(item_def_id);
155-
156-
$(lang_items.$name() == did)||*
128+
self.lang_items().is_weak_lang_item(item_def_id)
157129
}
158130
}
159-
160-
) }
161-
162-
weak_lang_items! {
163-
panic_impl, PanicImplLangItem, rust_begin_unwind;
164-
eh_personality, EhPersonalityLangItem, rust_eh_personality;
165-
eh_unwind_resume, EhUnwindResumeLangItem, rust_eh_unwind_resume;
166-
oom, OomLangItem, rust_oom;
167-
}

src/librustc_lang_items/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ macro_rules! enum_from_u32 {
3737

3838
pub mod lang_items;
3939
mod target;
40+
pub mod weak_lang_items;
4041

4142
pub use lang_items::{LangItem, LanguageItems};
4243
pub use target::{MethodKind, Target};
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//! Validity checking for weak lang items
2+
3+
use crate::{lang_items, LangItem, LanguageItems};
4+
5+
use rustc_data_structures::fx::FxHashMap;
6+
use rustc_hir::def_id::DefId;
7+
use rustc_span::symbol::{sym, Symbol};
8+
use syntax::ast;
9+
10+
use lazy_static::lazy_static;
11+
12+
macro_rules! weak_lang_items {
13+
($($name:ident, $item:ident, $sym:ident;)*) => (
14+
15+
lazy_static! {
16+
pub static ref WEAK_ITEMS_REFS: FxHashMap<Symbol, LangItem> = {
17+
let mut map = FxHashMap::default();
18+
$(map.insert(sym::$name, lang_items::$item);)*
19+
map
20+
};
21+
}
22+
23+
pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
24+
lang_items::extract(attrs).and_then(|(name, _)| {
25+
$(if name == sym::$name {
26+
Some(sym::$sym)
27+
} else)* {
28+
None
29+
}
30+
})
31+
}
32+
33+
impl LanguageItems {
34+
pub fn is_weak_lang_item(&self, item_def_id: DefId) -> bool {
35+
let did = Some(item_def_id);
36+
37+
$(self.$name() == did)||*
38+
}
39+
}
40+
41+
) }
42+
43+
weak_lang_items! {
44+
panic_impl, PanicImplLangItem, rust_begin_unwind;
45+
eh_personality, EhPersonalityLangItem, rust_eh_personality;
46+
eh_unwind_resume, EhUnwindResumeLangItem, rust_eh_unwind_resume;
47+
oom, OomLangItem, rust_oom;
48+
}

0 commit comments

Comments
 (0)