mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Fixup path fragments upon MBE transcription
This commit is contained in:
parent
037844c8a0
commit
fd7435d463
5 changed files with 89 additions and 5 deletions
|
@ -400,7 +400,8 @@ fn push_fragment(buf: &mut Vec<tt::TokenTree>, fragment: Fragment) {
|
|||
}
|
||||
buf.push(tt.into())
|
||||
}
|
||||
Fragment::Tokens(tt) | Fragment::Expr(tt) => buf.push(tt),
|
||||
Fragment::Path(tt::TokenTree::Subtree(tt)) => fix_up_and_push_path_tt(buf, tt),
|
||||
Fragment::Tokens(tt) | Fragment::Expr(tt) | Fragment::Path(tt) => buf.push(tt),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,6 +412,45 @@ fn push_subtree(buf: &mut Vec<tt::TokenTree>, tt: tt::Subtree) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Inserts the path separator `::` between an identifier and its following generic
|
||||
/// argument list, and then pushes into the buffer. See [`Fragment::Path`] for why
|
||||
/// we need this fixup.
|
||||
fn fix_up_and_push_path_tt(buf: &mut Vec<tt::TokenTree>, subtree: tt::Subtree) {
|
||||
stdx::always!(matches!(subtree.delimiter.kind, tt::DelimiterKind::Invisible));
|
||||
let mut prev_was_ident = false;
|
||||
// Note that we only need to fix up the top-level `TokenTree`s because the
|
||||
// context of the paths in the descendant `Subtree`s won't be changed by the
|
||||
// mbe transcription.
|
||||
for tt in subtree.token_trees {
|
||||
if prev_was_ident {
|
||||
// Pedantically, `(T) -> U` in `FnOnce(T) -> U` is treated as a generic
|
||||
// argument list and thus needs `::` between it and `FnOnce`. However in
|
||||
// today's Rust this type of path *semantically* cannot appear as a
|
||||
// top-level expression-context path, so we can safely ignore it.
|
||||
if let tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '<', .. })) = tt {
|
||||
buf.push(
|
||||
tt::Leaf::Punct(tt::Punct {
|
||||
char: ':',
|
||||
spacing: tt::Spacing::Joint,
|
||||
span: tt::Span::unspecified(),
|
||||
})
|
||||
.into(),
|
||||
);
|
||||
buf.push(
|
||||
tt::Leaf::Punct(tt::Punct {
|
||||
char: ':',
|
||||
spacing: tt::Spacing::Alone,
|
||||
span: tt::Span::unspecified(),
|
||||
})
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
prev_was_ident = matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Ident(_)));
|
||||
buf.push(tt);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles `${count(t, depth)}`. `our_depth` is the recursion depth and `count_depth` is the depth
|
||||
/// defined by the metavar expression.
|
||||
fn count(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue