@@ -16,10 +16,11 @@ use rustc_target::asm::{
16
16
17
17
use crate :: errors:: RegisterTypeUnstable ;
18
18
19
- pub struct InlineAsmCtxt < ' a , ' tcx > {
19
+ pub struct InlineAsmCtxt < ' a , ' tcx : ' a > {
20
20
tcx : TyCtxt < ' tcx > ,
21
21
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 > ,
23
24
}
24
25
25
26
enum NonAsmTypeReason < ' tcx > {
@@ -29,14 +30,15 @@ enum NonAsmTypeReason<'tcx> {
29
30
}
30
31
31
32
impl < ' 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 {
33
34
InlineAsmCtxt {
34
35
tcx,
35
36
typing_env : ty:: TypingEnv {
36
37
typing_mode : ty:: TypingMode :: non_body_analysis ( ) ,
37
38
param_env : ty:: ParamEnv :: empty ( ) ,
38
39
} ,
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:?}" ) ) ,
40
42
}
41
43
}
42
44
@@ -45,9 +47,19 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
45
47
pub fn new_in_fn (
46
48
tcx : TyCtxt < ' tcx > ,
47
49
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 ,
49
52
) -> 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)
51
63
}
52
64
53
65
// FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
@@ -139,9 +151,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
139
151
template : & [ InlineAsmTemplatePiece ] ,
140
152
is_input : bool ,
141
153
tied_input : Option < ( & ' tcx hir:: Expr < ' tcx > , Option < InlineAsmType > ) > ,
142
- target_features : & FxIndexSet < Symbol > ,
143
154
) -> Option < InlineAsmType > {
144
- let ty = ( self . get_operand_ty ) ( expr) ;
155
+ let ty = self . expr_ty ( expr) ;
145
156
if ty. has_non_region_infer ( ) {
146
157
bug ! ( "inference variable in asm operand ty: {:?} {:?}" , expr, ty) ;
147
158
}
@@ -229,7 +240,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
229
240
if let Some ( ( in_expr, Some ( in_asm_ty) ) ) = tied_input {
230
241
if in_asm_ty != asm_ty {
231
242
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) ;
233
244
self . tcx
234
245
. dcx ( )
235
246
. struct_span_err ( vec ! [ in_expr. span, expr. span] , msg)
@@ -291,7 +302,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
291
302
// (!). In that case we still need the earlier check to verify that the
292
303
// register class is usable at all.
293
304
if let Some ( feature) = feature {
294
- if !target_features. contains ( feature) {
305
+ if !self . target_features . contains ( feature) {
295
306
let msg = format ! ( "`{feature}` target feature is not enabled" ) ;
296
307
self . tcx
297
308
. dcx ( )
@@ -351,14 +362,13 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
351
362
Some ( asm_ty)
352
363
}
353
364
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 > ) {
356
366
let Some ( asm_arch) = self . tcx . sess . asm_arch else {
357
367
self . tcx . dcx ( ) . delayed_bug ( "target architecture does not support asm" ) ;
358
368
return ;
359
369
} ;
360
370
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 ( ) {
362
372
// Validate register classes against currently enabled target
363
373
// features. We check that at least one type is available for
364
374
// the enabled features.
@@ -381,12 +391,12 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
381
391
if let Err ( msg) = reg. validate (
382
392
asm_arch,
383
393
self . tcx . sess . relocation_model ( ) ,
384
- target_features,
394
+ self . target_features ,
385
395
& self . tcx . sess . target ,
386
396
op. is_clobber ( ) ,
387
397
) {
388
398
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) ;
390
400
continue ;
391
401
}
392
402
}
@@ -401,7 +411,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
401
411
{
402
412
match feature {
403
413
Some ( feature) => {
404
- if target_features. contains ( & feature) {
414
+ if self . target_features . contains ( & feature) {
405
415
missing_required_features. clear ( ) ;
406
416
break ;
407
417
} else {
@@ -426,7 +436,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
426
436
reg_class. name( ) ,
427
437
feature
428
438
) ;
429
- self . tcx . dcx ( ) . span_err ( * op_sp, msg) ;
439
+ self . tcx . dcx ( ) . span_err ( op_sp, msg) ;
430
440
// register isn't enabled, don't do more checks
431
441
continue ;
432
442
}
@@ -440,60 +450,29 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
440
450
. intersperse( ", " )
441
451
. collect:: <String >( ) ,
442
452
) ;
443
- self . tcx . dcx ( ) . span_err ( * op_sp, msg) ;
453
+ self . tcx . dcx ( ) . span_err ( op_sp, msg) ;
444
454
// register isn't enabled, don't do more checks
445
455
continue ;
446
456
}
447
457
}
448
458
}
449
459
}
450
460
451
- match * op {
461
+ match op {
452
462
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 ) ;
462
464
}
463
465
hir:: InlineAsmOperand :: Out { reg, late : _, expr } => {
464
466
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 ) ;
474
468
}
475
469
}
476
470
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 ) ;
486
472
}
487
473
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 ) ;
497
476
if let Some ( out_expr) = out_expr {
498
477
self . check_asm_operand_type (
499
478
idx,
@@ -502,7 +481,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
502
481
asm. template ,
503
482
false ,
504
483
Some ( ( in_expr, in_ty) ) ,
505
- target_features,
506
484
) ;
507
485
}
508
486
}
0 commit comments