Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #18106 - Veykril:push-yzsqoykyowts, r=Veykril
fix: Don't report typed hole error in asm! out ops Fixes https://github.com/rust-lang/rust-analyzer/issues/18103
bors 2024-09-12
parent 772acef · parent 6daa6d5 · commit 58418ab
-rw-r--r--crates/hir-def/src/body/lower/asm.rs77
-rw-r--r--crates/ide-diagnostics/src/handlers/typed_hole.rs22
2 files changed, 70 insertions, 29 deletions
diff --git a/crates/hir-def/src/body/lower/asm.rs b/crates/hir-def/src/body/lower/asm.rs
index 448bc2f033..4213370ac1 100644
--- a/crates/hir-def/src/body/lower/asm.rs
+++ b/crates/hir-def/src/body/lower/asm.rs
@@ -87,45 +87,64 @@ impl ExprCollector<'_> {
);
AsmOperand::In { reg, expr }
} else if dir_spec.out_token().is_some() {
- let expr = self.collect_expr_opt(
- op.asm_operand_expr().and_then(|it| it.in_expr()),
- );
- AsmOperand::Out { reg, expr: Some(expr), late: false }
+ let expr = op
+ .asm_operand_expr()
+ .and_then(|it| it.in_expr())
+ .filter(|it| !matches!(it, ast::Expr::UnderscoreExpr(_)))
+ .map(|expr| self.collect_expr(expr));
+ AsmOperand::Out { reg, expr, late: false }
} else if dir_spec.lateout_token().is_some() {
- let expr = self.collect_expr_opt(
- op.asm_operand_expr().and_then(|it| it.in_expr()),
- );
- AsmOperand::Out { reg, expr: Some(expr), late: true }
+ let expr = op
+ .asm_operand_expr()
+ .and_then(|it| it.in_expr())
+ .filter(|it| !matches!(it, ast::Expr::UnderscoreExpr(_)))
+ .map(|expr| self.collect_expr(expr));
+
+ AsmOperand::Out { reg, expr, late: true }
} else if dir_spec.inout_token().is_some() {
let Some(op_expr) = op.asm_operand_expr() else { continue };
let in_expr = self.collect_expr_opt(op_expr.in_expr());
- let out_expr =
- op_expr.out_expr().map(|it| self.collect_expr(it));
- match out_expr {
- Some(out_expr) => AsmOperand::SplitInOut {
- reg,
- in_expr,
- out_expr: Some(out_expr),
- late: false,
- },
- None => {
+ match op_expr.fat_arrow_token().is_some() {
+ true => {
+ let out_expr = op_expr
+ .out_expr()
+ .filter(|it| {
+ !matches!(it, ast::Expr::UnderscoreExpr(_))
+ })
+ .map(|expr| self.collect_expr(expr));
+
+ AsmOperand::SplitInOut {
+ reg,
+ in_expr,
+ out_expr,
+ late: false,
+ }
+ }
+ false => {
AsmOperand::InOut { reg, expr: in_expr, late: false }
}
}
} else if dir_spec.inlateout_token().is_some() {
let Some(op_expr) = op.asm_operand_expr() else { continue };
let in_expr = self.collect_expr_opt(op_expr.in_expr());
- let out_expr =
- op_expr.out_expr().map(|it| self.collect_expr(it));
- match out_expr {
- Some(out_expr) => AsmOperand::SplitInOut {
- reg,
- in_expr,
- out_expr: Some(out_expr),
- late: false,
- },
- None => {
- AsmOperand::InOut { reg, expr: in_expr, late: false }
+ match op_expr.fat_arrow_token().is_some() {
+ true => {
+ let out_expr = op_expr
+ .out_expr()
+ .filter(|it| {
+ !matches!(it, ast::Expr::UnderscoreExpr(_))
+ })
+ .map(|expr| self.collect_expr(expr));
+
+ AsmOperand::SplitInOut {
+ reg,
+ in_expr,
+ out_expr,
+ late: true,
+ }
+ }
+ false => {
+ AsmOperand::InOut { reg, expr: in_expr, late: true }
}
}
} else {
diff --git a/crates/ide-diagnostics/src/handlers/typed_hole.rs b/crates/ide-diagnostics/src/handlers/typed_hole.rs
index b5c242e1e9..6994a7ed14 100644
--- a/crates/ide-diagnostics/src/handlers/typed_hole.rs
+++ b/crates/ide-diagnostics/src/handlers/typed_hole.rs
@@ -402,4 +402,26 @@ fn f() {
],
);
}
+
+ #[test]
+ fn underscore_in_asm() {
+ check_diagnostics(
+ r#"
+//- minicore: asm
+fn rdtscp() -> u64 {
+ let hi: u64;
+ let lo: u64;
+ unsafe {
+ core::arch::asm!(
+ "rdtscp",
+ out("rdx") hi,
+ out("rax") lo,
+ out("rcx") _,
+ options(nomem, nostack, preserves_flags)
+ );
+ }
+ (hi << 32) | lo
+}"#,
+ );
+ }
}