Skip to content

Commit 040b4c8

Browse files
committed
Fix GenericArgs grammar
1 parent d21b5db commit 040b4c8

File tree

4 files changed

+107
-50
lines changed

4 files changed

+107
-50
lines changed

crates/ra_assists/src/ast_transform.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,25 @@ impl<'a> SubstituteTypeParams<'a> {
7979
};
8080

8181
// FIXME: It would probably be nicer if we could get this via HIR (i.e. get the
82-
// trait ref, and then go from the types in the substs back to the syntax)
82+
// trait ref, and then go from the types in the substs back to the syntax).
8383
fn get_syntactic_substs(impl_def: ast::Impl) -> Option<Vec<ast::Type>> {
8484
let target_trait = impl_def.target_trait()?;
8585
let path_type = match target_trait {
8686
ast::Type::PathType(path) => path,
8787
_ => return None,
8888
};
89-
let type_arg_list = path_type.path()?.segment()?.generic_arg_list()?;
89+
let generic_arg_list = path_type.path()?.segment()?.generic_arg_list()?;
90+
9091
let mut result = Vec::new();
91-
for type_arg in type_arg_list.type_args() {
92-
let type_arg: ast::TypeArg = type_arg;
93-
result.push(type_arg.ty()?);
92+
for generic_arg in generic_arg_list.generic_args() {
93+
match generic_arg {
94+
ast::GenericArg::TypeArg(type_arg) => result.push(type_arg.ty()?),
95+
ast::GenericArg::AssocTypeArg(_)
96+
| ast::GenericArg::LifetimeArg(_)
97+
| ast::GenericArg::ConstArg(_) => (),
98+
}
9499
}
100+
95101
Some(result)
96102
}
97103
}

crates/ra_hir_def/src/path/lower.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -151,30 +151,34 @@ pub(super) fn lower_generic_args(
151151
node: ast::GenericArgList,
152152
) -> Option<GenericArgs> {
153153
let mut args = Vec::new();
154-
for type_arg in node.type_args() {
155-
let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.ty());
156-
args.push(GenericArg::Type(type_ref));
157-
}
158-
// lifetimes ignored for now
159154
let mut bindings = Vec::new();
160-
for assoc_type_arg in node.assoc_type_args() {
161-
let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg;
162-
if let Some(name_ref) = assoc_type_arg.name_ref() {
163-
let name = name_ref.as_name();
164-
let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
165-
let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
166-
l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
167-
} else {
168-
Vec::new()
169-
};
170-
bindings.push(AssociatedTypeBinding { name, type_ref, bounds });
155+
for generic_arg in node.generic_args() {
156+
match generic_arg {
157+
ast::GenericArg::TypeArg(type_arg) => {
158+
let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.ty());
159+
args.push(GenericArg::Type(type_ref));
160+
}
161+
ast::GenericArg::AssocTypeArg(assoc_type_arg) => {
162+
if let Some(name_ref) = assoc_type_arg.name_ref() {
163+
let name = name_ref.as_name();
164+
let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
165+
let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
166+
l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
167+
} else {
168+
Vec::new()
169+
};
170+
bindings.push(AssociatedTypeBinding { name, type_ref, bounds });
171+
}
172+
}
173+
// Lifetimes and constants are ignored for now.
174+
ast::GenericArg::LifetimeArg(_) | ast::GenericArg::ConstArg(_) => (),
171175
}
172176
}
177+
173178
if args.is_empty() && bindings.is_empty() {
174-
None
175-
} else {
176-
Some(GenericArgs { args, has_self_type: false, bindings })
179+
return None;
177180
}
181+
Some(GenericArgs { args, has_self_type: false, bindings })
178182
}
179183

180184
/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)

