Skip to content

Commit 94af6c6

Browse files
committed
Auto merge of #16061 - Veykril:vec-completion, r=Veykril
fix: Fix fragment parser replacing matches with dummies on incomplete parses Notably, this caused some completions in the `vec!` macro to no longer work. Fixes #15016
2 parents b3af191 + 5f95765 commit 94af6c6

File tree

2 files changed

+82
-25
lines changed

2 files changed

+82
-25
lines changed

crates/hir-def/src/macro_expansion_tests/mbe/regression.rs

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,97 @@ fn test_vec() {
1313
check(
1414
r#"
1515
macro_rules! vec {
16-
($($item:expr),*) => {{
17-
let mut v = Vec::new();
18-
$( v.push($item); )*
19-
v
20-
}};
16+
() => (
17+
$crate::__rust_force_expr!($crate::vec::Vec::new())
18+
);
19+
($elem:expr; $n:expr) => (
20+
$crate::__rust_force_expr!($crate::vec::from_elem($elem, $n))
21+
);
22+
($($x:expr),+ $(,)?) => (
23+
$crate::__rust_force_expr!(<[_]>::into_vec(
24+
// This rustc_box is not required, but it produces a dramatic improvement in compile
25+
// time when constructing arrays with many elements.
26+
#[rustc_box]
27+
$crate::boxed::Box::new([$($x),+])
28+
))
29+
);
30+
}
31+
32+
macro_rules! __rust_force_expr {
33+
($e:expr) => {
34+
$e
35+
};
2136
}
37+
2238
fn main() {
2339
vec!();
2440
vec![1u32,2];
41+
vec![a.];
2542
}
2643
"#,
2744
expect![[r#"
2845
macro_rules! vec {
29-
($($item:expr),*) => {{
30-
let mut v = Vec::new();
31-
$( v.push($item); )*
32-
v
33-
}};
46+
() => (
47+
$crate::__rust_force_expr!($crate::vec::Vec::new())
48+
);
49+
($elem:expr; $n:expr) => (
50+
$crate::__rust_force_expr!($crate::vec::from_elem($elem, $n))
51+
);
52+
($($x:expr),+ $(,)?) => (
53+
$crate::__rust_force_expr!(<[_]>::into_vec(
54+
// This rustc_box is not required, but it produces a dramatic improvement in compile
55+
// time when constructing arrays with many elements.
56+
#[rustc_box]
57+
$crate::boxed::Box::new([$($x),+])
58+
))
59+
);
60+
}
61+
62+
macro_rules! __rust_force_expr {
63+
($e:expr) => {
64+
$e
65+
};
3466
}
67+
3568
fn main() {
36-
{
37-
let mut v = Vec::new();
38-
v
69+
$crate::__rust_force_expr!($crate:: vec:: Vec:: new());
70+
$crate::__rust_force_expr!(<[_]>:: into_vec(#[rustc_box]$crate:: boxed:: Box:: new([1u32, 2])));
71+
/* error: expected Expr */$crate::__rust_force_expr!($crate:: vec:: from_elem((a.), $n));
72+
}
73+
"#]],
74+
);
75+
// FIXME we should ahev testing infra for multi level expansion tests
76+
check(
77+
r#"
78+
macro_rules! __rust_force_expr {
79+
($e:expr) => {
80+
$e
3981
};
40-
{
41-
let mut v = Vec::new();
42-
v.push(1u32);
43-
v.push(2);
44-
v
82+
}
83+
84+
fn main() {
85+
__rust_force_expr!(crate:: vec:: Vec:: new());
86+
__rust_force_expr!(<[_]>:: into_vec(#[rustc_box] crate:: boxed:: Box:: new([1u32, 2])));
87+
__rust_force_expr/*+errors*/!(crate:: vec:: from_elem((a.), $n));
88+
}
89+
"#,
90+
expect![[r#"
91+
macro_rules! __rust_force_expr {
92+
($e:expr) => {
93+
$e
4594
};
4695
}
96+
97+
fn main() {
98+
(crate ::vec::Vec::new());
99+
(<[_]>::into_vec(#[rustc_box] crate ::boxed::Box::new([1u32, 2])));
100+
/* error: expected Expr *//* parse error: expected field name or number */
101+
/* parse error: expected expression */
102+
/* parse error: expected R_PAREN */
103+
/* parse error: expected COMMA */
104+
/* parse error: expected expression, item or let statement */
105+
(crate ::vec::from_elem((a.), $n));
106+
}
47107
"#]],
48108
);
49109
}

crates/mbe/src/tt_iter.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ impl<'a, S: Span> TtIter<'a, S> {
131131
let buffer = tt::buffer::TokenBuffer::from_tokens(self.inner.as_slice());
132132
let parser_input = to_parser_input(&buffer);
133133
let tree_traversal = entry_point.parse(&parser_input);
134-
135134
let mut cursor = buffer.begin();
136135
let mut error = false;
137136
for step in tree_traversal.iter() {
@@ -163,12 +162,10 @@ impl<'a, S: Span> TtIter<'a, S> {
163162
let mut curr = buffer.begin();
164163
let mut res = vec![];
165164

166-
if cursor.is_root() {
167-
while curr != cursor {
168-
let Some(token) = curr.token_tree() else { break };
169-
res.push(token.cloned());
170-
curr = curr.bump();
171-
}
165+
while curr != cursor {
166+
let Some(token) = curr.token_tree() else { break };
167+
res.push(token.cloned());
168+
curr = curr.bump();
172169
}
173170

174171
self.inner = self.inner.as_slice()[res.len()..].iter();

0 commit comments

Comments
 (0)