@@ -10,13 +10,13 @@ use rustc_middle::hir::nested_filter::OnlyBodies;
1010use rustc_middle:: query:: Providers ;
1111use rustc_middle:: ty:: TyCtxt ;
1212use rustc_session:: lint:: builtin:: UNDEFINED_NAKED_FUNCTION_ABI ;
13- use rustc_span:: Span ;
1413use rustc_span:: symbol:: sym;
14+ use rustc_span:: { BytePos , Span } ;
1515use rustc_target:: spec:: abi:: Abi ;
1616
1717use crate :: errors:: {
1818 NakedAsmOutsideNakedFn , NakedFunctionsAsmBlock , NakedFunctionsAsmOptions ,
19- NakedFunctionsMustUseNoreturn , NakedFunctionsOperands , NoPatterns , ParamsNotAllowed ,
19+ NakedFunctionsMustNakedAsm , NakedFunctionsOperands , NoPatterns , ParamsNotAllowed ,
2020 UndefinedNakedFunctionAbi ,
2121} ;
2222
@@ -121,21 +121,29 @@ impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> {
121121fn check_asm < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId , body : & ' tcx hir:: Body < ' tcx > ) {
122122 let mut this = CheckInlineAssembly { tcx, items : Vec :: new ( ) } ;
123123 this. visit_body ( body) ;
124- if let [ ( ItemKind :: Asm | ItemKind :: Err , _) ] = this. items [ ..] {
124+ if let [ ( ItemKind :: NakedAsm | ItemKind :: Err , _) ] = this. items [ ..] {
125125 // Ok.
126126 } else {
127127 let mut must_show_error = false ;
128- let mut has_asm = false ;
128+ let mut has_naked_asm = false ;
129129 let mut has_err = false ;
130130 let mut multiple_asms = vec ! [ ] ;
131131 let mut non_asms = vec ! [ ] ;
132132 for & ( kind, span) in & this. items {
133133 match kind {
134- ItemKind :: Asm if has_asm => {
134+ ItemKind :: NakedAsm if has_naked_asm => {
135135 must_show_error = true ;
136136 multiple_asms. push ( span) ;
137137 }
138- ItemKind :: Asm => has_asm = true ,
138+ ItemKind :: NakedAsm => has_naked_asm = true ,
139+ ItemKind :: InlineAsm => {
140+ has_err = true ;
141+
142+ // the span that contains the `asm!` call,
143+ // so tooling can replace it with `naked_asm!`
144+ let macro_span = span. with_hi ( span. lo ( ) + BytePos ( "asm!" . len ( ) as u32 ) ) ;
145+ tcx. dcx ( ) . emit_err ( NakedFunctionsMustNakedAsm { span, macro_span } ) ;
146+ }
139147 ItemKind :: NonAsm => {
140148 must_show_error = true ;
141149 non_asms. push ( span) ;
@@ -164,7 +172,8 @@ struct CheckInlineAssembly<'tcx> {
164172
165173#[ derive( Copy , Clone ) ]
166174enum ItemKind {
167- Asm ,
175+ NakedAsm ,
176+ InlineAsm ,
168177 NonAsm ,
169178 Err ,
170179}
@@ -205,8 +214,18 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
205214 }
206215
207216 ExprKind :: InlineAsm ( asm) => {
208- self . items . push ( ( ItemKind :: Asm , span) ) ;
209- self . check_inline_asm ( asm, span) ;
217+ match asm. asm_macro {
218+ rustc_ast:: AsmMacro :: Asm => {
219+ self . items . push ( ( ItemKind :: InlineAsm , span) ) ;
220+ }
221+ rustc_ast:: AsmMacro :: NakedAsm => {
222+ self . items . push ( ( ItemKind :: NakedAsm , span) ) ;
223+ self . check_inline_asm ( asm, span) ;
224+ }
225+ rustc_ast:: AsmMacro :: GlobalAsm => {
226+ // not allowed in this position
227+ }
228+ }
210229 }
211230
212231 ExprKind :: DropTemps ( ..) | ExprKind :: Block ( ..) => {
@@ -250,16 +269,6 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
250269 . join ( ", " ) ,
251270 } ) ;
252271 }
253-
254- if !asm. options . contains ( InlineAsmOptions :: NORETURN ) {
255- let last_span = asm
256- . operands
257- . last ( )
258- . map_or_else ( || asm. template_strs . last ( ) . unwrap ( ) . 2 , |op| op. 1 )
259- . shrink_to_hi ( ) ;
260-
261- self . tcx . dcx ( ) . emit_err ( NakedFunctionsMustUseNoreturn { span, last_span } ) ;
262- }
263272 }
264273}
265274
0 commit comments