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);
|
m.complete(p, ITEM_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test impl_type_params
|
||||||
|
// impl<const N: u32> Bar<N> {}
|
||||||
fn choose_type_params_over_qpath(p: &Parser) -> bool {
|
fn choose_type_params_over_qpath(p: &Parser) -> bool {
|
||||||
// There's an ambiguity between generic parameters and qualified paths in impls.
|
// 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.
|
// 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):
|
// but not qualified paths (with one exception):
|
||||||
// `<` `>` - empty generic parameters
|
// `<` `>` - empty generic parameters
|
||||||
// `<` `#` - generic parameters with attributes
|
// `<` `#` - generic parameters with attributes
|
||||||
|
// `<` `const` - const generic parameters
|
||||||
// `<` (LIFETIME|IDENT) `>` - single generic parameter
|
// `<` (LIFETIME|IDENT) `>` - single generic parameter
|
||||||
// `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
|
// `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
|
||||||
// `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
|
// `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
|
||||||
|
@ -119,7 +122,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool {
|
||||||
if !p.at(T![<]) {
|
if !p.at(T![<]) {
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
(p.nth(1) == LIFETIME || p.nth(1) == IDENT)
|
(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
|
// 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) {
|
fn type_arg(p: &mut Parser) {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
match p.current() {
|
match p.current() {
|
||||||
|
@ -47,6 +47,14 @@ fn type_arg(p: &mut Parser) {
|
||||||
types::type_(p);
|
types::type_(p);
|
||||||
m.complete(p, ASSOC_TYPE_ARG);
|
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);
|
types::type_(p);
|
||||||
m.complete(p, TYPE_ARG);
|
m.complete(p, TYPE_ARG);
|
||||||
|
|
|
@ -234,6 +234,7 @@ pub enum SyntaxKind {
|
||||||
LIFETIME_ARG,
|
LIFETIME_ARG,
|
||||||
TYPE_ARG,
|
TYPE_ARG,
|
||||||
ASSOC_TYPE_ARG,
|
ASSOC_TYPE_ARG,
|
||||||
|
CONST_ARG,
|
||||||
PARAM_LIST,
|
PARAM_LIST,
|
||||||
PARAM,
|
PARAM,
|
||||||
SELF_PARAM,
|
SELF_PARAM,
|
||||||
|
|
|
@ -3114,6 +3114,9 @@ impl TypeArgList {
|
||||||
pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> {
|
pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> {
|
||||||
AstChildren::new(&self.syntax)
|
AstChildren::new(&self.syntax)
|
||||||
}
|
}
|
||||||
|
pub fn const_arg(&self) -> AstChildren<ConstArg> {
|
||||||
|
AstChildren::new(&self.syntax)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct TypeArg {
|
pub struct TypeArg {
|
||||||
|
@ -3196,6 +3199,36 @@ impl AstNode for LifetimeArg {
|
||||||
}
|
}
|
||||||
impl LifetimeArg {}
|
impl LifetimeArg {}
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[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 struct MacroItems {
|
||||||
pub(crate) syntax: SyntaxNode,
|
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)
|
SOURCE_FILE@[0; 46)
|
||||||
TYPE_ALIAS_DEF@[0; 35)
|
TYPE_ALIAS_DEF@[0; 45)
|
||||||
TYPE_KW@[0; 4) "type"
|
TYPE_KW@[0; 4) "type"
|
||||||
WHITESPACE@[4; 5) " "
|
WHITESPACE@[4; 5) " "
|
||||||
NAME@[5; 6)
|
NAME@[5; 6)
|
||||||
|
@ -7,12 +7,12 @@ SOURCE_FILE@[0; 36)
|
||||||
WHITESPACE@[6; 7) " "
|
WHITESPACE@[6; 7) " "
|
||||||
EQ@[7; 8) "="
|
EQ@[7; 8) "="
|
||||||
WHITESPACE@[8; 9) " "
|
WHITESPACE@[8; 9) " "
|
||||||
PATH_TYPE@[9; 34)
|
PATH_TYPE@[9; 44)
|
||||||
PATH@[9; 34)
|
PATH@[9; 44)
|
||||||
PATH_SEGMENT@[9; 34)
|
PATH_SEGMENT@[9; 44)
|
||||||
NAME_REF@[9; 10)
|
NAME_REF@[9; 10)
|
||||||
IDENT@[9; 10) "B"
|
IDENT@[9; 10) "B"
|
||||||
TYPE_ARG_LIST@[10; 34)
|
TYPE_ARG_LIST@[10; 44)
|
||||||
L_ANGLE@[10; 11) "<"
|
L_ANGLE@[10; 11) "<"
|
||||||
LIFETIME_ARG@[11; 18)
|
LIFETIME_ARG@[11; 18)
|
||||||
LIFETIME@[11; 18) "\'static"
|
LIFETIME@[11; 18) "\'static"
|
||||||
|
@ -26,15 +26,30 @@ SOURCE_FILE@[0; 36)
|
||||||
IDENT@[20; 23) "i32"
|
IDENT@[20; 23) "i32"
|
||||||
COMMA@[23; 24) ","
|
COMMA@[23; 24) ","
|
||||||
WHITESPACE@[24; 25) " "
|
WHITESPACE@[24; 25) " "
|
||||||
ASSOC_TYPE_ARG@[25; 33)
|
CONST_ARG@[25; 26)
|
||||||
NAME_REF@[25; 29)
|
INT_NUMBER@[25; 26) "1"
|
||||||
IDENT@[25; 29) "Item"
|
COMMA@[26; 27) ","
|
||||||
EQ@[29; 30) "="
|
WHITESPACE@[27; 28) " "
|
||||||
PATH_TYPE@[30; 33)
|
CONST_ARG@[28; 33)
|
||||||
PATH@[30; 33)
|
BLOCK_EXPR@[28; 33)
|
||||||
PATH_SEGMENT@[30; 33)
|
BLOCK@[28; 33)
|
||||||
NAME_REF@[30; 33)
|
L_CURLY@[28; 29) "{"
|
||||||
IDENT@[30; 33) "u64"
|
WHITESPACE@[29; 30) " "
|
||||||
R_ANGLE@[33; 34) ">"
|
LITERAL@[30; 31)
|
||||||
SEMI@[34; 35) ";"
|
INT_NUMBER@[30; 31) "2"
|
||||||
WHITESPACE@[35; 36) "\n"
|
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",
|
"LIFETIME_ARG",
|
||||||
"TYPE_ARG",
|
"TYPE_ARG",
|
||||||
"ASSOC_TYPE_ARG",
|
"ASSOC_TYPE_ARG",
|
||||||
|
"CONST_ARG",
|
||||||
"PARAM_LIST",
|
"PARAM_LIST",
|
||||||
"PARAM",
|
"PARAM",
|
||||||
"SELF_PARAM",
|
"SELF_PARAM",
|
||||||
|
@ -511,10 +512,12 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
|
||||||
type_args: [TypeArg],
|
type_args: [TypeArg],
|
||||||
lifetime_args: [LifetimeArg],
|
lifetime_args: [LifetimeArg],
|
||||||
assoc_type_args: [AssocTypeArg],
|
assoc_type_args: [AssocTypeArg],
|
||||||
|
const_arg: [ConstArg],
|
||||||
}
|
}
|
||||||
struct TypeArg { TypeRef }
|
struct TypeArg { TypeRef }
|
||||||
struct AssocTypeArg { NameRef, TypeRef }
|
struct AssocTypeArg { NameRef, TypeRef }
|
||||||
struct LifetimeArg {}
|
struct LifetimeArg {}
|
||||||
|
struct ConstArg { Literal, BlockExpr }
|
||||||
|
|
||||||
struct MacroItems: ModuleItemOwner, FnDefOwner { }
|
struct MacroItems: ModuleItemOwner, FnDefOwner { }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue