Skip to content

Commit 37060aa

Browse files
Initial cleanups of InlineAsmCtxt
1 parent 2a6daaf commit 37060aa

File tree

3 files changed

+39
-60
lines changed

3 files changed

+39
-60
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
900900
let hir::ItemKind::GlobalAsm { asm } = it.kind else {
901901
span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it)
902902
};
903-
InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, def_id);
903+
InlineAsmCtxt::new_global_asm(tcx, def_id).check_asm(asm);
904904
}
905905
_ => {}
906906
}

compiler/rustc_hir_analysis/src/check/intrinsicck.rs

+34-56
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ use rustc_target::asm::{
1616

1717
use 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

2526
enum NonAsmTypeReason<'tcx> {
@@ -29,14 +30,15 @@ enum NonAsmTypeReason<'tcx> {
2930
}
3031

3132
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 {
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
}

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
101101
debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len());
102102
for (asm, hir_id) in deferred_asm_checks.drain(..) {
103103
let enclosing_id = self.tcx.hir_enclosing_body_owner(hir_id);
104-
let get_operand_ty = |expr| {
104+
let expr_ty = |expr: &hir::Expr<'tcx>| {
105105
let ty = self.typeck_results.borrow().expr_ty_adjusted(expr);
106106
let ty = self.resolve_vars_if_possible(ty);
107107
if ty.has_non_region_infer() {
@@ -113,9 +113,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
113113
InlineAsmCtxt::new_in_fn(
114114
self.tcx,
115115
self.infcx.typing_env(self.param_env),
116-
get_operand_ty,
116+
enclosing_id,
117+
expr_ty,
117118
)
118-
.check_asm(asm, enclosing_id);
119+
.check_asm(asm);
119120
}
120121
}
121122

0 commit comments

Comments
 (0)