11//! Checks validity of naked functions.
22
33use rustc_ast:: { Attribute , InlineAsmOptions } ;
4+ use rustc_errors:: struct_span_err;
45use rustc_hir as hir;
56use rustc_hir:: def_id:: LocalDefId ;
67use rustc_hir:: intravisit:: { FnKind , Visitor } ;
78use rustc_hir:: { ExprKind , HirId , InlineAsmOperand , StmtKind } ;
89use rustc_middle:: ty:: query:: Providers ;
910use rustc_middle:: ty:: TyCtxt ;
1011use rustc_session:: lint:: builtin:: UNDEFINED_NAKED_FUNCTION_ABI ;
11- use rustc_session:: lint:: builtin:: UNSUPPORTED_NAKED_FUNCTIONS ;
1212use rustc_span:: symbol:: sym;
1313use rustc_span:: Span ;
1414use rustc_target:: spec:: abi:: Abi ;
@@ -64,18 +64,16 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
6464 check_abi ( self . tcx , hir_id, fn_header. abi , ident_span) ;
6565 check_no_patterns ( self . tcx , body. params ) ;
6666 check_no_parameters_use ( self . tcx , body) ;
67- check_asm ( self . tcx , hir_id , body, span) ;
68- check_inline ( self . tcx , hir_id , attrs) ;
67+ check_asm ( self . tcx , body, span) ;
68+ check_inline ( self . tcx , attrs) ;
6969 }
7070 }
7171}
7272
7373/// Check that the function isn't inlined.
74- fn check_inline ( tcx : TyCtxt < ' _ > , hir_id : HirId , attrs : & [ Attribute ] ) {
74+ fn check_inline ( tcx : TyCtxt < ' _ > , attrs : & [ Attribute ] ) {
7575 for attr in attrs. iter ( ) . filter ( |attr| attr. has_name ( sym:: inline) ) {
76- tcx. struct_span_lint_hir ( UNSUPPORTED_NAKED_FUNCTIONS , hir_id, attr. span , |lint| {
77- lint. build ( "naked functions cannot be inlined" ) . emit ( ) ;
78- } ) ;
76+ tcx. sess . struct_span_err ( attr. span , "naked functions cannot be inlined" ) . emit ( ) ;
7977 }
8078}
8179
@@ -146,31 +144,31 @@ impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> {
146144}
147145
148146/// Checks that function body contains a single inline assembly block.
149- fn check_asm < ' tcx > ( tcx : TyCtxt < ' tcx > , hir_id : HirId , body : & ' tcx hir:: Body < ' tcx > , fn_span : Span ) {
147+ fn check_asm < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & ' tcx hir:: Body < ' tcx > , fn_span : Span ) {
150148 let mut this = CheckInlineAssembly { tcx, items : Vec :: new ( ) } ;
151149 this. visit_body ( body) ;
152150 if let [ ( ItemKind :: Asm , _) ] = this. items [ ..] {
153151 // Ok.
154152 } else {
155- tcx . struct_span_lint_hir ( UNSUPPORTED_NAKED_FUNCTIONS , hir_id , fn_span , |lint| {
156- let mut diag = lint . build ( "naked functions must contain a single asm block" ) ;
157- let mut has_asm = false ;
158- for & ( kind , span ) in & this . items {
159- match kind {
160- ItemKind :: Asm if has_asm => {
161- diag . span_label (
162- span ,
163- "multiple asm blocks are unsupported in naked functions" ,
164- ) ;
165- }
166- ItemKind :: Asm => has_asm = true ,
167- ItemKind :: NonAsm => {
168- diag . span_label ( span , "non-asm is unsupported in naked functions" ) ;
169- }
153+ let mut diag = struct_span_err ! (
154+ tcx . sess ,
155+ fn_span ,
156+ E0787 ,
157+ "naked functions must contain a single asm block"
158+ ) ;
159+ let mut has_asm = false ;
160+ for & ( kind , span ) in & this . items {
161+ match kind {
162+ ItemKind :: Asm if has_asm => {
163+ diag . span_label ( span , "multiple asm blocks are unsupported in naked functions" ) ;
164+ }
165+ ItemKind :: Asm => has_asm = true ,
166+ ItemKind :: NonAsm => {
167+ diag . span_label ( span , "non-asm is unsupported in naked functions" ) ;
170168 }
171169 }
172- diag . emit ( ) ;
173- } ) ;
170+ }
171+ diag . emit ( ) ;
174172 }
175173}
176174
@@ -221,7 +219,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
221219
222220 ExprKind :: InlineAsm ( ref asm) => {
223221 self . items . push ( ( ItemKind :: Asm , span) ) ;
224- self . check_inline_asm ( expr . hir_id , asm, span) ;
222+ self . check_inline_asm ( asm, span) ;
225223 }
226224
227225 ExprKind :: DropTemps ( ..) | ExprKind :: Block ( ..) | ExprKind :: Err => {
@@ -230,7 +228,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
230228 }
231229 }
232230
233- fn check_inline_asm ( & self , hir_id : HirId , asm : & ' tcx hir:: InlineAsm < ' tcx > , span : Span ) {
231+ fn check_inline_asm ( & self , asm : & ' tcx hir:: InlineAsm < ' tcx > , span : Span ) {
234232 let unsupported_operands: Vec < Span > = asm
235233 . operands
236234 . iter ( )
@@ -243,18 +241,17 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
243241 } )
244242 . collect ( ) ;
245243 if !unsupported_operands. is_empty ( ) {
246- self . tcx . struct_span_lint_hir (
247- UNSUPPORTED_NAKED_FUNCTIONS ,
248- hir_id,
244+ struct_span_err ! (
245+ self . tcx. sess,
249246 unsupported_operands,
250- |lint| {
251- lint. build ( "only `const` and `sym` operands are supported in naked functions" )
252- . emit ( ) ;
253- } ,
254- ) ;
247+ E0787 ,
248+ "only `const` and `sym` operands are supported in naked functions" ,
249+ )
250+ . emit ( ) ;
255251 }
256252
257253 let unsupported_options: Vec < & ' static str > = [
254+ ( InlineAsmOptions :: MAY_UNWIND , "`may_unwind`" ) ,
258255 ( InlineAsmOptions :: NOMEM , "`nomem`" ) ,
259256 ( InlineAsmOptions :: NOSTACK , "`nostack`" ) ,
260257 ( InlineAsmOptions :: PRESERVES_FLAGS , "`preserves_flags`" ) ,
@@ -266,19 +263,24 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
266263 . collect ( ) ;
267264
268265 if !unsupported_options. is_empty ( ) {
269- self . tcx . struct_span_lint_hir ( UNSUPPORTED_NAKED_FUNCTIONS , hir_id, span, |lint| {
270- lint. build ( & format ! (
271- "asm options unsupported in naked functions: {}" ,
272- unsupported_options. join( ", " )
273- ) )
274- . emit ( ) ;
275- } ) ;
266+ struct_span_err ! (
267+ self . tcx. sess,
268+ span,
269+ E0787 ,
270+ "asm options unsupported in naked functions: {}" ,
271+ unsupported_options. join( ", " )
272+ )
273+ . emit ( ) ;
276274 }
277275
278276 if !asm. options . contains ( InlineAsmOptions :: NORETURN ) {
279- self . tcx . struct_span_lint_hir ( UNSUPPORTED_NAKED_FUNCTIONS , hir_id, span, |lint| {
280- lint. build ( "asm in naked functions must use `noreturn` option" ) . emit ( ) ;
281- } ) ;
277+ struct_span_err ! (
278+ self . tcx. sess,
279+ span,
280+ E0787 ,
281+ "asm in naked functions must use `noreturn` option"
282+ )
283+ . emit ( ) ;
282284 }
283285 }
284286}
0 commit comments