aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_parser/src/grammar/items/traits.rs1
-rw-r--r--crates/ra_parser/src/grammar/type_params.rs11
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs4
-rw-r--r--crates/ra_syntax/src/ast/generated.rs68
-rw-r--r--crates/ra_syntax/src/grammar.ron13
5 files changed, 95 insertions, 2 deletions
diff --git a/crates/ra_parser/src/grammar/items/traits.rs b/crates/ra_parser/src/grammar/items/traits.rs
index f49615f6b..d03a6be0d 100644
--- a/crates/ra_parser/src/grammar/items/traits.rs
+++ b/crates/ra_parser/src/grammar/items/traits.rs
@@ -2,6 +2,7 @@ use super::*;
2 2
3// test trait_item 3// test trait_item
4// trait T<U>: Hash + Clone where U: Copy {} 4// trait T<U>: Hash + Clone where U: Copy {}
5// trait X<U: Debug + Display>: Hash + Clone where U: Copy {}
5pub(super) fn trait_def(p: &mut Parser) { 6pub(super) fn trait_def(p: &mut Parser) {
6 assert!(p.at(TRAIT_KW)); 7 assert!(p.at(TRAIT_KW));
7 p.bump(); 8 p.bump();
diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs
index 40f998682..e28c124cd 100644
--- a/crates/ra_parser/src/grammar/type_params.rs
+++ b/crates/ra_parser/src/grammar/type_params.rs
@@ -80,22 +80,29 @@ fn lifetime_bounds(p: &mut Parser) {
80} 80}
81 81
82pub(super) fn bounds_without_colon(p: &mut Parser) { 82pub(super) fn bounds_without_colon(p: &mut Parser) {
83 let outer = p.start();
83 loop { 84 loop {
85 let inner = p.start();
84 let has_paren = p.eat(L_PAREN); 86 let has_paren = p.eat(L_PAREN);
85 p.eat(QUESTION); 87 p.eat(QUESTION);
86 match p.current() { 88 match p.current() {
87 LIFETIME => p.bump(), 89 LIFETIME => p.bump(),
88 FOR_KW => types::for_type(p), 90 FOR_KW => types::for_type(p),
89 _ if paths::is_path_start(p) => types::path_type(p), 91 _ if paths::is_path_start(p) => types::path_type_(p, false),
90 _ => break, 92 _ => {
93 inner.abandon(p);
94 break;
95 }
91 } 96 }
92 if has_paren { 97 if has_paren {
93 p.expect(R_PAREN); 98 p.expect(R_PAREN);
94 } 99 }
100 inner.complete(p, TYPE_BOUND);
95 if !p.eat(PLUS) { 101 if !p.eat(PLUS) {
96 break; 102 break;
97 } 103 }
98 } 104 }
105 outer.complete(p, TYPE_BOUND_LIST);
99} 106}
100 107
101// test where_clause 108// test where_clause
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index 03247ae38..547af1b27 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -228,6 +228,8 @@ pub enum SyntaxKind {
228 PARAM, 228 PARAM,
229 SELF_PARAM, 229 SELF_PARAM,
230 ARG_LIST, 230 ARG_LIST,
231 TYPE_BOUND,
232 TYPE_BOUND_LIST,
231} 233}
232use self::SyntaxKind::*; 234use self::SyntaxKind::*;
233 235
@@ -567,6 +569,8 @@ impl SyntaxKind {
567 PARAM => &SyntaxInfo { name: "PARAM" }, 569 PARAM => &SyntaxInfo { name: "PARAM" },
568 SELF_PARAM => &SyntaxInfo { name: "SELF_PARAM" }, 570 SELF_PARAM => &SyntaxInfo { name: "SELF_PARAM" },
569 ARG_LIST => &SyntaxInfo { name: "ARG_LIST" }, 571 ARG_LIST => &SyntaxInfo { name: "ARG_LIST" },
572 TYPE_BOUND => &SyntaxInfo { name: "TYPE_BOUND" },
573 TYPE_BOUND_LIST => &SyntaxInfo { name: "TYPE_BOUND_LIST" },
570 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, 574 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
571 EOF => &SyntaxInfo { name: "EOF" }, 575 EOF => &SyntaxInfo { name: "EOF" },
572 } 576 }
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 47a37e4d1..faf80bc32 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -4369,6 +4369,74 @@ impl TypeArgList {
4369 } 4369 }
4370} 4370}
4371 4371
4372// TypeBound
4373#[derive(Debug, PartialEq, Eq, Hash)]
4374#[repr(transparent)]
4375pub struct TypeBound {
4376 pub(crate) syntax: SyntaxNode,
4377}
4378unsafe impl TransparentNewType for TypeBound {
4379 type Repr = rowan::SyntaxNode<RaTypes>;
4380}
4381
4382impl AstNode for TypeBound {
4383 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
4384 match syntax.kind() {
4385 TYPE_BOUND => Some(TypeBound::from_repr(syntax.into_repr())),
4386 _ => None,
4387 }
4388 }
4389 fn syntax(&self) -> &SyntaxNode { &self.syntax }
4390}
4391
4392impl ToOwned for TypeBound {
4393 type Owned = TreeArc<TypeBound>;
4394 fn to_owned(&self) -> TreeArc<TypeBound> { TreeArc::cast(self.syntax.to_owned()) }
4395}
4396
4397
4398impl TypeBound {
4399 pub fn type_ref(&self) -> Option<&TypeRef> {
4400 super::child_opt(self)
4401 }
4402
4403 pub fn lifetime(&self) -> Option<&Lifetime> {
4404 super::child_opt(self)
4405 }
4406}
4407
4408// TypeBoundList
4409#[derive(Debug, PartialEq, Eq, Hash)]
4410#[repr(transparent)]
4411pub struct TypeBoundList {
4412 pub(crate) syntax: SyntaxNode,
4413}
4414unsafe impl TransparentNewType for TypeBoundList {
4415 type Repr = rowan::SyntaxNode<RaTypes>;
4416}
4417
4418impl AstNode for TypeBoundList {
4419 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
4420 match syntax.kind() {
4421 TYPE_BOUND_LIST => Some(TypeBoundList::from_repr(syntax.into_repr())),
4422 _ => None,
4423 }
4424 }
4425 fn syntax(&self) -> &SyntaxNode { &self.syntax }
4426}
4427
4428impl ToOwned for TypeBoundList {
4429 type Owned = TreeArc<TypeBoundList>;
4430 fn to_owned(&self) -> TreeArc<TypeBoundList> { TreeArc::cast(self.syntax.to_owned()) }
4431}
4432
4433
4434impl TypeBoundList {
4435 pub fn bounds(&self) -> impl Iterator<Item = &TypeBound> {
4436 super::children(self)
4437 }
4438}
4439
4372// TypeParam 4440// TypeParam
4373#[derive(Debug, PartialEq, Eq, Hash)] 4441#[derive(Debug, PartialEq, Eq, Hash)]
4374#[repr(transparent)] 4442#[repr(transparent)]
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index ad6d74162..660a2b207 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -243,6 +243,8 @@ Grammar(
243 "PARAM", 243 "PARAM",
244 "SELF_PARAM", 244 "SELF_PARAM",
245 "ARG_LIST", 245 "ARG_LIST",
246 "TYPE_BOUND",
247 "TYPE_BOUND_LIST",
246 ], 248 ],
247 ast: { 249 ast: {
248 "SourceFile": ( 250 "SourceFile": (
@@ -577,6 +579,17 @@ Grammar(
577 traits: ["AttrsOwner"], 579 traits: ["AttrsOwner"],
578 ), 580 ),
579 "Lifetime": ( traits: ["AstToken"] ), 581 "Lifetime": ( traits: ["AstToken"] ),
582 "TypeBound": (
583 options: [
584 "TypeRef",
585 "Lifetime",
586 ]
587 ),
588 "TypeBoundList": (
589 collections: [
590 ["bounds", "TypeBound"],
591 ]
592 ),
580 "WhereClause": (), 593 "WhereClause": (),
581 "ExprStmt": ( 594 "ExprStmt": (
582 options: [ ["expr", "Expr"] ] 595 options: [ ["expr", "Expr"] ]