mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Merge #1676
1676: Fix for<'lifetime> for types specified by path r=matklad a=eupn Fixes #1467. Co-authored-by: Evgenii P <eupn@protonmail.com>
This commit is contained in:
commit
19e0d7d596
10 changed files with 100 additions and 13 deletions
|
@ -554,7 +554,7 @@ fn arg_list(p: &mut Parser) {
|
||||||
// let _ = format!();
|
// let _ = format!();
|
||||||
// }
|
// }
|
||||||
fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) {
|
fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) {
|
||||||
assert!(paths::is_path_start(p) || p.at(T![<]));
|
assert!(paths::is_path_start(p));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
paths::expr_path(p);
|
paths::expr_path(p);
|
||||||
match p.current() {
|
match p.current() {
|
||||||
|
|
|
@ -62,7 +62,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
|
||||||
if let Some(m) = literal(p) {
|
if let Some(m) = literal(p) {
|
||||||
return Some((m, BlockLike::NotBlock));
|
return Some((m, BlockLike::NotBlock));
|
||||||
}
|
}
|
||||||
if paths::is_path_start(p) || p.at(T![<]) {
|
if paths::is_path_start(p) {
|
||||||
return Some(path_expr(p, r));
|
return Some(path_expr(p, r));
|
||||||
}
|
}
|
||||||
let la = p.nth(1);
|
let la = p.nth(1);
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemF
|
||||||
}
|
}
|
||||||
Err(m) => m,
|
Err(m) => m,
|
||||||
};
|
};
|
||||||
if paths::is_path_start(p) {
|
if paths::is_use_path_start(p) {
|
||||||
match macro_call(p) {
|
match macro_call(p) {
|
||||||
BlockLike::Block => (),
|
BlockLike::Block => (),
|
||||||
BlockLike::NotBlock => {
|
BlockLike::NotBlock => {
|
||||||
|
@ -378,7 +378,7 @@ pub(crate) fn mod_item_list(p: &mut Parser) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn macro_call(p: &mut Parser) -> BlockLike {
|
fn macro_call(p: &mut Parser) -> BlockLike {
|
||||||
assert!(paths::is_path_start(p));
|
assert!(paths::is_use_path_start(p));
|
||||||
paths::use_path(p);
|
paths::use_path(p);
|
||||||
macro_call_after_excl(p)
|
macro_call_after_excl(p)
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ fn use_tree(p: &mut Parser) {
|
||||||
// use crate::Item;
|
// use crate::Item;
|
||||||
// use self::some::Struct;
|
// use self::some::Struct;
|
||||||
// use crate_name::some_item;
|
// use crate_name::some_item;
|
||||||
_ if paths::is_path_start(p) => {
|
_ if paths::is_use_path_start(p) => {
|
||||||
paths::use_path(p);
|
paths::use_path(p);
|
||||||
match p.current() {
|
match p.current() {
|
||||||
T![as] => {
|
T![as] => {
|
||||||
|
|
|
@ -4,6 +4,10 @@ pub(super) const PATH_FIRST: TokenSet =
|
||||||
token_set![IDENT, SELF_KW, SUPER_KW, CRATE_KW, COLONCOLON, L_ANGLE];
|
token_set![IDENT, SELF_KW, SUPER_KW, CRATE_KW, COLONCOLON, L_ANGLE];
|
||||||
|
|
||||||
pub(super) fn is_path_start(p: &Parser) -> bool {
|
pub(super) fn is_path_start(p: &Parser) -> bool {
|
||||||
|
is_use_path_start(p) || p.at(T![<])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn is_use_path_start(p: &Parser) -> bool {
|
||||||
match p.current() {
|
match p.current() {
|
||||||
IDENT | T![self] | T![super] | T![crate] | T![::] => true,
|
IDENT | T![self] | T![super] | T![crate] | T![::] => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -58,7 +62,7 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) {
|
||||||
if first && p.eat(T![<]) {
|
if first && p.eat(T![<]) {
|
||||||
types::type_(p);
|
types::type_(p);
|
||||||
if p.eat(T![as]) {
|
if p.eat(T![as]) {
|
||||||
if is_path_start(p) {
|
if is_use_path_start(p) {
|
||||||
types::path_type(p);
|
types::path_type(p);
|
||||||
} else {
|
} else {
|
||||||
p.error("expected a trait");
|
p.error("expected a trait");
|
||||||
|
|
|
@ -65,7 +65,7 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
|
||||||
{
|
{
|
||||||
return Some(bind_pat(p, true));
|
return Some(bind_pat(p, true));
|
||||||
}
|
}
|
||||||
if paths::is_path_start(p) {
|
if paths::is_use_path_start(p) {
|
||||||
return Some(path_pat(p));
|
return Some(path_pat(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ fn literal_pat(p: &mut Parser) -> CompletedMarker {
|
||||||
// let Bar(..) = ();
|
// let Bar(..) = ();
|
||||||
// }
|
// }
|
||||||
fn path_pat(p: &mut Parser) -> CompletedMarker {
|
fn path_pat(p: &mut Parser) -> CompletedMarker {
|
||||||
assert!(paths::is_path_start(p));
|
assert!(paths::is_use_path_start(p));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
paths::expr_path(p);
|
paths::expr_path(p);
|
||||||
let kind = match p.current() {
|
let kind = match p.current() {
|
||||||
|
|
|
@ -101,7 +101,7 @@ fn type_bound(p: &mut Parser) -> bool {
|
||||||
match p.current() {
|
match p.current() {
|
||||||
LIFETIME => p.bump(),
|
LIFETIME => p.bump(),
|
||||||
T![for] => types::for_type(p),
|
T![for] => types::for_type(p),
|
||||||
_ if paths::is_path_start(p) => types::path_type_(p, false),
|
_ if paths::is_use_path_start(p) => types::path_type_(p, false),
|
||||||
_ => {
|
_ => {
|
||||||
m.abandon(p);
|
m.abandon(p);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -29,7 +29,7 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
|
||||||
T![dyn ] => dyn_trait_type(p),
|
T![dyn ] => dyn_trait_type(p),
|
||||||
// Some path types are not allowed to have bounds (no plus)
|
// Some path types are not allowed to have bounds (no plus)
|
||||||
T![<] => path_type_(p, allow_bounds),
|
T![<] => path_type_(p, allow_bounds),
|
||||||
_ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds),
|
_ if paths::is_use_path_start(p) => path_or_macro_type_(p, allow_bounds),
|
||||||
_ => {
|
_ => {
|
||||||
p.err_recover("expected type", TYPE_RECOVERY_SET);
|
p.err_recover("expected type", TYPE_RECOVERY_SET);
|
||||||
}
|
}
|
||||||
|
@ -205,6 +205,7 @@ pub(super) fn for_binder(p: &mut Parser) {
|
||||||
// type A = for<'a> fn() -> ();
|
// type A = for<'a> fn() -> ();
|
||||||
// fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {}
|
// fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {}
|
||||||
// fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {}
|
// fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {}
|
||||||
|
// fn baz<T>(_t: &T) where for<'a> <&'a T as Baz>::Foo: Iterator {}
|
||||||
pub(super) fn for_type(p: &mut Parser) {
|
pub(super) fn for_type(p: &mut Parser) {
|
||||||
assert!(p.at(T![for]));
|
assert!(p.at(T![for]));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
|
@ -251,7 +252,7 @@ pub(super) fn path_type(p: &mut Parser) {
|
||||||
// type A = foo!();
|
// type A = foo!();
|
||||||
// type B = crate::foo!();
|
// type B = crate::foo!();
|
||||||
fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) {
|
fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) {
|
||||||
assert!(paths::is_path_start(p) || p.at(T![<]));
|
assert!(paths::is_path_start(p));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
paths::type_path(p);
|
paths::type_path(p);
|
||||||
|
|
||||||
|
@ -270,7 +271,7 @@ fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) {
|
pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) {
|
||||||
assert!(paths::is_path_start(p) || p.at(T![<]));
|
assert!(paths::is_path_start(p));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
paths::type_path(p);
|
paths::type_path(p);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
type A = for<'a> fn() -> ();
|
type A = for<'a> fn() -> ();
|
||||||
fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {}
|
fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {}
|
||||||
fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {}
|
fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {}
|
||||||
|
fn baz<T>(_t: &T) where for<'a> <&'a T as Baz>::Foo: Iterator {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SOURCE_FILE@[0; 135)
|
SOURCE_FILE@[0; 200)
|
||||||
TYPE_ALIAS_DEF@[0; 28)
|
TYPE_ALIAS_DEF@[0; 28)
|
||||||
TYPE_KW@[0; 4) "type"
|
TYPE_KW@[0; 4) "type"
|
||||||
WHITESPACE@[4; 5) " "
|
WHITESPACE@[4; 5) " "
|
||||||
|
@ -157,3 +157,84 @@ SOURCE_FILE@[0; 135)
|
||||||
L_CURLY@[132; 133) "{"
|
L_CURLY@[132; 133) "{"
|
||||||
R_CURLY@[133; 134) "}"
|
R_CURLY@[133; 134) "}"
|
||||||
WHITESPACE@[134; 135) "\n"
|
WHITESPACE@[134; 135) "\n"
|
||||||
|
FN_DEF@[135; 199)
|
||||||
|
FN_KW@[135; 137) "fn"
|
||||||
|
WHITESPACE@[137; 138) " "
|
||||||
|
NAME@[138; 141)
|
||||||
|
IDENT@[138; 141) "baz"
|
||||||
|
TYPE_PARAM_LIST@[141; 144)
|
||||||
|
L_ANGLE@[141; 142) "<"
|
||||||
|
TYPE_PARAM@[142; 143)
|
||||||
|
NAME@[142; 143)
|
||||||
|
IDENT@[142; 143) "T"
|
||||||
|
R_ANGLE@[143; 144) ">"
|
||||||
|
PARAM_LIST@[144; 152)
|
||||||
|
L_PAREN@[144; 145) "("
|
||||||
|
PARAM@[145; 151)
|
||||||
|
BIND_PAT@[145; 147)
|
||||||
|
NAME@[145; 147)
|
||||||
|
IDENT@[145; 147) "_t"
|
||||||
|
COLON@[147; 148) ":"
|
||||||
|
WHITESPACE@[148; 149) " "
|
||||||
|
REFERENCE_TYPE@[149; 151)
|
||||||
|
AMP@[149; 150) "&"
|
||||||
|
PATH_TYPE@[150; 151)
|
||||||
|
PATH@[150; 151)
|
||||||
|
PATH_SEGMENT@[150; 151)
|
||||||
|
NAME_REF@[150; 151)
|
||||||
|
IDENT@[150; 151) "T"
|
||||||
|
R_PAREN@[151; 152) ")"
|
||||||
|
WHITESPACE@[152; 153) " "
|
||||||
|
WHERE_CLAUSE@[153; 196)
|
||||||
|
WHERE_KW@[153; 158) "where"
|
||||||
|
WHITESPACE@[158; 159) " "
|
||||||
|
WHERE_PRED@[159; 196)
|
||||||
|
FOR_TYPE@[159; 186)
|
||||||
|
FOR_KW@[159; 162) "for"
|
||||||
|
TYPE_PARAM_LIST@[162; 166)
|
||||||
|
L_ANGLE@[162; 163) "<"
|
||||||
|
LIFETIME_PARAM@[163; 165)
|
||||||
|
LIFETIME@[163; 165) "\'a"
|
||||||
|
R_ANGLE@[165; 166) ">"
|
||||||
|
WHITESPACE@[166; 167) " "
|
||||||
|
PATH_TYPE@[167; 186)
|
||||||
|
PATH@[167; 186)
|
||||||
|
PATH@[167; 181)
|
||||||
|
PATH_SEGMENT@[167; 181)
|
||||||
|
L_ANGLE@[167; 168) "<"
|
||||||
|
REFERENCE_TYPE@[168; 173)
|
||||||
|
AMP@[168; 169) "&"
|
||||||
|
LIFETIME@[169; 171) "\'a"
|
||||||
|
WHITESPACE@[171; 172) " "
|
||||||
|
PATH_TYPE@[172; 173)
|
||||||
|
PATH@[172; 173)
|
||||||
|
PATH_SEGMENT@[172; 173)
|
||||||
|
NAME_REF@[172; 173)
|
||||||
|
IDENT@[172; 173) "T"
|
||||||
|
WHITESPACE@[173; 174) " "
|
||||||
|
AS_KW@[174; 176) "as"
|
||||||
|
WHITESPACE@[176; 177) " "
|
||||||
|
PATH_TYPE@[177; 180)
|
||||||
|
PATH@[177; 180)
|
||||||
|
PATH_SEGMENT@[177; 180)
|
||||||
|
NAME_REF@[177; 180)
|
||||||
|
IDENT@[177; 180) "Baz"
|
||||||
|
R_ANGLE@[180; 181) ">"
|
||||||
|
COLONCOLON@[181; 183) "::"
|
||||||
|
PATH_SEGMENT@[183; 186)
|
||||||
|
NAME_REF@[183; 186)
|
||||||
|
IDENT@[183; 186) "Foo"
|
||||||
|
COLON@[186; 187) ":"
|
||||||
|
WHITESPACE@[187; 188) " "
|
||||||
|
TYPE_BOUND_LIST@[188; 196)
|
||||||
|
TYPE_BOUND@[188; 196)
|
||||||
|
PATH_TYPE@[188; 196)
|
||||||
|
PATH@[188; 196)
|
||||||
|
PATH_SEGMENT@[188; 196)
|
||||||
|
NAME_REF@[188; 196)
|
||||||
|
IDENT@[188; 196) "Iterator"
|
||||||
|
WHITESPACE@[196; 197) " "
|
||||||
|
BLOCK@[197; 199)
|
||||||
|
L_CURLY@[197; 198) "{"
|
||||||
|
R_CURLY@[198; 199) "}"
|
||||||
|
WHITESPACE@[199; 200) "\n"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue