@@ -16,10 +16,11 @@ use rustc_target::asm::{
1616
1717use crate :: errors:: RegisterTypeUnstable ;
1818
19- pub struct InlineAsmCtxt < ' a , ' tcx > {
19+ pub struct InlineAsmCtxt < ' a , ' tcx : ' a > {
2020 tcx : TyCtxt < ' tcx > ,
2121 typing_env : ty:: TypingEnv < ' tcx > ,
22- get_operand_ty : Box < dyn Fn ( & ' tcx hir:: Expr < ' tcx > ) -> Ty < ' tcx > + ' a > ,
22+ target_features : & ' tcx FxIndexSet < Symbol > ,
23+ expr_ty : Box < dyn Fn ( & hir:: Expr < ' tcx > ) -> Ty < ' tcx > + ' a > ,
2324}
2425
2526enum NonAsmTypeReason < ' tcx > {
@@ -29,14 +30,15 @@ enum NonAsmTypeReason<'tcx> {
2930}
3031
3132impl < ' a , ' tcx > InlineAsmCtxt < ' a , ' tcx > {
32- pub fn new_global_asm ( tcx : TyCtxt < ' tcx > ) -> Self {
33+ pub fn new_global_asm ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId ) -> Self {
3334 InlineAsmCtxt {
3435 tcx,
3536 typing_env : ty:: TypingEnv {
3637 typing_mode : ty:: TypingMode :: non_body_analysis ( ) ,
3738 param_env : ty:: ParamEnv :: empty ( ) ,
3839 } ,
39- get_operand_ty : Box :: new ( |e| bug ! ( "asm operand in global asm: {e:?}" ) ) ,
40+ target_features : tcx. asm_target_features ( def_id) ,
41+ expr_ty : Box :: new ( |e| bug ! ( "asm operand in global asm: {e:?}" ) ) ,
4042 }
4143 }
4244
@@ -45,9 +47,19 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
4547 pub fn new_in_fn (
4648 tcx : TyCtxt < ' tcx > ,
4749 typing_env : ty:: TypingEnv < ' tcx > ,
48- get_operand_ty : impl Fn ( & ' tcx hir:: Expr < ' tcx > ) -> Ty < ' tcx > + ' a ,
50+ def_id : LocalDefId ,
51+ expr_ty : impl Fn ( & hir:: Expr < ' tcx > ) -> Ty < ' tcx > + ' a ,
4952 ) -> Self {
50- InlineAsmCtxt { tcx, typing_env, get_operand_ty : Box :: new ( get_operand_ty) }
53+ InlineAsmCtxt {
54+ tcx,
55+ typing_env,
56+ target_features : tcx. asm_target_features ( def_id) ,
57+ expr_ty : Box :: new ( expr_ty) ,
58+ }
59+ }
60+
61+ fn expr_ty ( & self , expr : & hir:: Expr < ' tcx > ) -> Ty < ' tcx > {
62+ ( self . expr_ty ) ( expr)
5163 }
5264
5365 // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
@@ -139,9 +151,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
139151 template : & [ InlineAsmTemplatePiece ] ,
140152 is_input : bool ,
141153 tied_input : Option < ( & ' tcx hir:: Expr < ' tcx > , Option < InlineAsmType > ) > ,
142- target_features : & FxIndexSet < Symbol > ,
143154 ) -> Option < InlineAsmType > {
144- let ty = ( self . get_operand_ty ) ( expr) ;
155+ let ty = self . expr_ty ( expr) ;
145156 if ty. has_non_region_infer ( ) {
146157 bug ! ( "inference variable in asm operand ty: {:?} {:?}" , expr, ty) ;
147158 }
@@ -229,7 +240,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
229240 if let Some ( ( in_expr, Some ( in_asm_ty) ) ) = tied_input {
230241 if in_asm_ty != asm_ty {
231242 let msg = "incompatible types for asm inout argument" ;
232- let in_expr_ty = ( self . get_operand_ty ) ( in_expr) ;
243+ let in_expr_ty = self . expr_ty ( in_expr) ;
233244 self . tcx
234245 . dcx ( )
235246 . struct_span_err ( vec ! [ in_expr. span, expr. span] , msg)
@@ -291,7 +302,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
291302 // (!). In that case we still need the earlier check to verify that the
292303 // register class is usable at all.
293304 if let Some ( feature) = feature {
294- if !target_features. contains ( feature) {
305+ if !self . target_features . contains ( feature) {
295306 let msg = format ! ( "`{feature}` target feature is not enabled" ) ;
296307 self . tcx
297308 . dcx ( )
@@ -351,14 +362,13 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
351362 Some ( asm_ty)
352363 }
353364
354- pub fn check_asm ( & self , asm : & hir:: InlineAsm < ' tcx > , enclosing_id : LocalDefId ) {
355- let target_features = self . tcx . asm_target_features ( enclosing_id. to_def_id ( ) ) ;
365+ pub fn check_asm ( & self , asm : & hir:: InlineAsm < ' tcx > ) {
356366 let Some ( asm_arch) = self . tcx . sess . asm_arch else {
357367 self . tcx . dcx ( ) . delayed_bug ( "target architecture does not support asm" ) ;
358368 return ;
359369 } ;
360370 let allow_experimental_reg = self . tcx . features ( ) . asm_experimental_reg ( ) ;
361- for ( idx, ( op, op_sp) ) in asm. operands . iter ( ) . enumerate ( ) {
371+ for ( idx, & ( op, op_sp) ) in asm. operands . iter ( ) . enumerate ( ) {
362372 // Validate register classes against currently enabled target
363373 // features. We check that at least one type is available for
364374 // the enabled features.
@@ -381,12 +391,12 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
381391 if let Err ( msg) = reg. validate (
382392 asm_arch,
383393 self . tcx . sess . relocation_model ( ) ,
384- target_features,
394+ self . target_features ,
385395 & self . tcx . sess . target ,
386396 op. is_clobber ( ) ,
387397 ) {
388398 let msg = format ! ( "cannot use register `{}`: {}" , reg. name( ) , msg) ;
389- self . tcx . dcx ( ) . span_err ( * op_sp, msg) ;
399+ self . tcx . dcx ( ) . span_err ( op_sp, msg) ;
390400 continue ;
391401 }
392402 }
@@ -401,7 +411,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
401411 {
402412 match feature {
403413 Some ( feature) => {
404- if target_features. contains ( & feature) {
414+ if self . target_features . contains ( & feature) {
405415 missing_required_features. clear ( ) ;
406416 break ;
407417 } else {
@@ -426,7 +436,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
426436 reg_class. name( ) ,
427437 feature
428438 ) ;
429- self . tcx . dcx ( ) . span_err ( * op_sp, msg) ;
439+ self . tcx . dcx ( ) . span_err ( op_sp, msg) ;
430440 // register isn't enabled, don't do more checks
431441 continue ;
432442 }
@@ -440,60 +450,29 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
440450 . intersperse( ", " )
441451 . collect:: <String >( ) ,
442452 ) ;
443- self . tcx . dcx ( ) . span_err ( * op_sp, msg) ;
453+ self . tcx . dcx ( ) . span_err ( op_sp, msg) ;
444454 // register isn't enabled, don't do more checks
445455 continue ;
446456 }
447457 }
448458 }
449459 }
450460
451- match * op {
461+ match op {
452462 hir:: InlineAsmOperand :: In { reg, expr } => {
453- self . check_asm_operand_type (
454- idx,
455- reg,
456- expr,
457- asm. template ,
458- true ,
459- None ,
460- target_features,
461- ) ;
463+ self . check_asm_operand_type ( idx, reg, expr, asm. template , true , None ) ;
462464 }
463465 hir:: InlineAsmOperand :: Out { reg, late : _, expr } => {
464466 if let Some ( expr) = expr {
465- self . check_asm_operand_type (
466- idx,
467- reg,
468- expr,
469- asm. template ,
470- false ,
471- None ,
472- target_features,
473- ) ;
467+ self . check_asm_operand_type ( idx, reg, expr, asm. template , false , None ) ;
474468 }
475469 }
476470 hir:: InlineAsmOperand :: InOut { reg, late : _, expr } => {
477- self . check_asm_operand_type (
478- idx,
479- reg,
480- expr,
481- asm. template ,
482- false ,
483- None ,
484- target_features,
485- ) ;
471+ self . check_asm_operand_type ( idx, reg, expr, asm. template , false , None ) ;
486472 }
487473 hir:: InlineAsmOperand :: SplitInOut { reg, late : _, in_expr, out_expr } => {
488- let in_ty = self . check_asm_operand_type (
489- idx,
490- reg,
491- in_expr,
492- asm. template ,
493- true ,
494- None ,
495- target_features,
496- ) ;
474+ let in_ty =
475+ self . check_asm_operand_type ( idx, reg, in_expr, asm. template , true , None ) ;
497476 if let Some ( out_expr) = out_expr {
498477 self . check_asm_operand_type (
499478 idx,
@@ -502,7 +481,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
502481 asm. template ,
503482 false ,
504483 Some ( ( in_expr, in_ty) ) ,
505- target_features,
506484 ) ;
507485 }
508486 }
0 commit comments