1
1
//! Checks validity of naked functions.
2
2
3
3
use rustc_ast:: InlineAsmOptions ;
4
- use rustc_errors:: { struct_span_err, Applicability } ;
5
4
use rustc_hir as hir;
6
5
use rustc_hir:: def:: DefKind ;
7
6
use rustc_hir:: def_id:: LocalDefId ;
@@ -14,6 +13,12 @@ use rustc_span::symbol::sym;
14
13
use rustc_span:: Span ;
15
14
use rustc_target:: spec:: abi:: Abi ;
16
15
16
+ use crate :: errors:: {
17
+ CannotInlineNakedFunction , NakedFunctionsAsmBlock , NakedFunctionsAsmOptions ,
18
+ NakedFunctionsMustUseNoreturn , NakedFunctionsOperands , NoPatterns , ParamsNotAllowed ,
19
+ UndefinedNakedFunctionAbi ,
20
+ } ;
21
+
17
22
pub ( crate ) fn provide ( providers : & mut Providers ) {
18
23
* providers = Providers { check_mod_naked_functions, ..* providers } ;
19
24
}
@@ -56,7 +61,7 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
56
61
fn check_inline ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) {
57
62
let attrs = tcx. get_attrs ( def_id. to_def_id ( ) , sym:: inline) ;
58
63
for attr in attrs {
59
- tcx. sess . struct_span_err ( attr . span , "naked functions cannot be inlined" ) . emit ( ) ;
64
+ tcx. sess . emit_err ( CannotInlineNakedFunction { span : attr . span } ) ;
60
65
}
61
66
}
62
67
@@ -65,12 +70,11 @@ fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: Abi) {
65
70
if abi == Abi :: Rust {
66
71
let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
67
72
let span = tcx. def_span ( def_id) ;
68
- tcx. struct_span_lint_hir (
73
+ tcx. emit_spanned_lint (
69
74
UNDEFINED_NAKED_FUNCTION_ABI ,
70
75
hir_id,
71
76
span,
72
- "Rust ABI is unsupported in naked functions" ,
73
- |lint| lint,
77
+ UndefinedNakedFunctionAbi ,
74
78
) ;
75
79
}
76
80
}
@@ -82,12 +86,7 @@ fn check_no_patterns(tcx: TyCtxt<'_>, params: &[hir::Param<'_>]) {
82
86
hir:: PatKind :: Wild
83
87
| hir:: PatKind :: Binding ( hir:: BindingAnnotation :: NONE , _, _, None ) => { }
84
88
_ => {
85
- tcx. sess
86
- . struct_span_err (
87
- param. pat . span ,
88
- "patterns not allowed in naked function parameters" ,
89
- )
90
- . emit ( ) ;
89
+ tcx. sess . emit_err ( NoPatterns { span : param. pat . span } ) ;
91
90
}
92
91
}
93
92
}
@@ -117,14 +116,7 @@ impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> {
117
116
) ) = expr. kind
118
117
{
119
118
if self . params . contains ( var_hir_id) {
120
- self . tcx
121
- . sess
122
- . struct_span_err (
123
- expr. span ,
124
- "referencing function parameters is not allowed in naked functions" ,
125
- )
126
- . help ( "follow the calling convention in asm block to use parameters" )
127
- . emit ( ) ;
119
+ self . tcx . sess . emit_err ( ParamsNotAllowed { span : expr. span } ) ;
128
120
return ;
129
121
}
130
122
}
@@ -139,26 +131,21 @@ fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<
139
131
if let [ ( ItemKind :: Asm | ItemKind :: Err , _) ] = this. items [ ..] {
140
132
// Ok.
141
133
} else {
142
- let mut diag = struct_span_err ! (
143
- tcx. sess,
144
- tcx. def_span( def_id) ,
145
- E0787 ,
146
- "naked functions must contain a single asm block"
147
- ) ;
148
-
149
134
let mut must_show_error = false ;
150
135
let mut has_asm = false ;
151
136
let mut has_err = false ;
137
+ let mut multiple_asms = vec ! [ ] ;
138
+ let mut non_asms = vec ! [ ] ;
152
139
for & ( kind, span) in & this. items {
153
140
match kind {
154
141
ItemKind :: Asm if has_asm => {
155
142
must_show_error = true ;
156
- diag . span_label ( span, "multiple asm blocks are unsupported in naked functions" ) ;
143
+ multiple_asms . push ( span) ;
157
144
}
158
145
ItemKind :: Asm => has_asm = true ,
159
146
ItemKind :: NonAsm => {
160
147
must_show_error = true ;
161
- diag . span_label ( span, "non-asm is unsupported in naked functions" ) ;
148
+ non_asms . push ( span) ;
162
149
}
163
150
ItemKind :: Err => has_err = true ,
164
151
}
@@ -168,9 +155,11 @@ fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<
168
155
// errors, then don't show an additional error. This allows for appending/prepending
169
156
// `compile_error!("...")` statements and reduces error noise.
170
157
if must_show_error || !has_err {
171
- diag. emit ( ) ;
172
- } else {
173
- diag. cancel ( ) ;
158
+ tcx. sess . emit_err ( NakedFunctionsAsmBlock {
159
+ span : tcx. def_span ( def_id) ,
160
+ multiple_asms,
161
+ non_asms,
162
+ } ) ;
174
163
}
175
164
}
176
165
}
@@ -251,13 +240,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
251
240
} )
252
241
. collect ( ) ;
253
242
if !unsupported_operands. is_empty ( ) {
254
- struct_span_err ! (
255
- self . tcx. sess,
256
- unsupported_operands,
257
- E0787 ,
258
- "only `const` and `sym` operands are supported in naked functions" ,
259
- )
260
- . emit ( ) ;
243
+ self . tcx . sess . emit_err ( NakedFunctionsOperands { unsupported_operands } ) ;
261
244
}
262
245
263
246
let unsupported_options: Vec < & ' static str > = [
@@ -273,14 +256,10 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
273
256
. collect ( ) ;
274
257
275
258
if !unsupported_options. is_empty ( ) {
276
- struct_span_err ! (
277
- self . tcx. sess,
259
+ self . tcx . sess . emit_err ( NakedFunctionsAsmOptions {
278
260
span,
279
- E0787 ,
280
- "asm options unsupported in naked functions: {}" ,
281
- unsupported_options. join( ", " )
282
- )
283
- . emit ( ) ;
261
+ unsupported_options : unsupported_options. join ( ", " ) ,
262
+ } ) ;
284
263
}
285
264
286
265
if !asm. options . contains ( InlineAsmOptions :: NORETURN ) {
@@ -290,20 +269,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
290
269
. map_or_else ( || asm. template_strs . last ( ) . unwrap ( ) . 2 , |op| op. 1 )
291
270
. shrink_to_hi ( ) ;
292
271
293
- struct_span_err ! (
294
- self . tcx. sess,
295
- span,
296
- E0787 ,
297
- "asm in naked functions must use `noreturn` option"
298
- )
299
- . span_suggestion (
300
- last_span,
301
- "consider specifying that the asm block is responsible \
302
- for returning from the function",
303
- ", options(noreturn)" ,
304
- Applicability :: MachineApplicable ,
305
- )
306
- . emit ( ) ;
272
+ self . tcx . sess . emit_err ( NakedFunctionsMustUseNoreturn { span, last_span } ) ;
307
273
}
308
274
}
309
275
}
0 commit comments