Auto merge of #14746 - lowr:patch/associated-return-types, r=Veykril
Parse associated return type bounds This PR implements parser support for associated return type bounds: `T: Foo<bar(): Send>`. This PR does not implement associated return types (`T::bar(): Send`) because it's not implemented even in rustc, and also removes `(..)`-style return type notation because it has been removed in rust-lang/rust#110203 (effectively reverting #14465). I don't plan to proactively follow this unstable feature unless an RFC is accepted and my main motivation here is to remove no-longer-valid syntax `(..)` from our parser, nevertheless adding minimal parser support so anyone interested (as can be seen in #14465) can experiment it without rust-analyzer's syntax errors.
This commit is contained in:
commit
bc03418127
14 changed files with 363 additions and 106 deletions
|
|
@ -189,6 +189,10 @@ pub(super) fn lower_generic_args(
|
|||
args.push(GenericArg::Type(type_ref));
|
||||
}
|
||||
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() {
|
||||
let name = name_ref.as_name();
|
||||
let args = assoc_type_arg
|
||||
|
|
@ -216,9 +220,6 @@ pub(super) fn lower_generic_args(
|
|||
let arg = ConstRefOrPath::from_expr_opt(arg.expr());
|
||||
args.push(GenericArg::Const(arg))
|
||||
}
|
||||
ast::GenericArg::ReturnTypeArg(_) => {
|
||||
// FIXME: return type notation is experimental, we don't do anything with it yet.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,29 @@ fn generic_arg(p: &mut Parser<'_>) -> bool {
|
|||
}
|
||||
}
|
||||
}
|
||||
IDENT if p.nth(1) == T!['('] && p.nth_at(2, T![..]) => return_type_arg(p),
|
||||
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),
|
||||
_ => return false,
|
||||
}
|
||||
|
|
@ -140,20 +162,3 @@ fn type_arg(p: &mut Parser<'_>) {
|
|||
types::type_(p);
|
||||
m.complete(p, TYPE_ARG);
|
||||
}
|
||||
|
||||
// test return_type_arg
|
||||
// type T = S<foo(..): Send>;
|
||||
pub(super) fn return_type_arg(p: &mut Parser<'_>) {
|
||||
let m = p.start();
|
||||
p.expect(IDENT);
|
||||
p.expect(T!['(']);
|
||||
p.expect(T![..]);
|
||||
p.expect(T![')']);
|
||||
if !p.at(T![:]) {
|
||||
p.error("expected :");
|
||||
m.abandon(p);
|
||||
return;
|
||||
}
|
||||
generic_params::bounds(p);
|
||||
m.complete(p, RETURN_TYPE_ARG);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ fn opt_path_type_args(p: &mut Parser<'_>, mode: Mode) {
|
|||
Mode::Type => {
|
||||
// test typepathfn_with_coloncolon
|
||||
// type F = Start::(Middle) -> (Middle)::End;
|
||||
// type GenericArg = S<Start(Middle)::End>;
|
||||
if p.at(T![::]) && p.nth_at(2, 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
|
||||
/// 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!(
|
||||
type_marker.kind(),
|
||||
SyntaxKind::PATH_TYPE | SyntaxKind::FOR_TYPE | SyntaxKind::MACRO_TYPE
|
||||
));
|
||||
if !p.at(T![+]) {
|
||||
return;
|
||||
return type_marker;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// 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"
|
||||
SEMICOLON ";"
|
||||
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 GenericArg = S<Start(Middle)::End>;
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
SOURCE_FILE
|
||||
TYPE_ALIAS
|
||||
TYPE_KW "type"
|
||||
WHITESPACE " "
|
||||
NAME
|
||||
IDENT "T"
|
||||
WHITESPACE " "
|
||||
EQ "="
|
||||
WHITESPACE " "
|
||||
PATH_TYPE
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "S"
|
||||
GENERIC_ARG_LIST
|
||||
L_ANGLE "<"
|
||||
RETURN_TYPE_ARG
|
||||
IDENT "foo"
|
||||
L_PAREN "("
|
||||
DOT2 ".."
|
||||
R_PAREN ")"
|
||||
COLON ":"
|
||||
WHITESPACE " "
|
||||
TYPE_BOUND_LIST
|
||||
TYPE_BOUND
|
||||
PATH_TYPE
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "Send"
|
||||
R_ANGLE ">"
|
||||
SEMICOLON ";"
|
||||
WHITESPACE "\n"
|
||||
|
|
@ -1 +0,0 @@
|
|||
type T = S<foo(..): Send>;
|
||||
|
|
@ -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>;
|
||||
|
|
@ -46,13 +46,14 @@ GenericArg =
|
|||
| AssocTypeArg
|
||||
| LifetimeArg
|
||||
| ConstArg
|
||||
| ReturnTypeArg
|
||||
|
||||
TypeArg =
|
||||
Type
|
||||
|
||||
AssocTypeArg =
|
||||
NameRef GenericArgList? (':' TypeBoundList | ('=' Type | ConstArg))
|
||||
NameRef
|
||||
(GenericArgList | ParamList RetType?)?
|
||||
(':' TypeBoundList | ('=' Type | ConstArg))
|
||||
|
||||
LifetimeArg =
|
||||
Lifetime
|
||||
|
|
@ -60,9 +61,6 @@ LifetimeArg =
|
|||
ConstArg =
|
||||
Expr
|
||||
|
||||
ReturnTypeArg =
|
||||
NameRef '(' '..' ')' ':' TypeBoundList
|
||||
|
||||
MacroCall =
|
||||
Attr* Path '!' TokenTree ';'?
|
||||
|
||||
|
|
@ -585,7 +583,7 @@ ImplTraitType =
|
|||
'impl' TypeBoundList
|
||||
|
||||
DynTraitType =
|
||||
'dyn' TypeBoundList
|
||||
'dyn'? TypeBoundList
|
||||
|
||||
TypeBoundList =
|
||||
bounds:(TypeBound ('+' TypeBound)* '+'?)
|
||||
|
|
|
|||
|
|
@ -121,6 +121,8 @@ impl ast::HasTypeBounds for AssocTypeArg {}
|
|||
impl AssocTypeArg {
|
||||
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 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 ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
||||
pub fn const_arg(&self) -> Option<ConstArg> { support::child(&self.syntax) }
|
||||
|
|
@ -142,18 +144,6 @@ impl ConstArg {
|
|||
pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ReturnTypeArg {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl ast::HasTypeBounds for ReturnTypeArg {}
|
||||
impl ReturnTypeArg {
|
||||
pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
|
||||
pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
|
||||
pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
|
||||
pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TypeBoundList {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
|
|
@ -1528,7 +1518,6 @@ pub enum GenericArg {
|
|||
AssocTypeArg(AssocTypeArg),
|
||||
LifetimeArg(LifetimeArg),
|
||||
ConstArg(ConstArg),
|
||||
ReturnTypeArg(ReturnTypeArg),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
@ -1878,17 +1867,6 @@ impl AstNode for ConstArg {
|
|||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for ReturnTypeArg {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == RETURN_TYPE_ARG }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for TypeBoundList {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND_LIST }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
|
|
@ -3243,12 +3221,9 @@ impl From<LifetimeArg> for GenericArg {
|
|||
impl From<ConstArg> for GenericArg {
|
||||
fn from(node: ConstArg) -> GenericArg { GenericArg::ConstArg(node) }
|
||||
}
|
||||
impl From<ReturnTypeArg> for GenericArg {
|
||||
fn from(node: ReturnTypeArg) -> GenericArg { GenericArg::ReturnTypeArg(node) }
|
||||
}
|
||||
impl AstNode for GenericArg {
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
matches!(kind, TYPE_ARG | ASSOC_TYPE_ARG | LIFETIME_ARG | CONST_ARG | RETURN_TYPE_ARG)
|
||||
matches!(kind, TYPE_ARG | ASSOC_TYPE_ARG | LIFETIME_ARG | CONST_ARG)
|
||||
}
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
let res = match syntax.kind() {
|
||||
|
|
@ -3256,7 +3231,6 @@ impl AstNode for GenericArg {
|
|||
ASSOC_TYPE_ARG => GenericArg::AssocTypeArg(AssocTypeArg { syntax }),
|
||||
LIFETIME_ARG => GenericArg::LifetimeArg(LifetimeArg { syntax }),
|
||||
CONST_ARG => GenericArg::ConstArg(ConstArg { syntax }),
|
||||
RETURN_TYPE_ARG => GenericArg::ReturnTypeArg(ReturnTypeArg { syntax }),
|
||||
_ => return None,
|
||||
};
|
||||
Some(res)
|
||||
|
|
@ -3267,7 +3241,6 @@ impl AstNode for GenericArg {
|
|||
GenericArg::AssocTypeArg(it) => &it.syntax,
|
||||
GenericArg::LifetimeArg(it) => &it.syntax,
|
||||
GenericArg::ConstArg(it) => &it.syntax,
|
||||
GenericArg::ReturnTypeArg(it) => &it.syntax,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4199,13 +4172,7 @@ impl AstNode for AnyHasTypeBounds {
|
|||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
matches!(
|
||||
kind,
|
||||
ASSOC_TYPE_ARG
|
||||
| RETURN_TYPE_ARG
|
||||
| TRAIT
|
||||
| TYPE_ALIAS
|
||||
| LIFETIME_PARAM
|
||||
| TYPE_PARAM
|
||||
| WHERE_PRED
|
||||
ASSOC_TYPE_ARG | TRAIT | TYPE_ALIAS | LIFETIME_PARAM | TYPE_PARAM | WHERE_PRED
|
||||
)
|
||||
}
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
|
|
@ -4368,11 +4335,6 @@ impl std::fmt::Display for ConstArg {
|
|||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for ReturnTypeArg {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for TypeBoundList {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue