Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 904d8f6

Browse files
committedDec 23, 2024
Auto merge of #134681 - lnicola:sync-from-ra, r=lnicola
Subtree update of `rust-analyzer` r? `@ghost`
2 parents 85c3989 + 8dbdcc0 commit 904d8f6

File tree

113 files changed

+3082
-2151
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+3082
-2151
lines changed
 

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

+38-14
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use smallvec::SmallVec;
1818
use span::{Edition, MacroFileId};
1919
use syntax::{ast, AstPtr, SyntaxNodePtr};
2020
use triomphe::Arc;
21+
use tt::TextRange;
2122

2223
use crate::{
2324
db::DefDatabase,
@@ -143,15 +144,7 @@ pub struct BodySourceMap {
143144

144145
pub types: TypesSourceMap,
145146

146-
// FIXME: Make this a sane struct.
147-
template_map: Option<
148-
Box<(
149-
// format_args!
150-
FxHashMap<ExprId, (HygieneId, Vec<(syntax::TextRange, Name)>)>,
151-
// asm!
152-
FxHashMap<ExprId, Vec<Vec<(syntax::TextRange, usize)>>>,
153-
)>,
154-
>,
147+
template_map: Option<Box<FormatTemplate>>,
155148

156149
expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, MacroFileId>,
157150

@@ -160,6 +153,20 @@ pub struct BodySourceMap {
160153
diagnostics: Vec<BodyDiagnostic>,
161154
}
162155

156+
#[derive(Default, Debug, Eq, PartialEq)]
157+
struct FormatTemplate {
158+
/// A map from `format_args!()` expressions to their captures.
159+
format_args_to_captures: FxHashMap<ExprId, (HygieneId, Vec<(syntax::TextRange, Name)>)>,
160+
/// A map from `asm!()` expressions to their captures.
161+
asm_to_captures: FxHashMap<ExprId, Vec<Vec<(syntax::TextRange, usize)>>>,
162+
/// A map from desugared expressions of implicit captures to their source.
163+
///
164+
/// The value stored for each capture is its template literal and offset inside it. The template literal
165+
/// is from the `format_args[_nl]!()` macro and so needs to be mapped up once to go to the user-written
166+
/// template.
167+
implicit_capture_to_source: FxHashMap<ExprId, InFile<(AstPtr<ast::Expr>, TextRange)>>,
168+
}
169+
163170
#[derive(Debug, Eq, PartialEq)]
164171
pub enum BodyDiagnostic {
165172
InactiveCode { node: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions },
@@ -798,18 +805,29 @@ impl BodySourceMap {
798805
node: InFile<&ast::FormatArgsExpr>,
799806
) -> Option<(HygieneId, &[(syntax::TextRange, Name)])> {
800807
let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>);
801-
let (hygiene, names) =
802-
self.template_map.as_ref()?.0.get(&self.expr_map.get(&src)?.as_expr()?)?;
808+
let (hygiene, names) = self
809+
.template_map
810+
.as_ref()?
811+
.format_args_to_captures
812+
.get(&self.expr_map.get(&src)?.as_expr()?)?;
803813
Some((*hygiene, &**names))
804814
}
805815

816+
pub fn format_args_implicit_capture(
817+
&self,
818+
capture_expr: ExprId,
819+
) -> Option<InFile<(AstPtr<ast::Expr>, TextRange)>> {
820+
self.template_map.as_ref()?.implicit_capture_to_source.get(&capture_expr).copied()
821+
}
822+
806823
pub fn asm_template_args(
807824
&self,
808825
node: InFile<&ast::AsmExpr>,
809826
) -> Option<(ExprId, &[Vec<(syntax::TextRange, usize)>])> {
810827
let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>);
811828
let expr = self.expr_map.get(&src)?.as_expr()?;
812-
Some(expr).zip(self.template_map.as_ref()?.1.get(&expr).map(std::ops::Deref::deref))
829+
Some(expr)
830+
.zip(self.template_map.as_ref()?.asm_to_captures.get(&expr).map(std::ops::Deref::deref))
813831
}
814832

815833
/// Get a reference to the body source map's diagnostics.
@@ -835,8 +853,14 @@ impl BodySourceMap {
835853
types,
836854
} = self;
837855
if let Some(template_map) = template_map {
838-
template_map.0.shrink_to_fit();
839-
template_map.1.shrink_to_fit();
856+
let FormatTemplate {
857+
format_args_to_captures,
858+
asm_to_captures,
859+
implicit_capture_to_source,
860+
} = &mut **template_map;
861+
format_args_to_captures.shrink_to_fit();
862+
asm_to_captures.shrink_to_fit();
863+
implicit_capture_to_source.shrink_to_fit();
840864
}
841865
expr_map.shrink_to_fit();
842866
expr_map_back.shrink_to_fit();

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

+16-4
Original file line numberDiff line numberDiff line change
@@ -1957,17 +1957,29 @@ impl ExprCollector<'_> {
19571957
_ => None,
19581958
});
19591959
let mut mappings = vec![];
1960-
let (fmt, hygiene) = match template.and_then(|it| self.expand_macros_to_string(it)) {
1961-
Some((s, is_direct_literal)) => {
1960+
let (fmt, hygiene) = match template.and_then(|template| {
1961+
self.expand_macros_to_string(template.clone()).map(|it| (it, template))
1962+
}) {
1963+
Some(((s, is_direct_literal), template)) => {
19621964
let call_ctx = self.expander.syntax_context();
19631965
let hygiene = self.hygiene_id_for(s.syntax().text_range().start());
19641966
let fmt = format_args::parse(
19651967
&s,
19661968
fmt_snippet,
19671969
args,
19681970
is_direct_literal,
1969-
|name| {
1971+
|name, range| {
19701972
let expr_id = self.alloc_expr_desugared(Expr::Path(Path::from(name)));
1973+
if let Some(range) = range {
1974+
self.source_map
1975+
.template_map
1976+
.get_or_insert_with(Default::default)
1977+
.implicit_capture_to_source
1978+
.insert(
1979+
expr_id,
1980+
self.expander.in_file((AstPtr::new(&template), range)),
1981+
);
1982+
}
19711983
if !hygiene.is_root() {
19721984
self.body.expr_hygiene.insert(expr_id, hygiene);
19731985
}
@@ -2139,7 +2151,7 @@ impl ExprCollector<'_> {
21392151
self.source_map
21402152
.template_map
21412153
.get_or_insert_with(Default::default)
2142-
.0
2154+
.format_args_to_captures
21432155
.insert(idx, (hygiene, mappings));
21442156
idx
21452157
}
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.