Skip to content

Commit

Permalink
Auto merge of #16061 - Veykril:vec-completion, r=Veykril
Browse files Browse the repository at this point in the history
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 rust-lang/rust-analyzer#15016
  • Loading branch information
bors committed Dec 13, 2023
2 parents b3af191 + 5f95765 commit 94af6c6
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 25 deletions.
96 changes: 78 additions & 18 deletions crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,97 @@ fn test_vec() {
check(
r#"
macro_rules! vec {
($($item:expr),*) => {{
let mut v = Vec::new();
$( v.push($item); )*
v
}};
() => (
$crate::__rust_force_expr!($crate::vec::Vec::new())
);
($elem:expr; $n:expr) => (
$crate::__rust_force_expr!($crate::vec::from_elem($elem, $n))
);
($($x:expr),+ $(,)?) => (
$crate::__rust_force_expr!(<[_]>::into_vec(
// This rustc_box is not required, but it produces a dramatic improvement in compile
// time when constructing arrays with many elements.
#[rustc_box]
$crate::boxed::Box::new([$($x),+])
))
);
}
macro_rules! __rust_force_expr {
($e:expr) => {
$e
};
}
fn main() {
vec!();
vec![1u32,2];
vec![a.];
}
"#,
expect![[r#"
macro_rules! vec {
($($item:expr),*) => {{
let mut v = Vec::new();
$( v.push($item); )*
v
}};
() => (
$crate::__rust_force_expr!($crate::vec::Vec::new())
);
($elem:expr; $n:expr) => (
$crate::__rust_force_expr!($crate::vec::from_elem($elem, $n))
);
($($x:expr),+ $(,)?) => (
$crate::__rust_force_expr!(<[_]>::into_vec(
// This rustc_box is not required, but it produces a dramatic improvement in compile
// time when constructing arrays with many elements.
#[rustc_box]
$crate::boxed::Box::new([$($x),+])
))
);
}
macro_rules! __rust_force_expr {
($e:expr) => {
$e
};
}
fn main() {
{
let mut v = Vec::new();
v
$crate::__rust_force_expr!($crate:: vec:: Vec:: new());
$crate::__rust_force_expr!(<[_]>:: into_vec(#[rustc_box]$crate:: boxed:: Box:: new([1u32, 2])));
/* error: expected Expr */$crate::__rust_force_expr!($crate:: vec:: from_elem((a.), $n));
}
"#]],
);
// FIXME we should ahev testing infra for multi level expansion tests
check(
r#"
macro_rules! __rust_force_expr {
($e:expr) => {
$e
};
{
let mut v = Vec::new();
v.push(1u32);
v.push(2);
v
}
fn main() {
__rust_force_expr!(crate:: vec:: Vec:: new());
__rust_force_expr!(<[_]>:: into_vec(#[rustc_box] crate:: boxed:: Box:: new([1u32, 2])));
__rust_force_expr/*+errors*/!(crate:: vec:: from_elem((a.), $n));
}
"#,
expect![[r#"
macro_rules! __rust_force_expr {
($e:expr) => {
$e
};
}
fn main() {
(crate ::vec::Vec::new());
(<[_]>::into_vec(#[rustc_box] crate ::boxed::Box::new([1u32, 2])));
/* error: expected Expr *//* parse error: expected field name or number */
/* parse error: expected expression */
/* parse error: expected R_PAREN */
/* parse error: expected COMMA */
/* parse error: expected expression, item or let statement */
(crate ::vec::from_elem((a.), $n));
}
"#]],
);
}
Expand Down
11 changes: 4 additions & 7 deletions crates/mbe/src/tt_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ impl<'a, S: Span> TtIter<'a, S> {
let buffer = tt::buffer::TokenBuffer::from_tokens(self.inner.as_slice());
let parser_input = to_parser_input(&buffer);
let tree_traversal = entry_point.parse(&parser_input);

let mut cursor = buffer.begin();
let mut error = false;
for step in tree_traversal.iter() {
Expand Down Expand Up @@ -163,12 +162,10 @@ impl<'a, S: Span> TtIter<'a, S> {
let mut curr = buffer.begin();
let mut res = vec![];

if cursor.is_root() {
while curr != cursor {
let Some(token) = curr.token_tree() else { break };
res.push(token.cloned());
curr = curr.bump();
}
while curr != cursor {
let Some(token) = curr.token_tree() else { break };
res.push(token.cloned());
curr = curr.bump();
}

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

0 comments on commit 94af6c6

Please sign in to comment.