about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros/src
diff options
context:
space:
mode:
authorFolkert de Vries <folkert@folkertdev.nl>2025-04-29 20:35:39 +0200
committerFolkert de Vries <folkert@folkertdev.nl>2025-05-17 23:06:11 +0200
commit5af9652e5c733eb14c9a28b92c7a2608cbf7ea59 (patch)
treea3e0ee99bffa9baa6d7b279936725f3cb09ada11 /compiler/rustc_builtin_macros/src
parentcd22c1b88385b65d657dedd520abaf1a0aaf7e3f (diff)
downloadrust-5af9652e5c733eb14c9a28b92c7a2608cbf7ea59.tar.gz
rust-5af9652e5c733eb14c9a28b92c7a2608cbf7ea59.zip
extract operand parser
Diffstat (limited to 'compiler/rustc_builtin_macros/src')
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs176
1 files changed, 93 insertions, 83 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 58aba3e5903..3afa2d3dd8e 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -69,6 +69,76 @@ fn parse_args<'a>(
     parse_asm_args(&mut p, sp, asm_macro)
 }
 
+fn parse_asm_operand<'a>(
+    p: &mut Parser<'a>,
+    asm_macro: AsmMacro,
+) -> PResult<'a, Option<ast::InlineAsmOperand>> {
+    let dcx = p.dcx();
+
+    Ok(Some(if eat_operand_keyword(p, exp!(In), asm_macro)? {
+        let reg = parse_reg(p)?;
+        if p.eat_keyword(exp!(Underscore)) {
+            let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
+            return Err(err);
+        }
+        let expr = p.parse_expr()?;
+        ast::InlineAsmOperand::In { reg, expr }
+    } else if eat_operand_keyword(p, exp!(Out), asm_macro)? {
+        let reg = parse_reg(p)?;
+        let expr = if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
+        ast::InlineAsmOperand::Out { reg, expr, late: false }
+    } else if eat_operand_keyword(p, exp!(Lateout), asm_macro)? {
+        let reg = parse_reg(p)?;
+        let expr = if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
+        ast::InlineAsmOperand::Out { reg, expr, late: true }
+    } else if eat_operand_keyword(p, exp!(Inout), asm_macro)? {
+        let reg = parse_reg(p)?;
+        if p.eat_keyword(exp!(Underscore)) {
+            let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
+            return Err(err);
+        }
+        let expr = p.parse_expr()?;
+        if p.eat(exp!(FatArrow)) {
+            let out_expr =
+                if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
+            ast::InlineAsmOperand::SplitInOut { reg, in_expr: expr, out_expr, late: false }
+        } else {
+            ast::InlineAsmOperand::InOut { reg, expr, late: false }
+        }
+    } else if eat_operand_keyword(p, exp!(Inlateout), asm_macro)? {
+        let reg = parse_reg(p)?;
+        if p.eat_keyword(exp!(Underscore)) {
+            let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
+            return Err(err);
+        }
+        let expr = p.parse_expr()?;
+        if p.eat(exp!(FatArrow)) {
+            let out_expr =
+                if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
+            ast::InlineAsmOperand::SplitInOut { reg, in_expr: expr, out_expr, late: true }
+        } else {
+            ast::InlineAsmOperand::InOut { reg, expr, late: true }
+        }
+    } else if eat_operand_keyword(p, exp!(Label), asm_macro)? {
+        let block = p.parse_block()?;
+        ast::InlineAsmOperand::Label { block }
+    } else if p.eat_keyword(exp!(Const)) {
+        let anon_const = p.parse_expr_anon_const()?;
+        ast::InlineAsmOperand::Const { anon_const }
+    } else if p.eat_keyword(exp!(Sym)) {
+        let expr = p.parse_expr()?;
+        let ast::ExprKind::Path(qself, path) = &expr.kind else {
+            let err = dcx.create_err(errors::AsmSymNoPath { span: expr.span });
+            return Err(err);
+        };
+        let sym =
+            ast::InlineAsmSym { id: ast::DUMMY_NODE_ID, qself: qself.clone(), path: path.clone() };
+        ast::InlineAsmOperand::Sym { sym }
+    } else {
+        return Ok(None);
+    }))
+}
+
 // Primarily public for rustfmt consumption.
 // Internal consumers should continue to leverage `expand_asm`/`expand__global_asm`
 pub fn parse_asm_args<'a>(
@@ -135,91 +205,31 @@ pub fn parse_asm_args<'a>(
             None
         };
 
