mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-29 06:23:25 +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(
|
check(
|
||||||
r#"
|
r#"
|
||||||
macro_rules! vec {
|
macro_rules! vec {
|
||||||
($($item:expr),*) => {{
|
() => (
|
||||||
let mut v = Vec::new();
|
$crate::__rust_force_expr!($crate::vec::Vec::new())
|
||||||
$( v.push($item); )*
|
);
|
||||||
v
|
($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() {
|
fn main() {
|
||||||
vec!();
|
vec!();
|
||||||
vec![1u32,2];
|
vec![1u32,2];
|
||||||
|
vec![a.];
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
macro_rules! vec {
|
macro_rules! vec {
|
||||||
($($item:expr),*) => {{
|
() => (
|
||||||
let mut v = Vec::new();
|
$crate::__rust_force_expr!($crate::vec::Vec::new())
|
||||||
$( v.push($item); )*
|
);
|
||||||
v
|
($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() {
|
fn main() {
|
||||||
{
|
$crate::__rust_force_expr!($crate:: vec:: Vec:: new());
|
||||||
let mut v = Vec::new();
|
$crate::__rust_force_expr!(<[_]>:: into_vec(#[rustc_box]$crate:: boxed:: Box:: new([1u32, 2])));
|
||||||
v
|
/* 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);
|
fn main() {
|
||||||
v.push(2);
|
__rust_force_expr!(crate:: vec:: Vec:: new());
|
||||||
v
|
__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 buffer = tt::buffer::TokenBuffer::from_tokens(self.inner.as_slice());
|
||||||
let parser_input = to_parser_input(&buffer);
|
let parser_input = to_parser_input(&buffer);
|
||||||
let tree_traversal = entry_point.parse(&parser_input);
|
let tree_traversal = entry_point.parse(&parser_input);
|
||||||
|
|
||||||
let mut cursor = buffer.begin();
|
let mut cursor = buffer.begin();
|
||||||
let mut error = false;
|
let mut error = false;
|
||||||
for step in tree_traversal.iter() {
|
for step in tree_traversal.iter() {
|
||||||
|
@ -163,13 +162,11 @@ impl<'a, S: Span> TtIter<'a, S> {
|
||||||
let mut curr = buffer.begin();
|
let mut curr = buffer.begin();
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
|
|
||||||
if cursor.is_root() {
|
|
||||||
while curr != cursor {
|
while curr != cursor {
|
||||||
let Some(token) = curr.token_tree() else { break };
|
let Some(token) = curr.token_tree() else { break };
|
||||||
res.push(token.cloned());
|
res.push(token.cloned());
|
||||||
curr = curr.bump();
|
curr = curr.bump();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
self.inner = self.inner.as_slice()[res.len()..].iter();
|
self.inner = self.inner.as_slice()[res.len()..].iter();
|
||||||
let res = match res.len() {
|
let res = match res.len() {
|
||||||
|
|
Loading…
Reference in a new issue