Skip to content

Commit c075a99

Browse files
committed
Fix name fetching being incorrect for asm operands
1 parent 564926a commit c075a99

File tree

10 files changed

+107
-93
lines changed

10 files changed

+107
-93
lines changed

crates/hir-def/src/body.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub struct BodySourceMap {
105105
// format_args!
106106
FxHashMap<ExprId, Vec<(syntax::TextRange, Name)>>,
107107
// asm!
108-
FxHashMap<ExprId, Vec<(syntax::TextRange, usize, Option<Name>)>>,
108+
FxHashMap<ExprId, Vec<(syntax::TextRange, usize)>>,
109109
)>,
110110
>,
111111

@@ -439,7 +439,7 @@ impl BodySourceMap {
439439
pub fn asm_template_args(
440440
&self,
441441
node: InFile<&ast::AsmExpr>,
442-
) -> Option<(ExprId, &[(syntax::TextRange, usize, Option<Name>)])> {
442+
) -> Option<(ExprId, &[(syntax::TextRange, usize)])> {
443443
let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>);
444444
let expr = self.expr_map.get(&src)?;
445445
Some(*expr).zip(self.template_map.as_ref()?.1.get(expr).map(std::ops::Deref::deref))
@@ -487,7 +487,7 @@ impl BodySourceMap {
487487
&self,
488488
) -> Option<&(
489489
FxHashMap<Idx<Expr>, Vec<(tt::TextRange, Name)>>,
490-
FxHashMap<Idx<Expr>, Vec<(tt::TextRange, usize, Option<Name>)>>,
490+
FxHashMap<Idx<Expr>, Vec<(tt::TextRange, usize)>>,
491491
)> {
492492
self.template_map.as_deref()
493493
}

crates/hir-def/src/body/lower/asm.rs

Lines changed: 81 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -65,80 +65,89 @@ impl ExprCollector<'_> {
6565
continue;
6666
}
6767
ast::AsmPiece::AsmOperandNamed(op) => {
68-
if let Some(name) = op.name() {
69-
let sym = Symbol::intern(&name.text());
70-
named_args.insert(sym.clone(), slot);
71-
named_pos.insert(slot, sym);
68+
let name = op.name().map(|name| Symbol::intern(&name.text()));
69+
if let Some(name) = &name {
70+
named_args.insert(name.clone(), slot);
71+
named_pos.insert(slot, name.clone());
7272
}
7373
let Some(op) = op.asm_operand() else { continue };
74-
match op {
75-
ast::AsmOperand::AsmRegOperand(op) => {
76-
let Some(dir_spec) = op.asm_dir_spec() else {
77-
continue;
78-
};
79-
let Some(reg) = lower_reg(op.asm_reg_spec()) else {
80-
continue;
81-
};
82-
if dir_spec.in_token().is_some() {
83-
let expr = self.collect_expr_opt(
84-
op.asm_operand_expr().and_then(|it| it.in_expr()),
85-
);
86-
AsmOperand::In { reg, expr }
87-
} else if dir_spec.out_token().is_some() {
88-
let expr = self.collect_expr_opt(
89-
op.asm_operand_expr().and_then(|it| it.in_expr()),
90-
);
91-
AsmOperand::Out { reg, expr: Some(expr), late: false }
92-
} else if dir_spec.lateout_token().is_some() {
93-
let expr = self.collect_expr_opt(
94-
op.asm_operand_expr().and_then(|it| it.in_expr()),
95-
);
96-
AsmOperand::Out { reg, expr: Some(expr), late: true }
97-
} else if dir_spec.inout_token().is_some() {
98-
let Some(op_expr) = op.asm_operand_expr() else { continue };
99-
let in_expr = self.collect_expr_opt(op_expr.in_expr());
100-
let out_expr = op_expr.out_expr().map(|it| self.collect_expr(it));
101-
match out_expr {
102-
Some(out_expr) => AsmOperand::SplitInOut {
103-
reg,
104-
in_expr,
105-
out_expr: Some(out_expr),
106-
late: false,
107-
},
108-
None => AsmOperand::InOut { reg, expr: in_expr, late: false },
109-
}
110-
} else if dir_spec.inlateout_token().is_some() {
111-
let Some(op_expr) = op.asm_operand_expr() else { continue };
112-
let in_expr = self.collect_expr_opt(op_expr.in_expr());
113-
let out_expr = op_expr.out_expr().map(|it| self.collect_expr(it));
114-
match out_expr {
115-
Some(out_expr) => AsmOperand::SplitInOut {
116-
reg,
117-
in_expr,
118-
out_expr: Some(out_expr),
119-
late: false,
120-
},
121-
None => AsmOperand::InOut { reg, expr: in_expr, late: false },
74+
(
75+
name.map(Name::new_symbol_root),
76+
match op {
77+
ast::AsmOperand::AsmRegOperand(op) => {
78+
let Some(dir_spec) = op.asm_dir_spec() else {
79+
continue;
80+
};
81+
let Some(reg) = lower_reg(op.asm_reg_spec()) else {
82+
continue;
83+
};
84+
if dir_spec.in_token().is_some() {
85+
let expr = self.collect_expr_opt(
86+
op.asm_operand_expr().and_then(|it| it.in_expr()),
87+
);
88+
AsmOperand::In { reg, expr }
89+
} 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 }
94+
} 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 }
99+
} else if dir_spec.inout_token().is_some() {
100+
let Some(op_expr) = op.asm_operand_expr() else { continue };
101+
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 => {
112+
AsmOperand::InOut { reg, expr: in_expr, late: false }
113+
}
114+
}
115+
} else if dir_spec.inlateout_token().is_some() {
116+
let Some(op_expr) = op.asm_operand_expr() else { continue };
117+
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 }
129+
}
130+
}
131+
} else {
132+
continue;
122133
}
123-
} else {
124-
continue;
125134
}
126-
}
127-
ast::AsmOperand::AsmLabel(l) => {
128-
AsmOperand::Label(self.collect_block_opt(l.block_expr()))
129-
}
130-
ast::AsmOperand::AsmConst(c) => {
131-
AsmOperand::Const(self.collect_expr_opt(c.expr()))
132-
}
133-
ast::AsmOperand::AsmSym(s) => {
134-
let Some(path) =
135-
s.path().and_then(|p| self.expander.parse_path(self.db, p))
136-
else {
137-
continue;
138-
};
139-
AsmOperand::Sym(path)
140-
}
141-
}
135+
ast::AsmOperand::AsmLabel(l) => {
136+
AsmOperand::Label(self.collect_block_opt(l.block_expr()))
137+
}
138+
ast::AsmOperand::AsmConst(c) => {
139+
AsmOperand::Const(self.collect_expr_opt(c.expr()))
140+
}
141+
ast::AsmOperand::AsmSym(s) => {
142+
let Some(path) =
143+
s.path().and_then(|p| self.expander.parse_path(self.db, p))
144+
else {
145+
continue;
146+
};
147+
AsmOperand::Sym(path)
148+
}
149+
},
150+
)
142151
}
143152
};
144153
operands.push(op);
@@ -204,7 +213,7 @@ impl ExprCollector<'_> {
204213
rustc_parse_format::Piece::NextArgument(arg) => {
205214
// let span = arg_spans.next();
206215

207-
let (operand_idx, name) = match arg.position {
216+
let (operand_idx, _name) = match arg.position {
208217
rustc_parse_format::ArgumentIs(idx)
209218
| rustc_parse_format::ArgumentImplicitlyIs(idx) => {
210219
if idx >= operands.len()
@@ -227,7 +236,7 @@ impl ExprCollector<'_> {
227236

228237
if let Some(operand_idx) = operand_idx {
229238
if let Some(position_span) = to_span(arg.position_span) {
230-
mappings.push((position_span, operand_idx, name));
239+
mappings.push((position_span, operand_idx));
231240
}
232241
}
233242
}

crates/hir-def/src/hir.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ pub struct OffsetOf {
307307

308308
#[derive(Debug, Clone, PartialEq, Eq)]
309309
pub struct InlineAsm {
310-
pub operands: Box<[AsmOperand]>,
310+
pub operands: Box<[(Option<Name>, AsmOperand)]>,
311311
pub options: AsmOptions,
312312
}
313313

@@ -485,7 +485,7 @@ impl Expr {
485485
match self {
486486
Expr::Missing => {}
487487
Expr::Path(_) | Expr::OffsetOf(_) => {}
488-
Expr::InlineAsm(it) => it.operands.iter().for_each(|op| match op {
488+
Expr::InlineAsm(it) => it.operands.iter().for_each(|(_, op)| match op {
489489
AsmOperand::In { expr, .. }
490490
| AsmOperand::Out { expr: Some(expr), .. }
491491
| AsmOperand::InOut { expr, .. } => f(*expr),

crates/hir-ty/src/infer/closure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ impl InferenceContext<'_> {
669669
fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) {
670670
match &self.body[tgt_expr] {
671671
Expr::OffsetOf(_) => (),
672-
Expr::InlineAsm(e) => e.operands.iter().for_each(|op| match op {
672+
Expr::InlineAsm(e) => e.operands.iter().for_each(|(_, op)| match op {
673673
AsmOperand::In { expr, .. }
674674
| AsmOperand::Out { expr: Some(expr), .. }
675675
| AsmOperand::InOut { expr, .. } => self.walk_expr_without_adjust(*expr),

crates/hir-ty/src/infer/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ impl InferenceContext<'_> {
956956
};
957957

958958
let diverge = asm.options.contains(AsmOptions::NORETURN);
959-
asm.operands.iter().for_each(|operand| match *operand {
959+
asm.operands.iter().for_each(|(_, operand)| match *operand {
960960
AsmOperand::In { expr, .. } => check_expr_asm_operand(expr, true),
961961
AsmOperand::Out { expr: Some(expr), .. } | AsmOperand::InOut { expr, .. } => {
962962
check_expr_asm_operand(expr, false)

crates/hir-ty/src/infer/mutability.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl InferenceContext<'_> {
4242
match &self.body[tgt_expr] {
4343
Expr::Missing => (),
4444
Expr::InlineAsm(e) => {
45-
e.operands.iter().for_each(|op| match op {
45+
e.operands.iter().for_each(|(_, op)| match op {
4646
AsmOperand::In { expr, .. }
4747
| AsmOperand::Out { expr: Some(expr), .. }
4848
| AsmOperand::InOut { expr, .. } => {

crates/hir/src/lib.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5259,13 +5259,10 @@ impl InlineAsmOperand {
52595259
}
52605260

52615261
pub fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
5262-
db.body_with_source_map(self.owner)
5263-
.1
5264-
.template_map()?
5265-
.1
5266-
.get(&self.expr)?
5267-
.get(self.index)
5268-
.and_then(|(_, _, name)| name.clone())
5262+
match &db.body(self.owner)[self.expr] {
5263+
hir_def::hir::Expr::InlineAsm(e) => e.operands.get(self.index)?.0.clone(),
5264+
_ => None,
5265+
}
52695266
}
52705267
}
52715268

crates/hir/src/semantics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ impl<'db> SemanticsImpl<'db> {
576576
let (owner, (expr, asm_parts)) = source_analyzer.as_asm_parts(asm.as_ref())?;
577577
let res = asm_parts
578578
.iter()
579-
.map(|&(range, index, _)| {
579+
.map(|&(range, index)| {
580580
(
581581
range + quote.end(),
582582
Some(Either::Right(InlineAsmOperand { owner, expr, index })),

crates/hir/src/source_analyzer.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -913,8 +913,8 @@ impl SourceAnalyzer {
913913
let (expr, args) = body_source_map.asm_template_args(asm)?;
914914
Some(*def).zip(
915915
args.iter()
916-
.find(|(range, _, _)| range.contains_inclusive(offset))
917-
.map(|(range, idx, _)| (expr, *range, *idx)),
916+
.find(|(range, _)| range.contains_inclusive(offset))
917+
.map(|(range, idx)| (expr, *range, *idx)),
918918
)
919919
}
920920

@@ -944,7 +944,7 @@ impl SourceAnalyzer {
944944
pub(crate) fn as_asm_parts(
945945
&self,
946946
asm: InFile<&ast::AsmExpr>,
947-
) -> Option<(DefWithBodyId, (ExprId, &[(TextRange, usize, Option<Name>)]))> {
947+
) -> Option<(DefWithBodyId, (ExprId, &[(TextRange, usize)]))> {
948948
let (def, _, body_source_map) = self.def.as_ref()?;
949949
Some(*def).zip(body_source_map.asm_template_args(asm))
950950
}

crates/ide/src/rename.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3008,15 +3008,23 @@ fn test() {
30083008
fn test() {
30093009
core::arch::asm!(
30103010
"push {base$0}",
3011-
base = const 0
3011+
"push {base}",
3012+
boo = const 0,
3013+
virtual_free = sym VIRTUAL_FREE,
3014+
base = const 0,
3015+
boo = const 0,
30123016
);
30133017
}
30143018
"#,
30153019
r#"
30163020
fn test() {
30173021
core::arch::asm!(
30183022
"push {bose}",
3019-
bose = const 0
3023+
"push {bose}",
3024+
boo = const 0,
3025+
virtual_free = sym VIRTUAL_FREE,
3026+
bose = const 0,
3027+
boo = const 0,
30203028
);
30213029
}
30223030
"#,

0 commit comments

Comments
 (0)