diff options
| author | George Wort <george.wort@arm.com> | 2023-11-28 10:25:22 +0000 |
|---|---|---|
| committer | George Wort <george.wort@arm.com> | 2023-11-28 10:37:19 +0000 |
| commit | e0bfb615da4f48e08f0c86e1ce0e9af765d603fb (patch) | |
| tree | 287b8649b558f5b491512de504ef622e233be17b /compiler | |
| parent | a6b8ae582a89321e24ea942d9c3eb73229809487 (diff) | |
| download | rust-e0bfb615da4f48e08f0c86e1ce0e9af765d603fb.tar.gz rust-e0bfb615da4f48e08f0c86e1ce0e9af765d603fb.zip | |
Name explicit registers in conflict register errors for inline assembly
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/asm.rs | 21 |
2 files changed, 27 insertions, 6 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 83fe95f16f9..b9d959ab605 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2237,6 +2237,18 @@ pub enum InlineAsmOperand { }, } +impl InlineAsmOperand { + pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> { + match self { + Self::In { reg, .. } + | Self::Out { reg, .. } + | Self::InOut { reg, .. } + | Self::SplitInOut { reg, .. } => Some(reg), + Self::Const { .. } | Self::Sym { .. } => None, + } + } +} + /// Inline assembly. /// /// E.g., `asm!("NOP");`. diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index a1e62699680..d0198615388 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -353,10 +353,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let idx2 = *o.get(); let (ref op2, op_sp2) = operands[idx2]; - let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg() - else { - unreachable!(); - }; let in_out = match (op, op2) { ( @@ -374,11 +370,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { _ => None, }; + let reg_str = |idx| -> &str { + // HIR asm doesn't preserve the original alias string of the explicit register, + // so we have to retrieve it from AST + let (op, _): &(InlineAsmOperand, Span) = &asm.operands[idx]; + if let Some(ast::InlineAsmRegOrRegClass::Reg(reg_sym)) = + op.reg() + { + reg_sym.as_str() + } else { + unreachable!(); + } + }; + sess.emit_err(RegisterConflict { op_span1: op_sp, op_span2: op_sp2, - reg1_name: reg.name(), - reg2_name: reg2.name(), + reg1_name: reg_str(idx), + reg2_name: reg_str(idx2), in_out, }); } |
