mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Merge #6967
6967: Correctly parse legacy trait objects with leading ForType r=matklad a=Veykril Fixes #1422 Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
fa75e11eb6
4 changed files with 63 additions and 9 deletions
|
@ -113,7 +113,7 @@ fn type_bound(p: &mut Parser) -> bool {
|
|||
p.eat(T![?]);
|
||||
match p.current() {
|
||||
LIFETIME_IDENT => lifetime(p),
|
||||
T![for] => types::for_type(p),
|
||||
T![for] => types::for_type(p, false),
|
||||
_ if paths::is_use_path_start(p) => types::path_type_(p, false),
|
||||
_ => {
|
||||
m.abandon(p);
|
||||
|
|
|
@ -44,7 +44,7 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
|
|||
T![&] => ref_type(p),
|
||||
T![_] => infer_type(p),
|
||||
T![fn] | T![unsafe] | T![extern] => fn_ptr_type(p),
|
||||
T![for] => for_type(p),
|
||||
T![for] => for_type(p, allow_bounds),
|
||||
T![impl] => impl_trait_type(p),
|
||||
T![dyn] => dyn_trait_type(p),
|
||||
// Some path types are not allowed to have bounds (no plus)
|
||||
|
@ -227,7 +227,7 @@ pub(super) fn for_binder(p: &mut Parser) {
|
|||
// type A = for<'a> fn() -> ();
|
||||
// type B = for<'a> unsafe extern "C" fn(&'a ()) -> ();
|
||||
// type Obj = for<'a> PartialEq<&'a i32>;
|
||||
pub(super) fn for_type(p: &mut Parser) {
|
||||
pub(super) fn for_type(p: &mut Parser, allow_bounds: bool) {
|
||||
assert!(p.at(T![for]));
|
||||
let m = p.start();
|
||||
for_binder(p);
|
||||
|
@ -240,7 +240,13 @@ pub(super) fn for_type(p: &mut Parser) {
|
|||
}
|
||||
}
|
||||
type_no_bounds(p);
|
||||
m.complete(p, FOR_TYPE);
|
||||
let completed = m.complete(p, FOR_TYPE);
|
||||
|
||||
// test no_dyn_trait_leading_for
|
||||
// type A = for<'a> Test<'a> + Send;
|
||||
if allow_bounds {
|
||||
opt_type_bounds_as_dyn_trait_type(p, completed);
|
||||
}
|
||||
}
|
||||
|
||||
// test impl_trait_type
|
||||
|
@ -290,7 +296,7 @@ fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) {
|
|||
let path = m.complete(p, kind);
|
||||
|
||||
if allow_bounds {
|
||||
opt_path_type_bounds_as_dyn_trait_type(p, path);
|
||||
opt_type_bounds_as_dyn_trait_type(p, path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,19 +310,23 @@ pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) {
|
|||
// fn foo() -> Box<dyn T + 'f> {}
|
||||
let path = m.complete(p, PATH_TYPE);
|
||||
if allow_bounds {
|
||||
opt_path_type_bounds_as_dyn_trait_type(p, path);
|
||||
opt_type_bounds_as_dyn_trait_type(p, path);
|
||||
}
|
||||
}
|
||||
|
||||
/// This turns a parsed PATH_TYPE optionally into a DYN_TRAIT_TYPE
|
||||
/// This turns a parsed PATH_TYPE or FOR_TYPE optionally into a DYN_TRAIT_TYPE
|
||||
/// with a TYPE_BOUND_LIST
|
||||
fn opt_path_type_bounds_as_dyn_trait_type(p: &mut Parser, path_type_marker: CompletedMarker) {
|
||||
fn opt_type_bounds_as_dyn_trait_type(p: &mut Parser, type_marker: CompletedMarker) {
|
||||
assert!(matches!(
|
||||
type_marker.kind(),
|
||||
SyntaxKind::PATH_TYPE | SyntaxKind::FOR_TYPE | SyntaxKind::MACRO_CALL
|
||||
));
|
||||
if !p.at(T![+]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// First create a TYPE_BOUND from the completed PATH_TYPE
|
||||
let m = path_type_marker.precede(p).complete(p, TYPE_BOUND);
|
||||
let m = type_marker.precede(p).complete(p, TYPE_BOUND);
|
||||
|
||||
// Next setup a marker for the TYPE_BOUND_LIST
|
||||
let m = m.precede(p);
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
SOURCE_FILE@0..34
|
||||
TYPE_ALIAS@0..33
|
||||
TYPE_KW@0..4 "type"
|
||||
WHITESPACE@4..5 " "
|
||||
NAME@5..6
|
||||
IDENT@5..6 "A"
|
||||
WHITESPACE@6..7 " "
|
||||
EQ@7..8 "="
|
||||
WHITESPACE@8..9 " "
|
||||
DYN_TRAIT_TYPE@9..32
|
||||
TYPE_BOUND_LIST@9..32
|
||||
TYPE_BOUND@9..25
|
||||
FOR_TYPE@9..25
|
||||
FOR_KW@9..12 "for"
|
||||
GENERIC_PARAM_LIST@12..16
|
||||
L_ANGLE@12..13 "<"
|
||||
LIFETIME_PARAM@13..15
|
||||
LIFETIME@13..15
|
||||
LIFETIME_IDENT@13..15 "\'a"
|
||||
R_ANGLE@15..16 ">"
|
||||
WHITESPACE@16..17 " "
|
||||
PATH_TYPE@17..25
|
||||
PATH@17..25
|
||||
PATH_SEGMENT@17..25
|
||||
NAME_REF@17..21
|
||||
IDENT@17..21 "Test"
|
||||
GENERIC_ARG_LIST@21..25
|
||||
L_ANGLE@21..22 "<"
|
||||
LIFETIME_ARG@22..24
|
||||
LIFETIME@22..24
|
||||
LIFETIME_IDENT@22..24 "\'a"
|
||||
R_ANGLE@24..25 ">"
|
||||
WHITESPACE@25..26 " "
|
||||
PLUS@26..27 "+"
|
||||
WHITESPACE@27..28 " "
|
||||
TYPE_BOUND@28..32
|
||||
PATH_TYPE@28..32
|
||||
PATH@28..32
|
||||
PATH_SEGMENT@28..32
|
||||
NAME_REF@28..32
|
||||
IDENT@28..32 "Send"
|
||||
SEMICOLON@32..33 ";"
|
||||
WHITESPACE@33..34 "\n"
|
|
@ -0,0 +1 @@
|
|||
type A = for<'a> Test<'a> + Send;
|
Loading…
Reference in a new issue