mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
fix: Don't report typed hole error in asm! out ops
This commit is contained in:
parent
77e1969c15
commit
6daa6d59f3
2 changed files with 70 additions and 29 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}"#,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue