Skip to content

Commit

Permalink
fix: Don't report typed hole error in asm! out ops
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Sep 12, 2024
1 parent 91e9cd3 commit 4361c1b
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 29 deletions.
77 changes: 48 additions & 29 deletions src/tools/rust-analyzer/crates/hir-def/src/body/lower/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}"#,
);
}
}

0 comments on commit 4361c1b

Please sign in to comment.