about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorGeorge Wort <george.wort@arm.com>2023-11-28 10:25:22 +0000
committerGeorge Wort <george.wort@arm.com>2023-11-28 10:37:19 +0000
commite0bfb615da4f48e08f0c86e1ce0e9af765d603fb (patch)
tree287b8649b558f5b491512de504ef622e233be17b /compiler
parenta6b8ae582a89321e24ea942d9c3eb73229809487 (diff)
downloadrust-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.rs12
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs21
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,
                                     });
                                 }