mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 20:09:19 +00:00
Parse associated return type bounds
This commit is contained in:
parent
d7d8971203
commit
fa2340a4df
12 changed files with 361 additions and 5 deletions
|
@ -189,6 +189,10 @@ pub(super) fn lower_generic_args(
|
||||||
args.push(GenericArg::Type(type_ref));
|
args.push(GenericArg::Type(type_ref));
|
||||||
}
|
}
|
||||||
ast::GenericArg::AssocTypeArg(assoc_type_arg) => {
|
ast::GenericArg::AssocTypeArg(assoc_type_arg) => {
|
||||||
|
if assoc_type_arg.param_list().is_some() {
|
||||||
|
// We currently ignore associated return type bounds.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if let Some(name_ref) = assoc_type_arg.name_ref() {
|
if let Some(name_ref) = assoc_type_arg.name_ref() {
|
||||||
let name = name_ref.as_name();
|
let name = name_ref.as_name();
|
||||||
let args = assoc_type_arg
|
let args = assoc_type_arg
|
||||||
|
|
|
@ -76,6 +76,29 @@ fn generic_arg(p: &mut Parser<'_>) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
IDENT if p.nth_at(1, T!['(']) => {
|
||||||
|
let m = p.start();
|
||||||
|
name_ref(p);
|
||||||
|
params::param_list_fn_trait(p);
|
||||||
|
if p.at(T![:]) && !p.at(T![::]) {
|
||||||
|
// test associated_return_type_bounds
|
||||||
|
// fn foo<T: Foo<foo(): Send, bar(i32): Send, baz(i32, i32): Send>>() {}
|
||||||
|
generic_params::bounds(p);
|
||||||
|
m.complete(p, ASSOC_TYPE_ARG);
|
||||||
|
} else {
|
||||||
|
// test bare_dyn_types_with_paren_as_generic_args
|
||||||
|
// type A = S<Fn(i32)>;
|
||||||
|
// type A = S<Fn(i32) + Send>;
|
||||||
|
// type B = S<Fn(i32) -> i32>;
|
||||||
|
// type C = S<Fn(i32) -> i32 + Send>;
|
||||||
|
opt_ret_type(p);
|
||||||
|
let m = m.complete(p, PATH_SEGMENT).precede(p).complete(p, PATH);
|
||||||
|
let m = paths::type_path_for_qualifier(p, m);
|
||||||
|
let m = m.precede(p).complete(p, PATH_TYPE);
|
||||||
|
let m = types::opt_type_bounds_as_dyn_trait_type(p, m);
|
||||||
|
m.precede(p).complete(p, TYPE_ARG);
|
||||||
|
}
|
||||||
|
}
|
||||||
_ if p.at_ts(types::TYPE_FIRST) => type_arg(p),
|
_ if p.at_ts(types::TYPE_FIRST) => type_arg(p),
|
||||||
_ => return false,
|
_ => return false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,6 +136,7 @@ fn opt_path_type_args(p: &mut Parser<'_>, mode: Mode) {
|
||||||
Mode::Type => {
|
Mode::Type => {
|
||||||
// test typepathfn_with_coloncolon
|
// test typepathfn_with_coloncolon
|
||||||
// type F = Start::(Middle) -> (Middle)::End;
|
// type F = Start::(Middle) -> (Middle)::End;
|
||||||
|
// type GenericArg = S<Start(Middle)::End>;
|
||||||
if p.at(T![::]) && p.nth_at(2, T!['(']) {
|
if p.at(T![::]) && p.nth_at(2, T!['(']) {
|
||||||
p.bump(T![::]);
|
p.bump(T![::]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -337,13 +337,16 @@ pub(super) fn path_type_(p: &mut Parser<'_>, allow_bounds: bool) {
|
||||||
|
|
||||||
/// This turns a parsed PATH_TYPE or FOR_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
|
/// with a TYPE_BOUND_LIST
|
||||||
fn opt_type_bounds_as_dyn_trait_type(p: &mut Parser<'_>, type_marker: CompletedMarker) {
|
pub(super) fn opt_type_bounds_as_dyn_trait_type(
|
||||||
|
p: &mut Parser<'_>,
|
||||||
|
type_marker: CompletedMarker,
|
||||||
|
) -> CompletedMarker {
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
type_marker.kind(),
|
type_marker.kind(),
|
||||||
SyntaxKind::PATH_TYPE | SyntaxKind::FOR_TYPE | SyntaxKind::MACRO_TYPE
|
SyntaxKind::PATH_TYPE | SyntaxKind::FOR_TYPE | SyntaxKind::MACRO_TYPE
|
||||||
));
|
));
|
||||||
if !p.at(T![+]) {
|
if !p.at(T![+]) {
|
||||||
return;
|
return type_marker;
|
||||||
}
|
}
|
||||||
|
|
||||||
// First create a TYPE_BOUND from the completed PATH_TYPE
|
// First create a TYPE_BOUND from the completed PATH_TYPE
|
||||||
|
@ -360,5 +363,5 @@ fn opt_type_bounds_as_dyn_trait_type(p: &mut Parser<'_>, type_marker: CompletedM
|
||||||
let m = generic_params::bounds_without_colon_m(p, m);
|
let m = generic_params::bounds_without_colon_m(p, m);
|
||||||
|
|
||||||
// Finally precede everything with DYN_TRAIT_TYPE
|
// Finally precede everything with DYN_TRAIT_TYPE
|
||||||
m.precede(p).complete(p, DYN_TRAIT_TYPE);
|
m.precede(p).complete(p, DYN_TRAIT_TYPE)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,3 +41,41 @@ SOURCE_FILE
|
||||||
IDENT "End"
|
IDENT "End"
|
||||||
SEMICOLON ";"
|
SEMICOLON ";"
|
||||||
WHITESPACE "\n"
|
WHITESPACE "\n"
|
||||||
|
TYPE_ALIAS
|
||||||
|
TYPE_KW "type"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "GenericArg"
|
||||||
|
WHITESPACE " "
|
||||||
|
EQ "="
|
||||||
|
WHITESPACE " "
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "S"
|
||||||
|
GENERIC_ARG_LIST
|
||||||
|
L_ANGLE "<"
|
||||||
|
TYPE_ARG
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Start"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
PARAM
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Middle"
|
||||||
|
R_PAREN ")"
|
||||||
|
COLON2 "::"
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "End"
|
||||||
|
R_ANGLE ">"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
type F = Start::(Middle) -> (Middle)::End;
|
type F = Start::(Middle) -> (Middle)::End;
|
||||||
|
type GenericArg = S<Start(Middle)::End>;
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
SOURCE_FILE
|
||||||
|
FN
|
||||||
|
FN_KW "fn"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "foo"
|
||||||
|
GENERIC_PARAM_LIST
|
||||||
|
L_ANGLE "<"
|
||||||
|
TYPE_PARAM
|
||||||
|
NAME
|
||||||
|
IDENT "T"
|
||||||
|
COLON ":"
|
||||||
|
WHITESPACE " "
|
||||||
|
TYPE_BOUND_LIST
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Foo"
|
||||||
|
GENERIC_ARG_LIST
|
||||||
|
L_ANGLE "<"
|
||||||
|
ASSOC_TYPE_ARG
|
||||||
|
NAME_REF
|
||||||
|
IDENT "foo"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
R_PAREN ")"
|
||||||
|
COLON ":"
|
||||||
|
WHITESPACE " "
|
||||||
|
TYPE_BOUND_LIST
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Send"
|
||||||
|
COMMA ","
|
||||||
|
WHITESPACE " "
|
||||||
|
ASSOC_TYPE_ARG
|
||||||
|
NAME_REF
|
||||||
|
IDENT "bar"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
PARAM
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "i32"
|
||||||
|
R_PAREN ")"
|
||||||
|
COLON ":"
|
||||||
|
WHITESPACE " "
|
||||||
|
TYPE_BOUND_LIST
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Send"
|
||||||
|
COMMA ","
|
||||||
|
WHITESPACE " "
|
||||||
|
ASSOC_TYPE_ARG
|
||||||
|
NAME_REF
|
||||||
|
IDENT "baz"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
PARAM
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "i32"
|
||||||
|
COMMA ","
|
||||||
|
WHITESPACE " "
|
||||||
|
PARAM
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "i32"
|
||||||
|
R_PAREN ")"
|
||||||
|
COLON ":"
|
||||||
|
WHITESPACE " "
|
||||||
|
TYPE_BOUND_LIST
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Send"
|
||||||
|
R_ANGLE ">"
|
||||||
|
R_ANGLE ">"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
R_PAREN ")"
|
||||||
|
WHITESPACE " "
|
||||||
|
BLOCK_EXPR
|
||||||
|
STMT_LIST
|
||||||
|
L_CURLY "{"
|
||||||
|
R_CURLY "}"
|
||||||
|
WHITESPACE "\n"
|
|
@ -0,0 +1 @@
|
||||||
|
fn foo<T: Foo<foo(): Send, bar(i32): Send, baz(i32, i32): Send>>() {}
|
|
@ -0,0 +1,175 @@
|
||||||
|
SOURCE_FILE
|
||||||
|
TYPE_ALIAS
|
||||||
|
TYPE_KW "type"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "A"
|
||||||
|
WHITESPACE " "
|
||||||
|
EQ "="
|
||||||
|
WHITESPACE " "
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "S"
|
||||||
|
GENERIC_ARG_LIST
|
||||||
|
L_ANGLE "<"
|
||||||
|
TYPE_ARG
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Fn"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
PARAM
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "i32"
|
||||||
|
R_PAREN ")"
|
||||||
|
R_ANGLE ">"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
TYPE_ALIAS
|
||||||
|
TYPE_KW "type"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "A"
|
||||||
|
WHITESPACE " "
|
||||||
|
EQ "="
|
||||||
|
WHITESPACE " "
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "S"
|
||||||
|
GENERIC_ARG_LIST
|
||||||
|
L_ANGLE "<"
|
||||||
|
TYPE_ARG
|
||||||
|
DYN_TRAIT_TYPE
|
||||||
|
TYPE_BOUND_LIST
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Fn"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
PARAM
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "i32"
|
||||||
|
R_PAREN ")"
|
||||||
|
WHITESPACE " "
|
||||||
|
PLUS "+"
|
||||||
|
WHITESPACE " "
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Send"
|
||||||
|
R_ANGLE ">"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
TYPE_ALIAS
|
||||||
|
TYPE_KW "type"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "B"
|
||||||
|
WHITESPACE " "
|
||||||
|
EQ "="
|
||||||
|
WHITESPACE " "
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "S"
|
||||||
|
GENERIC_ARG_LIST
|
||||||
|
L_ANGLE "<"
|
||||||
|
TYPE_ARG
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Fn"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
PARAM
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "i32"
|
||||||
|
R_PAREN ")"
|
||||||
|
WHITESPACE " "
|
||||||
|
RET_TYPE
|
||||||
|
THIN_ARROW "->"
|
||||||
|
WHITESPACE " "
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "i32"
|
||||||
|
R_ANGLE ">"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
TYPE_ALIAS
|
||||||
|
TYPE_KW "type"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "C"
|
||||||
|
WHITESPACE " "
|
||||||
|
EQ "="
|
||||||
|
WHITESPACE " "
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "S"
|
||||||
|
GENERIC_ARG_LIST
|
||||||
|
L_ANGLE "<"
|
||||||
|
TYPE_ARG
|
||||||
|
DYN_TRAIT_TYPE
|
||||||
|
TYPE_BOUND_LIST
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Fn"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
PARAM
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "i32"
|
||||||
|
R_PAREN ")"
|
||||||
|
WHITESPACE " "
|
||||||
|
RET_TYPE
|
||||||
|
THIN_ARROW "->"
|
||||||
|
WHITESPACE " "
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "i32"
|
||||||
|
WHITESPACE " "
|
||||||
|
PLUS "+"
|
||||||
|
WHITESPACE " "
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Send"
|
||||||
|
R_ANGLE ">"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
|
@ -0,0 +1,4 @@
|
||||||
|
type A = S<Fn(i32)>;
|
||||||
|
type A = S<Fn(i32) + Send>;
|
||||||
|
type B = S<Fn(i32) -> i32>;
|
||||||
|
type C = S<Fn(i32) -> i32 + Send>;
|
|
@ -51,7 +51,9 @@ TypeArg =
|
||||||
Type
|
Type
|
||||||
|
|
||||||
AssocTypeArg =
|
AssocTypeArg =
|
||||||
NameRef GenericArgList? (':' TypeBoundList | ('=' Type | ConstArg))
|
NameRef
|
||||||
|
(GenericArgList | ParamList RetType?)?
|
||||||
|
(':' TypeBoundList | ('=' Type | ConstArg))
|
||||||
|
|
||||||
LifetimeArg =
|
LifetimeArg =
|
||||||
Lifetime
|
Lifetime
|
||||||
|
@ -581,7 +583,7 @@ ImplTraitType =
|
||||||
'impl' TypeBoundList
|
'impl' TypeBoundList
|
||||||
|
|
||||||
DynTraitType =
|
DynTraitType =
|
||||||
'dyn' TypeBoundList
|
'dyn'? TypeBoundList
|
||||||
|
|
||||||
TypeBoundList =
|
TypeBoundList =
|
||||||
bounds:(TypeBound ('+' TypeBound)* '+'?)
|
bounds:(TypeBound ('+' TypeBound)* '+'?)
|
||||||
|
|
|
@ -121,6 +121,8 @@ impl ast::HasTypeBounds for AssocTypeArg {}
|
||||||
impl AssocTypeArg {
|
impl AssocTypeArg {
|
||||||
pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
|
pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
|
||||||
pub fn generic_arg_list(&self) -> Option<GenericArgList> { support::child(&self.syntax) }
|
pub fn generic_arg_list(&self) -> Option<GenericArgList> { support::child(&self.syntax) }
|
||||||
|
pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
|
||||||
|
pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
|
||||||
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
|
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
|
||||||
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
||||||
pub fn const_arg(&self) -> Option<ConstArg> { support::child(&self.syntax) }
|
pub fn const_arg(&self) -> Option<ConstArg> { support::child(&self.syntax) }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue