mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 21:13:37 +00:00
Fix Return Type Syntax to include ..
(i.e. method(..)
and not method()
) as specified in the RFC
This commit is contained in:
parent
7106cd3be5
commit
21e6058ab7
12 changed files with 183 additions and 16 deletions
|
@ -102,13 +102,18 @@ fn generic_arg(p: &mut Parser<'_>) -> bool {
|
||||||
IDENT if p.nth_at(1, T!['(']) => {
|
IDENT if p.nth_at(1, T!['(']) => {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
name_ref(p);
|
name_ref(p);
|
||||||
params::param_list_fn_trait(p);
|
if p.nth_at(1, T![..]) {
|
||||||
if p.at(T![:]) && !p.at(T![::]) {
|
let rtn = p.start();
|
||||||
// test associated_return_type_bounds
|
p.bump(T!['(']);
|
||||||
// fn foo<T: Foo<foo(): Send, bar(i32): Send, baz(i32, i32): Send>>() {}
|
p.bump(T![..]);
|
||||||
|
p.expect(T![')']);
|
||||||
|
rtn.complete(p, RETURN_TYPE_SYNTAX);
|
||||||
|
// test return_type_syntax_assoc_type_bound
|
||||||
|
// fn foo<T: Trait<method(..): Send>>() {}
|
||||||
generic_params::bounds(p);
|
generic_params::bounds(p);
|
||||||
m.complete(p, ASSOC_TYPE_ARG);
|
m.complete(p, ASSOC_TYPE_ARG);
|
||||||
} else {
|
} else {
|
||||||
|
params::param_list_fn_trait(p);
|
||||||
// test bare_dyn_types_with_paren_as_generic_args
|
// test bare_dyn_types_with_paren_as_generic_args
|
||||||
// type A = S<Fn(i32)>;
|
// type A = S<Fn(i32)>;
|
||||||
// type A = S<Fn(i32) + Send>;
|
// type A = S<Fn(i32) + Send>;
|
||||||
|
|
|
@ -119,8 +119,7 @@ fn lifetime_bounds(p: &mut Parser<'_>) {
|
||||||
// test type_param_bounds
|
// test type_param_bounds
|
||||||
// struct S<T: 'a + ?Sized + (Copy) + ~const Drop>;
|
// struct S<T: 'a + ?Sized + (Copy) + ~const Drop>;
|
||||||
pub(super) fn bounds(p: &mut Parser<'_>) {
|
pub(super) fn bounds(p: &mut Parser<'_>) {
|
||||||
assert!(p.at(T![:]));
|
p.expect(T![:]);
|
||||||
p.bump(T![:]);
|
|
||||||
bounds_without_colon(p);
|
bounds_without_colon(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,11 +140,24 @@ fn opt_path_type_args(p: &mut Parser<'_>, mode: Mode) {
|
||||||
if p.at(T![::]) && p.nth_at(2, T!['(']) {
|
if p.at(T![::]) && p.nth_at(2, T!['(']) {
|
||||||
p.bump(T![::]);
|
p.bump(T![::]);
|
||||||
}
|
}
|
||||||
// test path_fn_trait_args
|
|
||||||
// type F = Box<Fn(i32) -> ()>;
|
|
||||||
if p.at(T!['(']) {
|
if p.at(T!['(']) {
|
||||||
params::param_list_fn_trait(p);
|
if p.nth_at(1, T![..]) {
|
||||||
opt_ret_type(p);
|
// test return_type_syntax_in_path
|
||||||
|
// fn foo<T>()
|
||||||
|
// where
|
||||||
|
// T::method(..): Send,
|
||||||
|
// {}
|
||||||
|
let rtn = p.start();
|
||||||
|
p.bump(T!['(']);
|
||||||
|
p.bump(T![..]);
|
||||||
|
p.expect(T![')']);
|
||||||
|
rtn.complete(p, RETURN_TYPE_SYNTAX);
|
||||||
|
} else {
|
||||||
|
// test path_fn_trait_args
|
||||||
|
// type F = Box<Fn(i32) -> ()>;
|
||||||
|
params::param_list_fn_trait(p);
|
||||||
|
opt_ret_type(p);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
generic_args::opt_generic_arg_list(p, false);
|
generic_args::opt_generic_arg_list(p, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,7 @@ pub enum SyntaxKind {
|
||||||
RENAME,
|
RENAME,
|
||||||
REST_PAT,
|
REST_PAT,
|
||||||
RETURN_EXPR,
|
RETURN_EXPR,
|
||||||
|
RETURN_TYPE_SYNTAX,
|
||||||
RET_TYPE,
|
RET_TYPE,
|
||||||
SELF_PARAM,
|
SELF_PARAM,
|
||||||
SLICE_PAT,
|
SLICE_PAT,
|
||||||
|
|
|
@ -37,10 +37,6 @@ mod ok {
|
||||||
#[test]
|
#[test]
|
||||||
fn assoc_type_eq() { run_and_expect_no_errors("test_data/parser/inline/ok/assoc_type_eq.rs"); }
|
fn assoc_type_eq() { run_and_expect_no_errors("test_data/parser/inline/ok/assoc_type_eq.rs"); }
|
||||||
#[test]
|
#[test]
|
||||||
fn associated_return_type_bounds() {
|
|
||||||
run_and_expect_no_errors("test_data/parser/inline/ok/associated_return_type_bounds.rs");
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn associated_type_bounds() {
|
fn associated_type_bounds() {
|
||||||
run_and_expect_no_errors("test_data/parser/inline/ok/associated_type_bounds.rs");
|
run_and_expect_no_errors("test_data/parser/inline/ok/associated_type_bounds.rs");
|
||||||
}
|
}
|
||||||
|
@ -519,6 +515,16 @@ mod ok {
|
||||||
#[test]
|
#[test]
|
||||||
fn return_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/return_expr.rs"); }
|
fn return_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/return_expr.rs"); }
|
||||||
#[test]
|
#[test]
|
||||||
|
fn return_type_syntax_assoc_type_bound() {
|
||||||
|
run_and_expect_no_errors(
|
||||||
|
"test_data/parser/inline/ok/return_type_syntax_assoc_type_bound.rs",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn return_type_syntax_in_path() {
|
||||||
|
run_and_expect_no_errors("test_data/parser/inline/ok/return_type_syntax_in_path.rs");
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
fn self_param() { run_and_expect_no_errors("test_data/parser/inline/ok/self_param.rs"); }
|
fn self_param() { run_and_expect_no_errors("test_data/parser/inline/ok/self_param.rs"); }
|
||||||
#[test]
|
#[test]
|
||||||
fn self_param_outer_attr() {
|
fn self_param_outer_attr() {
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
fn foo<T: Foo<foo(): Send, bar(i32): Send, baz(i32, i32): Send>>() {}
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
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 "Trait"
|
||||||
|
GENERIC_ARG_LIST
|
||||||
|
L_ANGLE "<"
|
||||||
|
ASSOC_TYPE_ARG
|
||||||
|
NAME_REF
|
||||||
|
IDENT "method"
|
||||||
|
RETURN_TYPE_SYNTAX
|
||||||
|
L_PAREN "("
|
||||||
|
DOT2 ".."
|
||||||
|
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: Trait<method(..): Send>>() {}
|
|
@ -0,0 +1,50 @@
|
||||||
|
SOURCE_FILE
|
||||||
|
FN
|
||||||
|
FN_KW "fn"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "foo"
|
||||||
|
GENERIC_PARAM_LIST
|
||||||
|
L_ANGLE "<"
|
||||||
|
TYPE_PARAM
|
||||||
|
NAME
|
||||||
|
IDENT "T"
|
||||||
|
R_ANGLE ">"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
R_PAREN ")"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
WHERE_CLAUSE
|
||||||
|
WHERE_KW "where"
|
||||||
|
WHITESPACE "\n "
|
||||||
|
WHERE_PRED
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "T"
|
||||||
|
COLON2 "::"
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "method"
|
||||||
|
RETURN_TYPE_SYNTAX
|
||||||
|
L_PAREN "("
|
||||||
|
DOT2 ".."
|
||||||
|
R_PAREN ")"
|
||||||
|
COLON ":"
|
||||||
|
WHITESPACE " "
|
||||||
|
TYPE_BOUND_LIST
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Send"
|
||||||
|
COMMA ","
|
||||||
|
WHITESPACE "\n"
|
||||||
|
BLOCK_EXPR
|
||||||
|
STMT_LIST
|
||||||
|
L_CURLY "{"
|
||||||
|
R_CURLY "}"
|
||||||
|
WHITESPACE "\n"
|
|
@ -0,0 +1,4 @@
|
||||||
|
fn foo<T>()
|
||||||
|
where
|
||||||
|
T::method(..): Send,
|
||||||
|
{}
|
|
@ -38,8 +38,12 @@ PathSegment =
|
||||||
'::'? NameRef
|
'::'? NameRef
|
||||||
| NameRef GenericArgList?
|
| NameRef GenericArgList?
|
||||||
| NameRef ParamList RetType?
|
| NameRef ParamList RetType?
|
||||||
|
| NameRef ReturnTypeSyntax
|
||||||
| '<' Type ('as' PathType)? '>'
|
| '<' Type ('as' PathType)? '>'
|
||||||
|
|
||||||
|
ReturnTypeSyntax =
|
||||||
|
'(' '..' ')'
|
||||||
|
|
||||||
|
|
||||||
//*************************//
|
//*************************//
|
||||||
// Generics //
|
// Generics //
|
||||||
|
@ -59,7 +63,7 @@ TypeArg =
|
||||||
|
|
||||||
AssocTypeArg =
|
AssocTypeArg =
|
||||||
NameRef
|
NameRef
|
||||||
(GenericArgList | ParamList RetType?)?
|
(GenericArgList | ParamList RetType? | ReturnTypeSyntax)?
|
||||||
(':' TypeBoundList | ('=' Type | ConstArg))
|
(':' TypeBoundList | ('=' Type | ConstArg))
|
||||||
|
|
||||||
LifetimeArg =
|
LifetimeArg =
|
||||||
|
|
|
@ -114,6 +114,8 @@ impl AssocTypeArg {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
|
pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn return_type_syntax(&self) -> Option<ReturnTypeSyntax> { support::child(&self.syntax) }
|
||||||
|
#[inline]
|
||||||
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
|
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
|
||||||
|
@ -1221,6 +1223,8 @@ impl PathSegment {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
|
pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn return_type_syntax(&self) -> Option<ReturnTypeSyntax> { support::child(&self.syntax) }
|
||||||
|
#[inline]
|
||||||
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
|
pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
|
||||||
|
@ -1485,6 +1489,19 @@ impl ReturnExpr {
|
||||||
pub fn return_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![return]) }
|
pub fn return_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![return]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct ReturnTypeSyntax {
|
||||||
|
pub(crate) syntax: SyntaxNode,
|
||||||
|
}
|
||||||
|
impl ReturnTypeSyntax {
|
||||||
|
#[inline]
|
||||||
|
pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
|
||||||
|
#[inline]
|
||||||
|
pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
|
||||||
|
#[inline]
|
||||||
|
pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct SelfParam {
|
pub struct SelfParam {
|
||||||
pub(crate) syntax: SyntaxNode,
|
pub(crate) syntax: SyntaxNode,
|
||||||
|
@ -3697,6 +3714,20 @@ impl AstNode for ReturnExpr {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||||
}
|
}
|
||||||
|
impl AstNode for ReturnTypeSyntax {
|
||||||
|
#[inline]
|
||||||
|
fn can_cast(kind: SyntaxKind) -> bool { kind == RETURN_TYPE_SYNTAX }
|
||||||
|
#[inline]
|
||||||
|
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||||
|
if Self::can_cast(syntax.kind()) {
|
||||||
|
Some(Self { syntax })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||||
|
}
|
||||||
impl AstNode for SelfParam {
|
impl AstNode for SelfParam {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn can_cast(kind: SyntaxKind) -> bool { kind == SELF_PARAM }
|
fn can_cast(kind: SyntaxKind) -> bool { kind == SELF_PARAM }
|
||||||
|
@ -6609,6 +6640,11 @@ impl std::fmt::Display for ReturnExpr {
|
||||||
std::fmt::Display::fmt(self.syntax(), f)
|
std::fmt::Display::fmt(self.syntax(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl std::fmt::Display for ReturnTypeSyntax {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(self.syntax(), f)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl std::fmt::Display for SelfParam {
|
impl std::fmt::Display for SelfParam {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
std::fmt::Display::fmt(self.syntax(), f)
|
std::fmt::Display::fmt(self.syntax(), f)
|
||||||
|
|
Loading…
Reference in a new issue