-        let op = if eat_operand_keyword(p, exp!(In), asm_macro)? {
-            let reg = parse_reg(p)?;
-            if p.eat_keyword(exp!(Underscore)) {
-                let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
-                return Err(err);
-            }
-            let expr = p.parse_expr()?;
-            ast::InlineAsmOperand::In { reg, expr }
-        } else if eat_operand_keyword(p, exp!(Out), asm_macro)? {
-            let reg = parse_reg(p)?;
-            let expr = if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
-            ast::InlineAsmOperand::Out { reg, expr, late: false }
-        } else if eat_operand_keyword(p, exp!(Lateout), asm_macro)? {
-            let reg = parse_reg(p)?;
-            let expr = if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
-            ast::InlineAsmOperand::Out { reg, expr, late: true }
-        } else if eat_operand_keyword(p, exp!(Inout), asm_macro)? {
-            let reg = parse_reg(p)?;
-            if p.eat_keyword(exp!(Underscore)) {
-                let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
-                return Err(err);
-            }
-            let expr = p.parse_expr()?;
-            if p.eat(exp!(FatArrow)) {
-                let out_expr =
-                    if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
-                ast::InlineAsmOperand::SplitInOut { reg, in_expr: expr, out_expr, late: false }
-            } else {
-                ast::InlineAsmOperand::InOut { reg, expr, late: false }
-            }
-        } else if eat_operand_keyword(p, exp!(Inlateout), asm_macro)? {
-            let reg = parse_reg(p)?;
-            if p.eat_keyword(exp!(Underscore)) {
-                let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
-                return Err(err);
-            }
-            let expr = p.parse_expr()?;
-            if p.eat(exp!(FatArrow)) {
-                let out_expr =
-                    if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
-                ast::InlineAsmOperand::SplitInOut { reg, in_expr: expr, out_expr, late: true }
-            } else {
-                ast::InlineAsmOperand::InOut { reg, expr, late: true }
-            }
-        } else if eat_operand_keyword(p, exp!(Label), asm_macro)? {
-            let block = p.parse_block()?;
-            ast::InlineAsmOperand::Label { block }
-        } else if p.eat_keyword(exp!(Const)) {
-            let anon_const = p.parse_expr_anon_const()?;
-            ast::InlineAsmOperand::Const { anon_const }
-        } else if p.eat_keyword(exp!(Sym)) {
-            let expr = p.parse_expr()?;
-            let ast::ExprKind::Path(qself, path) = &expr.kind else {
-                let err = dcx.create_err(errors::AsmSymNoPath { span: expr.span });
-                return Err(err);
-            };
-            let sym = ast::InlineAsmSym {
-                id: ast::DUMMY_NODE_ID,
-                qself: qself.clone(),
-                path: path.clone(),
-            };
-            ast::InlineAsmOperand::Sym { sym }
-        } else if allow_templates {
-            let template = p.parse_expr()?;
-            // If it can't possibly expand to a string, provide diagnostics here to include other
-            // things it could have been.
-            match template.kind {
-                ast::ExprKind::Lit(token_lit)
-                    if matches!(
-                        token_lit.kind,
-                        token::LitKind::Str | token::LitKind::StrRaw(_)
-                    ) => {}
-                ast::ExprKind::MacCall(..) => {}
-                _ => {
-                    let err = dcx.create_err(errors::AsmExpectedOther {
-                        span: template.span,
-                        is_inline_asm: matches!(asm_macro, AsmMacro::Asm),
-                    });
-                    return Err(err);
+        let Some(op) = parse_asm_operand(p, asm_macro)? else {
+            if allow_templates {
+                let template = p.parse_expr()?;
+                // If it can't possibly expand to a string, provide diagnostics here to include other
+                // things it could have been.
+                match template.kind {
+                    ast::ExprKind::Lit(token_lit)
+                        if matches!(
+                            token_lit.kind,
+                            token::LitKind::Str | token::LitKind::StrRaw(_)
+                        ) => {}
+                    ast::ExprKind::MacCall(..) => {}
+                    _ => {
+                        let err = dcx.create_err(errors::AsmExpectedOther {
+                            span: template.span,
+                            is_inline_asm: matches!(asm_macro, AsmMacro::Asm),
+                        });
+                        return Err(err);
+                    }
                 }
+                args.templates.push(template);
+                continue;
+            } else {
+                p.unexpected_any()?
             }
-            args.templates.push(template);
-            continue;
-        } else {
-            p.unexpected_any()?
         };
 
         let explicit_reg = matches!(op.reg(), Some(ast::InlineAsmRegOrRegClass::Reg(_)));