diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs index af972c9246..34db43939a 100644 --- a/crates/hir-def/src/body.rs +++ b/crates/hir-def/src/body.rs @@ -105,7 +105,7 @@ pub struct BodySourceMap { // format_args! FxHashMap>, // asm! - FxHashMap)>>, + FxHashMap>, )>, >, @@ -439,7 +439,7 @@ impl BodySourceMap { pub fn asm_template_args( &self, node: InFile<&ast::AsmExpr>, - ) -> Option<(ExprId, &[(syntax::TextRange, usize, Option)])> { + ) -> Option<(ExprId, &[(syntax::TextRange, usize)])> { let src = node.map(AstPtr::new).map(AstPtr::upcast::); let expr = self.expr_map.get(&src)?; Some(*expr).zip(self.template_map.as_ref()?.1.get(expr).map(std::ops::Deref::deref)) @@ -487,7 +487,7 @@ impl BodySourceMap { &self, ) -> Option<&( FxHashMap, Vec<(tt::TextRange, Name)>>, - FxHashMap, Vec<(tt::TextRange, usize, Option)>>, + FxHashMap, Vec<(tt::TextRange, usize)>>, )> { self.template_map.as_deref() } diff --git a/crates/hir-def/src/body/lower/asm.rs b/crates/hir-def/src/body/lower/asm.rs index 300935db49..bf6ba41482 100644 --- a/crates/hir-def/src/body/lower/asm.rs +++ b/crates/hir-def/src/body/lower/asm.rs @@ -65,80 +65,89 @@ impl ExprCollector<'_> { continue; } ast::AsmPiece::AsmOperandNamed(op) => { - if let Some(name) = op.name() { - let sym = Symbol::intern(&name.text()); - named_args.insert(sym.clone(), slot); - named_pos.insert(slot, sym); + let name = op.name().map(|name| Symbol::intern(&name.text())); + if let Some(name) = &name { + named_args.insert(name.clone(), slot); + named_pos.insert(slot, name.clone()); } let Some(op) = op.asm_operand() else { continue }; - match op { - ast::AsmOperand::AsmRegOperand(op) => { - let Some(dir_spec) = op.asm_dir_spec() else { - continue; - }; - let Some(reg) = lower_reg(op.asm_reg_spec()) else { - continue; - }; - if dir_spec.in_token().is_some() { - let expr = self.collect_expr_opt( - op.asm_operand_expr().and_then(|it| it.in_expr()), - ); - 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 } - } 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 } - } 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 => AsmOperand::InOut { reg, expr: in_expr, late: false }, + ( + name.map(Name::new_symbol_root), + match op { + ast::AsmOperand::AsmRegOperand(op) => { + let Some(dir_spec) = op.asm_dir_spec() else { + continue; + }; + let Some(reg) = lower_reg(op.asm_reg_spec()) else { + continue; + }; + if dir_spec.in_token().is_some() { + let expr = self.collect_expr_opt( + op.asm_operand_expr().and_then(|it| it.in_expr()), + ); + 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 } + } 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 } + } 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 => { + 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 } + } + } + } else { + continue; } - } 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 }, - } - } else { - continue; } - } - ast::AsmOperand::AsmLabel(l) => { - AsmOperand::Label(self.collect_block_opt(l.block_expr())) - } - ast::AsmOperand::AsmConst(c) => { - AsmOperand::Const(self.collect_expr_opt(c.expr())) - } - ast::AsmOperand::AsmSym(s) => { - let Some(path) = - s.path().and_then(|p| self.expander.parse_path(self.db, p)) - else { - continue; - }; - AsmOperand::Sym(path) - } - } + ast::AsmOperand::AsmLabel(l) => { + AsmOperand::Label(self.collect_block_opt(l.block_expr())) + } + ast::AsmOperand::AsmConst(c) => { + AsmOperand::Const(self.collect_expr_opt(c.expr())) + } + ast::AsmOperand::AsmSym(s) => { + let Some(path) = + s.path().and_then(|p| self.expander.parse_path(self.db, p)) + else { + continue; + }; + AsmOperand::Sym(path) + } + }, + ) } }; operands.push(op); @@ -204,7 +213,7 @@ impl ExprCollector<'_> { rustc_parse_format::Piece::NextArgument(arg) => { // let span = arg_spans.next(); - let (operand_idx, name) = match arg.position { + let (operand_idx, _name) = match arg.position { rustc_parse_format::ArgumentIs(idx) | rustc_parse_format::ArgumentImplicitlyIs(idx) => { if idx >= operands.len() @@ -227,7 +236,7 @@ impl ExprCollector<'_> { if let Some(operand_idx) = operand_idx { if let Some(position_span) = to_span(arg.position_span) { - mappings.push((position_span, operand_idx, name)); + mappings.push((position_span, operand_idx)); } } } diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs index 7d2c573ebf..d9358a2882 100644 --- a/crates/hir-def/src/hir.rs +++ b/crates/hir-def/src/hir.rs @@ -307,7 +307,7 @@ pub struct OffsetOf { #[derive(Debug, Clone, PartialEq, Eq)] pub struct InlineAsm { - pub operands: Box<[AsmOperand]>, + pub operands: Box<[(Option, AsmOperand)]>, pub options: AsmOptions, } @@ -485,7 +485,7 @@ impl Expr { match self { Expr::Missing => {} Expr::Path(_) | Expr::OffsetOf(_) => {} - Expr::InlineAsm(it) => it.operands.iter().for_each(|op| match op { + Expr::InlineAsm(it) => it.operands.iter().for_each(|(_, op)| match op { AsmOperand::In { expr, .. } | AsmOperand::Out { expr: Some(expr), .. } | AsmOperand::InOut { expr, .. } => f(*expr), diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index 3ad330c1a0..5cad08b939 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -669,7 +669,7 @@ impl InferenceContext<'_> { fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) { match &self.body[tgt_expr] { Expr::OffsetOf(_) => (), - Expr::InlineAsm(e) => e.operands.iter().for_each(|op| match op { + Expr::InlineAsm(e) => e.operands.iter().for_each(|(_, op)| match op { AsmOperand::In { expr, .. } | AsmOperand::Out { expr: Some(expr), .. } | AsmOperand::InOut { expr, .. } => self.walk_expr_without_adjust(*expr), diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index e6eaf2f446..a82d091cbb 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -956,7 +956,7 @@ impl InferenceContext<'_> { }; let diverge = asm.options.contains(AsmOptions::NORETURN); - asm.operands.iter().for_each(|operand| match *operand { + asm.operands.iter().for_each(|(_, operand)| match *operand { AsmOperand::In { expr, .. } => check_expr_asm_operand(expr, true), AsmOperand::Out { expr: Some(expr), .. } | AsmOperand::InOut { expr, .. } => { check_expr_asm_operand(expr, false) diff --git a/crates/hir-ty/src/infer/mutability.rs b/crates/hir-ty/src/infer/mutability.rs index e841c66308..8e52725e53 100644 --- a/crates/hir-ty/src/infer/mutability.rs +++ b/crates/hir-ty/src/infer/mutability.rs @@ -42,7 +42,7 @@ impl InferenceContext<'_> { match &self.body[tgt_expr] { Expr::Missing => (), Expr::InlineAsm(e) => { - e.operands.iter().for_each(|op| match op { + e.operands.iter().for_each(|(_, op)| match op { AsmOperand::In { expr, .. } | AsmOperand::Out { expr: Some(expr), .. } | AsmOperand::InOut { expr, .. } => { diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 75969bd899..3b8b901fa1 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -5259,13 +5259,10 @@ impl InlineAsmOperand { } pub fn name(&self, db: &dyn HirDatabase) -> Option { - db.body_with_source_map(self.owner) - .1 - .template_map()? - .1 - .get(&self.expr)? - .get(self.index) - .and_then(|(_, _, name)| name.clone()) + match &db.body(self.owner)[self.expr] { + hir_def::hir::Expr::InlineAsm(e) => e.operands.get(self.index)?.0.clone(), + _ => None, + } } } diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 543f2fc089..0ba0e44657 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -576,7 +576,7 @@ impl<'db> SemanticsImpl<'db> { let (owner, (expr, asm_parts)) = source_analyzer.as_asm_parts(asm.as_ref())?; let res = asm_parts .iter() - .map(|&(range, index, _)| { + .map(|&(range, index)| { ( range + quote.end(), Some(Either::Right(InlineAsmOperand { owner, expr, index })), diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 4baf9079a0..f6f1da1b7d 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -913,8 +913,8 @@ impl SourceAnalyzer { let (expr, args) = body_source_map.asm_template_args(asm)?; Some(*def).zip( args.iter() - .find(|(range, _, _)| range.contains_inclusive(offset)) - .map(|(range, idx, _)| (expr, *range, *idx)), + .find(|(range, _)| range.contains_inclusive(offset)) + .map(|(range, idx)| (expr, *range, *idx)), ) } @@ -944,7 +944,7 @@ impl SourceAnalyzer { pub(crate) fn as_asm_parts( &self, asm: InFile<&ast::AsmExpr>, - ) -> Option<(DefWithBodyId, (ExprId, &[(TextRange, usize, Option)]))> { + ) -> Option<(DefWithBodyId, (ExprId, &[(TextRange, usize)]))> { let (def, _, body_source_map) = self.def.as_ref()?; Some(*def).zip(body_source_map.asm_template_args(asm)) } diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index 9b9344e98c..e46cb5a781 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -3008,7 +3008,11 @@ fn test() { fn test() { core::arch::asm!( "push {base$0}", - base = const 0 + "push {base}", + boo = const 0, + virtual_free = sym VIRTUAL_FREE, + base = const 0, + boo = const 0, ); } "#, @@ -3016,7 +3020,11 @@ fn test() { fn test() { core::arch::asm!( "push {bose}", - bose = const 0 + "push {bose}", + boo = const 0, + virtual_free = sym VIRTUAL_FREE, + bose = const 0, + boo = const 0, ); } "#,