mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
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 https://github.com/rust-lang/rust-analyzer/issues/15016
This commit is contained in:
commit
94af6c63b7
2 changed files with 82 additions and 25 deletions
|
@ -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));
|
||||
}
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue