@@ -10,13 +10,12 @@ use rustc_errors::struct_span_err;
10
10
use rustc_hir as hir;
11
11
use rustc_hir:: def_id:: DefId ;
12
12
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 ;
14
15
use rustc_span:: Span ;
15
16
use rustc_target:: spec:: PanicStrategy ;
16
- use syntax:: ast;
17
17
18
- macro_rules! weak_lang_items {
19
- ( $( $name: ident, $item: ident, $sym: ident; ) * ) => (
18
+ pub use rustc_lang_items:: weak_lang_items:: link_name;
20
19
21
20
struct Context < ' a , ' tcx > {
22
21
tcx : TyCtxt < ' tcx > ,
@@ -25,16 +24,14 @@ struct Context<'a, 'tcx> {
25
24
26
25
/// Checks the crate for usage of weak lang items, returning a vector of all the
27
26
/// 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 ) {
30
28
// These are never called by user code, they're generated by the compiler.
31
29
// They will never implicitly be added to the `missing` array unless we do
32
30
// so here.
33
31
if items. eh_personality ( ) . is_none ( ) {
34
32
items. missing . push ( lang_items:: EhPersonalityLangItem ) ;
35
33
}
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 ( ) {
38
35
items. missing . push ( lang_items:: EhUnwindResumeLangItem ) ;
39
36
}
40
37
@@ -45,16 +42,6 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>,
45
42
verify ( tcx, items) ;
46
43
}
47
44
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
-
58
45
/// Returns `true` if the specified `lang_item` doesn't actually need to be
59
46
/// present for this compilation.
60
47
///
@@ -66,29 +53,26 @@ pub fn whitelisted(tcx: TyCtxt<'_>, lang_item: lang_items::LangItem) -> bool {
66
53
// symbols. Other panic runtimes ensure that the relevant symbols are
67
54
// available to link things together, but they're never exercised.
68
55
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 ;
71
58
}
72
59
73
60
false
74
61
}
75
62
76
- fn verify<' tcx>( tcx: TyCtxt <' tcx>,
77
- items: & lang_items:: LanguageItems ) {
63
+ fn verify < ' tcx > ( tcx : TyCtxt < ' tcx > , items : & lang_items:: LanguageItems ) {
78
64
// We only need to check for the presence of weak lang items if we're
79
65
// 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 ,
89
73
} ) ;
90
74
if !needs_check {
91
- return
75
+ return ;
92
76
}
93
77
94
78
let mut missing = FxHashSet :: default ( ) ;
@@ -98,37 +82,28 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>,
98
82
}
99
83
}
100
84
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" ) ) ;
111
91
} 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) ) ;
114
93
}
115
94
}
116
- ) *
95
+ }
117
96
}
118
97
119
98
impl < ' a , ' tcx > Context < ' a , ' tcx > {
120
99
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) ;
124
103
}
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 ( ) ;
132
107
}
133
108
}
134
109
}
@@ -150,18 +125,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
150
125
151
126
impl < ' tcx > TyCtxt < ' tcx > {
152
127
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)
157
129
}
158
130
}
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
- }
0 commit comments