crates/ra_syntax/src/ast/generated/nodes.rs

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@ pub struct GenericArgList {
4646
impl GenericArgList {
4747
pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
4848
pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
49-
pub fn type_args(&self) -> AstChildren<TypeArg> { support::children(&self.syntax) }
50-
pub fn lifetime_args(&self) -> AstChildren<LifetimeArg> { support::children(&self.syntax) }
51-
pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> { support::children(&self.syntax) }
52-
pub fn const_args(&self) -> AstChildren<ConstArg> { support::children(&self.syntax) }
49+
pub fn generic_args(&self) -> AstChildren<GenericArg> { support::children(&self.syntax) }
5350
pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
5451
}
5552
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -86,15 +83,6 @@ impl TypeArg {
8683
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
8784
}
8885
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
89-
pub struct LifetimeArg {
90-
pub(crate) syntax: SyntaxNode,
91-
}
92-
impl LifetimeArg {
93-
pub fn lifetime_token(&self) -> Option<SyntaxToken> {
94-
support::token(&self.syntax, T![lifetime])
95-
}
96-
}
97-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9886
pub struct AssocTypeArg {
9987
pub(crate) syntax: SyntaxNode,
10088
}
@@ -105,6 +93,15 @@ impl AssocTypeArg {
10593
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
10694
}
10795
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
96+
pub struct LifetimeArg {
97+
pub(crate) syntax: SyntaxNode,
98+
}
99+
impl LifetimeArg {
100+
pub fn lifetime_token(&self) -> Option<SyntaxToken> {
101+
support::token(&self.syntax, T![lifetime])
102+
}
103+
}
104+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
108105
pub struct ConstArg {
109106
pub(crate) syntax: SyntaxNode,
110107
}
@@ -1272,6 +1269,13 @@ impl MacroStmts {
12721269
pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
12731270
}
12741271
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1272+
pub enum GenericArg {
1273+
TypeArg(TypeArg),
1274+
AssocTypeArg(AssocTypeArg),
1275+
LifetimeArg(LifetimeArg),
1276+
ConstArg(ConstArg),
1277+
}
1278+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12751279
pub enum Type {
12761280
ArrayType(ArrayType),
12771281
DynTraitType(DynTraitType),
@@ -1489,8 +1493,8 @@ impl AstNode for TypeArg {
14891493
}
14901494
fn syntax(&self) -> &SyntaxNode { &self.syntax }
14911495
}
1492-
impl AstNode for LifetimeArg {
1493-
fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME_ARG }
1496+
impl AstNode for AssocTypeArg {
1497+
fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_TYPE_ARG }
14941498
fn cast(syntax: SyntaxNode) -> Option<Self> {
14951499
if Self::can_cast(syntax.kind()) {
14961500
Some(Self { syntax })
@@ -1500,8 +1504,8 @@ impl AstNode for LifetimeArg {
15001504
}
15011505
fn syntax(&self) -> &SyntaxNode { &self.syntax }
15021506
}
1503-
impl AstNode for AssocTypeArg {
1504-
fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_TYPE_ARG }
1507+
impl AstNode for LifetimeArg {
1508+
fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME_ARG }
15051509
fn cast(syntax: SyntaxNode) -> Option<Self> {
15061510
if Self::can_cast(syntax.kind()) {
15071511
Some(Self { syntax })
@@ -2765,6 +2769,44 @@ impl AstNode for MacroStmts {
27652769
}
27662770
fn syntax(&self) -> &SyntaxNode { &self.syntax }
27672771
}
2772+
impl From<TypeArg> for GenericArg {
2773+
fn from(node: TypeArg) -> GenericArg { GenericArg::TypeArg(node) }
2774+
}
2775+
impl From<AssocTypeArg> for GenericArg {
2776+
fn from(node: AssocTypeArg) -> GenericArg { GenericArg::AssocTypeArg(node) }
2777+
}
2778+
impl From<LifetimeArg> for GenericArg {
2779+
fn from(node: LifetimeArg) -> GenericArg { GenericArg::LifetimeArg(node) }
2780+
}
2781+
impl From<ConstArg> for GenericArg {
2782+
fn from(node: ConstArg) -> GenericArg { GenericArg::ConstArg(node) }
2783+
}
2784+
impl AstNode for GenericArg {
2785+
fn can_cast(kind: SyntaxKind) -> bool {
2786+
match kind {
2787+
TYPE_ARG | ASSOC_TYPE_ARG | LIFETIME_ARG | CONST_ARG => true,
2788+
_ => false,
2789+
}
2790+
}
2791+
fn cast(syntax: SyntaxNode) -> Option<Self> {
2792+
let res = match syntax.kind() {
2793+
TYPE_ARG => GenericArg::TypeArg(TypeArg { syntax }),
2794+
ASSOC_TYPE_ARG => GenericArg::AssocTypeArg(AssocTypeArg { syntax }),
2795+
LIFETIME_ARG => GenericArg::LifetimeArg(LifetimeArg { syntax }),
2796+
CONST_ARG => GenericArg::ConstArg(ConstArg { syntax }),
2797+
_ => return None,
2798+
};
2799+
Some(res)
2800+
}
2801+
fn syntax(&self) -> &SyntaxNode {
2802+
match self {
2803+
GenericArg::TypeArg(it) => &it.syntax,
2804+
GenericArg::AssocTypeArg(it) => &it.syntax,
2805+
GenericArg::LifetimeArg(it) => &it.syntax,
2806+
GenericArg::ConstArg(it) => &it.syntax,
2807+
}
2808+
}
2809+
}
27682810
impl From<ArrayType> for Type {
27692811
fn from(node: ArrayType) -> Type { Type::ArrayType(node) }
27702812
}
@@ -3380,6 +3422,11 @@ impl From<Item> for Stmt {
33803422
impl From<LetStmt> for Stmt {
33813423
fn from(node: LetStmt) -> Stmt { Stmt::LetStmt(node) }
33823424
}
3425+
impl std::fmt::Display for GenericArg {
3426+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3427+
std::fmt::Display::fmt(self.syntax(), f)
3428+
}
3429+
}
33833430
impl std::fmt::Display for Type {
33843431
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33853432
std::fmt::Display::fmt(self.syntax(), f)
@@ -3470,12 +3517,12 @@ impl std::fmt::Display for TypeArg {
34703517
std::fmt::Display::fmt(self.syntax(), f)
34713518
}
34723519
}
3473-
impl std::fmt::Display for LifetimeArg {
3520+
impl std::fmt::Display for AssocTypeArg {
34743521
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34753522
std::fmt::Display::fmt(self.syntax(), f)
34763523
}
34773524
}
3478-
impl std::fmt::Display for AssocTypeArg {
3525+
impl std::fmt::Display for LifetimeArg {
34793526
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34803527
std::fmt::Display::fmt(self.syntax(), f)
34813528
}

xtask/src/codegen/rust.ungram

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ PathSegment =
88
| '<' PathType ('as' PathType)? '>'
99

1010
GenericArgList =
11-
'::'? '<'
12-
TypeArg*
13-
LifetimeArg*
14-
AssocTypeArg*
15-
ConstArg*
16-
'>'
11+
'::'? '<' (GenericArg (',' GenericArg)* ','?)? '>'
12+
13+
GenericArg =
14+
TypeArg
15+
| AssocTypeArg
16+
| LifetimeArg
17+
| ConstArg
1718

1819
TypeArg =
1920
Type
@@ -27,7 +28,6 @@ LifetimeArg =
2728
ConstArg =
2829
Literal | BlockExpr BlockExpr
2930

30-
3131
SourceFile =
3232
'shebang'?
3333
Attr*

0 commit comments

Comments
 (0)