Skip to content

Commit 6db1411

Browse files
authored
Merge pull request rust-lang#19037 from ChayimFriedman2/fix-other-test
fix: In completion's expand, consider recursion stop condition (when we're not inside a macro call anymore) *after* the recursive call instead of before it
2 parents 9051647 + 1360b4c commit 6db1411

File tree

2 files changed

+83
-8
lines changed

2 files changed

+83
-8
lines changed

src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub(super) fn expand_and_analyze(
5959
// make the offset point to the start of the original token, as that is what the
6060
// intermediate offsets calculated in expansion always points to
6161
let offset = offset - relative_offset;
62-
let expansion = expand(
62+
let expansion = expand_maybe_stop(
6363
sema,
6464
original_file.clone(),
6565
speculative_file.clone(),
@@ -118,31 +118,56 @@ fn token_at_offset_ignore_whitespace(file: &SyntaxNode, offset: TextSize) -> Opt
118118
/// that we check, we subtract `COMPLETION_MARKER.len()`. This may not be accurate because proc macros
119119
/// can insert the text of the completion marker in other places while removing the span, but this is
120120
/// the best we can do.
121-
fn expand(
121+
fn expand_maybe_stop(
122122
sema: &Semantics<'_, RootDatabase>,
123123
original_file: SyntaxNode,
124124
speculative_file: SyntaxNode,
125125
original_offset: TextSize,
126126
fake_ident_token: SyntaxToken,
127127
relative_offset: TextSize,
128128
) -> Option<ExpansionResult> {
129-
let _p = tracing::info_span!("CompletionContext::expand").entered();
129+
if let result @ Some(_) = expand(
130+
sema,
131+
original_file.clone(),
132+
speculative_file.clone(),
133+
original_offset,
134+
fake_ident_token.clone(),
135+
relative_offset,
136+
) {
137+
return result;
138+
}
130139

140+
// This needs to come after the recursive call, because our "inside macro" detection is subtly wrong
141+
// with regard to attribute macros named `test` that are not std's test. So hopefully we will expand
142+
// them successfully above and be able to analyze.
131143
// Left biased since there may already be an identifier token there, and we appended to it.
132144
if !sema.might_be_inside_macro_call(&fake_ident_token)
133145
&& token_at_offset_ignore_whitespace(&original_file, original_offset + relative_offset)
134146
.is_some_and(|original_token| !sema.might_be_inside_macro_call(&original_token))
135147
{
136148
// Recursion base case.
137-
return Some(ExpansionResult {
149+
Some(ExpansionResult {
138150
original_file,
139151
speculative_file,
140152
original_offset,
141153
speculative_offset: fake_ident_token.text_range().start(),
142154
fake_ident_token,
143155
derive_ctx: None,
144-
});
156+
})
157+
} else {
158+
None
145159
}
160+
}
161+
162+
fn expand(
163+
sema: &Semantics<'_, RootDatabase>,
164+
original_file: SyntaxNode,
165+
speculative_file: SyntaxNode,
166+
original_offset: TextSize,
167+
fake_ident_token: SyntaxToken,
168+
relative_offset: TextSize,
169+
) -> Option<ExpansionResult> {
170+
let _p = tracing::info_span!("CompletionContext::expand").entered();
146171

147172
let parent_item =
148173
|item: &ast::Item| item.syntax().ancestors().skip(1).find_map(ast::Item::cast);
@@ -197,7 +222,7 @@ fn expand(
197222
// stop here to prevent problems from happening
198223
return None;
199224
}
200-
let result = expand(
225+
let result = expand_maybe_stop(
201226
sema,
202227
actual_expansion.clone(),
203228
fake_expansion.clone(),
@@ -317,7 +342,7 @@ fn expand(
317342
// stop here to prevent problems from happening
318343
return None;
319344
}
320-
let result = expand(
345+
let result = expand_maybe_stop(
321346
sema,
322347
actual_expansion.clone(),
323348
fake_expansion.clone(),
@@ -386,7 +411,7 @@ fn expand(
386411
// stop here to prevent problems from happening
387412
return None;
388413
}
389-
let result = expand(
414+
let result = expand_maybe_stop(
390415
sema,
391416
actual_expansion.clone(),
392417
fake_expansion.clone(),

src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,3 +1986,53 @@ fn foo() {
19861986
"#]],
19871987
);
19881988
}
1989+
1990+
#[test]
1991+
fn non_std_test_attr_macro() {
1992+
check(
1993+
r#"
1994+
//- proc_macros: identity
1995+
use proc_macros::identity as test;
1996+
1997+
#[test]
1998+
fn foo() {
1999+
$0
2000+
}
2001+
"#,
2002+
expect![[r#"
2003+
fn foo() fn()
2004+
md proc_macros
2005+
bt u32 u32
2006+
kw async
2007+
kw const
2008+
kw crate::
2009+
kw enum
2010+
kw extern
2011+
kw false
2012+
kw fn
2013+
kw for
2014+
kw if
2015+
kw if let
2016+
kw impl
2017+
kw let
2018+
kw loop
2019+
kw match
2020+
kw mod
2021+
kw return
2022+
kw self::
2023+
kw static
2024+
kw struct
2025+
kw trait
2026+
kw true
2027+
kw type
2028+
kw union
2029+
kw unsafe
2030+
kw use
2031+
kw while
2032+
kw while let
2033+
sn macro_rules
2034+
sn pd
2035+
sn ppd
2036+
"#]],
2037+
);
2038+
}

0 commit comments

Comments
 (0)