Skip to content

Commit 8cd0a27

Browse files
committed
Auto merge of rust-lang#18106 - Veykril:push-yzsqoykyowts, r=Veykril
fix: Don't report typed hole error in asm! out ops Fixes rust-lang/rust-analyzer#18103
2 parents 628a3d7 + 4361c1b commit 8cd0a27

File tree

2 files changed

+70
-29
lines changed
  • src/tools/rust-analyzer/crates

2 files changed

+70
-29
lines changed

src/tools/rust-analyzer/crates/hir-def/src/body/lower/asm.rs

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -87,45 +87,64 @@ impl ExprCollector<'_> {
8787
);
8888
AsmOperand::In { reg, expr }
8989
} else if dir_spec.out_token().is_some() {
90-
let expr = self.collect_expr_opt(
91-
op.asm_operand_expr().and_then(|it| it.in_expr()),
92-
);
93-
AsmOperand::Out { reg, expr: Some(expr), late: false }
90+
let expr = op
91+
.asm_operand_expr()
92+
.and_then(|it| it.in_expr())
93+
.filter(|it| !matches!(it, ast::Expr::UnderscoreExpr(_)))
94+
.map(|expr| self.collect_expr(expr));
95+
AsmOperand::Out { reg, expr, late: false }
9496
} else if dir_spec.lateout_token().is_some() {
95-
let expr = self.collect_expr_opt(
96-
op.asm_operand_expr().and_then(|it| it.in_expr()),
97-
);
98-
AsmOperand::Out { reg, expr: Some(expr), late: true }
97+
let expr = op
98+
.asm_operand_expr()
99+
.and_then(|it| it.in_expr())
100+
.filter(|it| !matches!(it, ast::Expr::UnderscoreExpr(_)))
101+
.map(|expr| self.collect_expr(expr));
102+
103+
AsmOperand::Out { reg, expr, late: true }
99104
} else if dir_spec.inout_token().is_some() {
100105
let Some(op_expr) = op.asm_operand_expr() else { continue };
101106
let in_expr = self.collect_expr_opt(op_expr.in_expr());
102-
let out_expr =
103-
op_expr.out_expr().map(|it| self.collect_expr(it));
104-
match out_expr {
105-
Some(out_expr) => AsmOperand::SplitInOut {
106-
reg,
107-
in_expr,
108-
out_expr: Some(out_expr),
109-
late: false,
110-
},
111-
None => {
107+
match op_expr.fat_arrow_token().is_some() {
108+
true => {
109+
let out_expr = op_expr
110+
.out_expr()
111+
.filter(|it| {
112+
!matches!(it, ast::Expr::UnderscoreExpr(_))
113+
})
114+
.map(|expr| self.collect_expr(expr));
115+
116+
AsmOperand::SplitInOut {
117+
reg,
118+
in_expr,
119+
out_expr,
120+
late: false,
121+
}
122+
}
123+
false => {
112124
AsmOperand::InOut { reg, expr: in_expr, late: false }
113125
}
114126
}
115127
} else if dir_spec.inlateout_token().is_some() {
116128
let Some(op_expr) = op.asm_operand_expr() else { continue };
117129
let in_expr = self.collect_expr_opt(op_expr.in_expr());
118-
let out_expr =
119-
op_expr.out_expr().map(|it| self.collect_expr(it));
120-
match out_expr {
121-
Some(out_expr) => AsmOperand::SplitInOut {
122-
reg,
123-
in_expr,
124-
out_expr: Some(out_expr),
125-
late: false,
126-
},
127-
None => {
128-
AsmOperand::InOut { reg, expr: in_expr, late: false }
130+
match op_expr.fat_arrow_token().is_some() {
131+
true => {
132+
let out_expr = op_expr
133+
.out_expr()
134+
.filter(|it| {
135+
!matches!(it, ast::Expr::UnderscoreExpr(_))
136+
})
137+
.map(|expr| self.collect_expr(expr));
138+
139+
AsmOperand::SplitInOut {
140+
reg,
141+
in_expr,
142+
out_expr,
143+
late: true,
144+
}
145+
}
146+
false => {
147+
AsmOperand::InOut { reg, expr: in_expr, late: true }
129148
}
130149
}
131150
} else {

src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,4 +402,26 @@ fn f() {
402402
],
403403
);
404404
}
405+
406+
#[test]
407+
fn underscore_in_asm() {
408+
check_diagnostics(
409+
r#"
410+
//- minicore: asm
411+
fn rdtscp() -> u64 {
412+
let hi: u64;
413+
let lo: u64;
414+
unsafe {
415+
core::arch::asm!(
416+
"rdtscp",
417+
out("rdx") hi,
418+
out("rax") lo,
419+
out("rcx") _,
420+
options(nomem, nostack, preserves_flags)
421+
);
422+
}
423+
(hi << 32) | lo
424+
}"#,
425+
);
426+
}
405427
}

0 commit comments

Comments
 (0)