mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
Improve const generics parsing
- Handle const generics type args - Fix issue with const generic as first parameter in trait impl
This commit is contained in:
parent
c92a090f49
commit
ce1b34fd59
9 changed files with 123 additions and 21 deletions
|
@ -100,6 +100,8 @@ pub(crate) fn impl_item_list(p: &mut Parser) {
|
|||
m.complete(p, ITEM_LIST);
|
||||
}
|
||||
|
||||
// test impl_type_params
|
||||
// impl<const N: u32> Bar<N> {}
|
||||
fn choose_type_params_over_qpath(p: &Parser) -> bool {
|
||||
// There's an ambiguity between generic parameters and qualified paths in impls.
|
||||
// If we see `<` it may start both, so we have to inspect some following tokens.
|
||||
|
@ -107,6 +109,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool {
|
|||
// but not qualified paths (with one exception):
|
||||
// `<` `>` - empty generic parameters
|
||||
// `<` `#` - generic parameters with attributes
|
||||
// `<` `const` - const generic parameters
|
||||
// `<` (LIFETIME|IDENT) `>` - single generic parameter
|
||||
// `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
|
||||
// `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
|
||||
|
@ -119,7 +122,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool {
|
|||
if !p.at(T![<]) {
|
||||
return false;
|
||||
}
|
||||
if p.nth(1) == T![#] || p.nth(1) == T![>] {
|
||||
if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == CONST_KW {
|
||||
return true;
|
||||
}
|
||||
(p.nth(1) == LIFETIME || p.nth(1) == IDENT)
|
||||
|
|
|
@ -26,7 +26,7 @@ pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) {
|
|||
}
|
||||
|
||||
// test type_arg
|
||||
// type A = B<'static, i32, Item=u64>;
|
||||
// type A = B<'static, i32, 1, { 2 }, Item=u64>;
|
||||
fn type_arg(p: &mut Parser) {
|
||||
let m = p.start();
|
||||
match p.current() {
|
||||
|
@ -47,6 +47,14 @@ fn type_arg(p: &mut Parser) {
|
|||
types::type_(p);
|
||||
m.complete(p, ASSOC_TYPE_ARG);
|
||||
}
|
||||
T!['{'] => {
|
||||
expressions::block(p);
|
||||
m.complete(p, CONST_ARG);
|
||||
}
|
||||
k if k.is_literal() => {
|
||||
p.bump(k);
|
||||
m.complete(p, CONST_ARG);
|
||||
}
|
||||
_ => {
|
||||
types::type_(p);
|
||||
m.complete(p, TYPE_ARG);
|
||||
|
|
|
@ -234,6 +234,7 @@ pub enum SyntaxKind {
|
|||
LIFETIME_ARG,
|
||||
TYPE_ARG,
|
||||
ASSOC_TYPE_ARG,
|
||||
CONST_ARG,
|
||||
PARAM_LIST,
|
||||
PARAM,
|
||||
SELF_PARAM,
|
||||
|
|
|
@ -3114,6 +3114,9 @@ impl TypeArgList {
|
|||
pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> {
|
||||
AstChildren::new(&self.syntax)
|
||||
}
|
||||
pub fn const_arg(&self) -> AstChildren<ConstArg> {
|
||||
AstChildren::new(&self.syntax)
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TypeArg {
|
||||
|
@ -3196,6 +3199,36 @@ impl AstNode for LifetimeArg {
|
|||
}
|
||||
impl LifetimeArg {}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ConstArg {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl AstNode for ConstArg {
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
CONST_ARG => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode {
|
||||
&self.syntax
|
||||
}
|
||||
}
|
||||
impl ConstArg {
|
||||
pub fn literal(&self) -> Option<Literal> {
|
||||
AstChildren::new(&self.syntax).next()
|
||||
}
|
||||
pub fn block_expr(&self) -> Option<BlockExpr> {
|
||||
AstChildren::new(&self.syntax).next()
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct MacroItems {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
type A = B<'static, i32, Item=u64>;
|
||||
type A = B<'static, i32, 1, { 2 }, Item=u64>;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
SOURCE_FILE@[0; 36)
|
||||
TYPE_ALIAS_DEF@[0; 35)
|
||||
SOURCE_FILE@[0; 46)
|
||||
TYPE_ALIAS_DEF@[0; 45)
|
||||
TYPE_KW@[0; 4) "type"
|
||||
WHITESPACE@[4; 5) " "
|
||||
NAME@[5; 6)
|
||||
|
@ -7,12 +7,12 @@ SOURCE_FILE@[0; 36)
|
|||
WHITESPACE@[6; 7) " "
|
||||
EQ@[7; 8) "="
|
||||
WHITESPACE@[8; 9) " "
|
||||
PATH_TYPE@[9; 34)
|
||||
PATH@[9; 34)
|
||||
PATH_SEGMENT@[9; 34)
|
||||
PATH_TYPE@[9; 44)
|
||||
PATH@[9; 44)
|
||||
PATH_SEGMENT@[9; 44)
|
||||
NAME_REF@[9; 10)
|
||||
IDENT@[9; 10) "B"
|
||||
TYPE_ARG_LIST@[10; 34)
|
||||
TYPE_ARG_LIST@[10; 44)
|
||||
L_ANGLE@[10; 11) "<"
|
||||
LIFETIME_ARG@[11; 18)
|
||||
LIFETIME@[11; 18) "\'static"
|
||||
|
@ -26,15 +26,30 @@ SOURCE_FILE@[0; 36)
|
|||
IDENT@[20; 23) "i32"
|
||||
COMMA@[23; 24) ","
|
||||
WHITESPACE@[24; 25) " "
|
||||
ASSOC_TYPE_ARG@[25; 33)
|
||||
NAME_REF@[25; 29)
|
||||
IDENT@[25; 29) "Item"
|
||||
EQ@[29; 30) "="
|
||||
PATH_TYPE@[30; 33)
|
||||
PATH@[30; 33)
|
||||
PATH_SEGMENT@[30; 33)
|
||||
NAME_REF@[30; 33)
|
||||
IDENT@[30; 33) "u64"
|
||||
R_ANGLE@[33; 34) ">"
|
||||
SEMI@[34; 35) ";"
|
||||
WHITESPACE@[35; 36) "\n"
|
||||
CONST_ARG@[25; 26)
|
||||
INT_NUMBER@[25; 26) "1"
|
||||
COMMA@[26; 27) ","
|
||||
WHITESPACE@[27; 28) " "
|
||||
CONST_ARG@[28; 33)
|
||||
BLOCK_EXPR@[28; 33)
|
||||
BLOCK@[28; 33)
|
||||
L_CURLY@[28; 29) "{"
|
||||
WHITESPACE@[29; 30) " "
|
||||
LITERAL@[30; 31)
|
||||
INT_NUMBER@[30; 31) "2"
|
||||
WHITESPACE@[31; 32) " "
|
||||
R_CURLY@[32; 33) "}"
|
||||
COMMA@[33; 34) ","
|
||||
WHITESPACE@[34; 35) " "
|
||||
ASSOC_TYPE_ARG@[35; 43)
|
||||
NAME_REF@[35; 39)
|
||||
IDENT@[35; 39) "Item"
|
||||
EQ@[39; 40) "="
|
||||
PATH_TYPE@[40; 43)
|
||||
PATH@[40; 43)
|
||||
PATH_SEGMENT@[40; 43)
|
||||
NAME_REF@[40; 43)
|
||||
IDENT@[40; 43) "u64"
|
||||
R_ANGLE@[43; 44) ">"
|
||||
SEMI@[44; 45) ";"
|
||||
WHITESPACE@[45; 46) "\n"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
impl<const N: u32> Bar<N> {}
|
|
@ -0,0 +1,38 @@
|
|||
SOURCE_FILE@[0; 29)
|
||||
IMPL_BLOCK@[0; 28)
|
||||
IMPL_KW@[0; 4) "impl"
|
||||
TYPE_PARAM_LIST@[4; 18)
|
||||
L_ANGLE@[4; 5) "<"
|
||||
CONST_PARAM@[5; 17)
|
||||
CONST_KW@[5; 10) "const"
|
||||
WHITESPACE@[10; 11) " "
|
||||
NAME@[11; 12)
|
||||
IDENT@[11; 12) "N"
|
||||
COLON@[12; 13) ":"
|
||||
WHITESPACE@[13; 14) " "
|
||||
PATH_TYPE@[14; 17)
|
||||
PATH@[14; 17)
|
||||
PATH_SEGMENT@[14; 17)
|
||||
NAME_REF@[14; 17)
|
||||
IDENT@[14; 17) "u32"
|
||||
R_ANGLE@[17; 18) ">"
|
||||
WHITESPACE@[18; 19) " "
|
||||
PATH_TYPE@[19; 25)
|
||||
PATH@[19; 25)
|
||||
PATH_SEGMENT@[19; 25)
|
||||
NAME_REF@[19; 22)
|
||||
IDENT@[19; 22) "Bar"
|
||||
TYPE_ARG_LIST@[22; 25)
|
||||
L_ANGLE@[22; 23) "<"
|
||||
TYPE_ARG@[23; 24)
|
||||
PATH_TYPE@[23; 24)
|
||||
PATH@[23; 24)
|
||||
PATH_SEGMENT@[23; 24)
|
||||
NAME_REF@[23; 24)
|
||||
IDENT@[23; 24) "N"
|
||||
R_ANGLE@[24; 25) ">"
|
||||
WHITESPACE@[25; 26) " "
|
||||
ITEM_LIST@[26; 28)
|
||||
L_CURLY@[26; 27) "{"
|
||||
R_CURLY@[27; 28) "}"
|
||||
WHITESPACE@[28; 29) "\n"
|
|
@ -206,6 +206,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
|
|||
"LIFETIME_ARG",
|
||||
"TYPE_ARG",
|
||||
"ASSOC_TYPE_ARG",
|
||||
"CONST_ARG",
|
||||
"PARAM_LIST",
|
||||
"PARAM",
|
||||
"SELF_PARAM",
|
||||
|
@ -511,10 +512,12 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
|
|||
type_args: [TypeArg],
|
||||
lifetime_args: [LifetimeArg],
|
||||
assoc_type_args: [AssocTypeArg],
|
||||
const_arg: [ConstArg],
|
||||
}
|
||||
struct TypeArg { TypeRef }
|
||||
struct AssocTypeArg { NameRef, TypeRef }
|
||||
struct LifetimeArg {}
|
||||
struct ConstArg { Literal, BlockExpr }
|
||||
|
||||
struct MacroItems: ModuleItemOwner, FnDefOwner { }
|
||||
|
||||
|
|
Loading…
Reference in a new issue