aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/grammar.ron1
-rw-r--r--src/grammar/type_params.rs60
-rw-r--r--src/grammar/types.rs2
-rw-r--r--src/syntax_kinds/generated.rs2
4 files changed, 50 insertions, 15 deletions
diff --git a/src/grammar.ron b/src/grammar.ron
index df1dfe050..0443dd798 100644
--- a/src/grammar.ron
+++ b/src/grammar.ron
@@ -192,6 +192,7 @@ Grammar(
192 "ALIAS", 192 "ALIAS",
193 "VISIBILITY", 193 "VISIBILITY",
194 "WHERE_CLAUSE", 194 "WHERE_CLAUSE",
195 "WHERE_PRED",
195 "ABI", 196 "ABI",
196 "NAME", 197 "NAME",
197 "NAME_REF", 198 "NAME_REF",
diff --git a/src/grammar/type_params.rs b/src/grammar/type_params.rs
index 1227482ad..0a3e8fd07 100644
--- a/src/grammar/type_params.rs
+++ b/src/grammar/type_params.rs
@@ -24,13 +24,8 @@ pub(super) fn type_param_list(p: &mut Parser) {
24 assert!(p.at(LIFETIME)); 24 assert!(p.at(LIFETIME));
25 let m = p.start(); 25 let m = p.start();
26 p.bump(); 26 p.bump();
27 if p.eat(COLON) { 27 if p.at(COLON) {
28 while p.at(LIFETIME) { 28 lifetime_bounds(p);
29 p.bump();
30 if !p.eat(PLUS) {
31 break;
32 }
33 }
34 } 29 }
35 m.complete(p, LIFETIME_PARAM); 30 m.complete(p, LIFETIME_PARAM);
36 } 31 }
@@ -60,6 +55,17 @@ pub(super) fn bounds(p: &mut Parser) {
60 bounds_without_colon(p); 55 bounds_without_colon(p);
61} 56}
62 57
58fn lifetime_bounds(p: &mut Parser) {
59 assert!(p.at(COLON));
60 p.bump();
61 while p.at(LIFETIME) {
62 p.bump();
63 if !p.eat(PLUS) {
64 break;
65 }
66 }
67}
68
63pub(super) fn bounds_without_colon(p: &mut Parser) { 69pub(super) fn bounds_without_colon(p: &mut Parser) {
64 loop { 70 loop {
65 let has_paren = p.eat(L_PAREN); 71 let has_paren = p.eat(L_PAREN);
@@ -83,13 +89,39 @@ pub(super) fn bounds_without_colon(p: &mut Parser) {
83 } 89 }
84} 90}
85 91
92// test where_clause
93// fn foo()
94// where
95// 'a: 'b + 'c,
96// T: Clone + Copy + 'static,
97// Iterator::Item: 'a,
98// {}
86pub(super) fn where_clause(p: &mut Parser) { 99pub(super) fn where_clause(p: &mut Parser) {
87 if p.at(WHERE_KW) { 100 if !p.at(WHERE_KW) {
88 let m = p.start(); 101 return;
89 p.bump(); 102 }
90 p.expect(IDENT); 103 let m = p.start();
91 p.expect(COLON); 104 p.bump();
92 p.expect(IDENT); 105 loop {
93 m.complete(p, WHERE_CLAUSE); 106 if !(paths::is_path_start(p) || p.current() == LIFETIME) {
107 break
108 }
109 where_predicate(p);
110 if p.current() != L_CURLY && p.current() != SEMI {
111 p.expect(COMMA);
112 }
113 }
114 m.complete(p, WHERE_CLAUSE);
115}
116
117fn where_predicate(p: &mut Parser) {
118 let m = p.start();
119 if p.at(LIFETIME) {
120 p.eat(LIFETIME);
121 lifetime_bounds(p)
122 } else {
123 types::path_type(p);
124 bounds(p);
94 } 125 }
126 m.complete(p, WHERE_PRED);
95} 127}
diff --git a/src/grammar/types.rs b/src/grammar/types.rs
index c8ced3d28..0d8c6bfba 100644
--- a/src/grammar/types.rs
+++ b/src/grammar/types.rs
@@ -199,7 +199,7 @@ fn impl_trait_type(p: &mut Parser) {
199// type B = ::Foo; 199// type B = ::Foo;
200// type C = self::Foo; 200// type C = self::Foo;
201// type D = super::Foo; 201// type D = super::Foo;
202fn path_type(p: &mut Parser) { 202pub(super) fn path_type(p: &mut Parser) {
203 assert!(paths::is_path_start(p)); 203 assert!(paths::is_path_start(p));
204 let m = p.start(); 204 let m = p.start();
205 paths::type_path(p); 205 paths::type_path(p);
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs
index a74acf6eb..9a9c1f223 100644
--- a/src/syntax_kinds/generated.rs
+++ b/src/syntax_kinds/generated.rs
@@ -175,6 +175,7 @@ pub enum SyntaxKind {
175 ALIAS, 175 ALIAS,
176 VISIBILITY, 176 VISIBILITY,
177 WHERE_CLAUSE, 177 WHERE_CLAUSE,
178 WHERE_PRED,
178 ABI, 179 ABI,
179 NAME, 180 NAME,
180 NAME_REF, 181 NAME_REF,
@@ -415,6 +416,7 @@ impl SyntaxKind {
415 ALIAS => &SyntaxInfo { name: "ALIAS" }, 416 ALIAS => &SyntaxInfo { name: "ALIAS" },
416 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, 417 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" },
417 WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, 418 WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" },
419 WHERE_PRED => &SyntaxInfo { name: "WHERE_PRED" },
418 ABI => &SyntaxInfo { name: "ABI" }, 420 ABI => &SyntaxInfo { name: "ABI" },
419 NAME => &SyntaxInfo { name: "NAME" }, 421 NAME => &SyntaxInfo { name: "NAME" },
420 NAME_REF => &SyntaxInfo { name: "NAME_REF" }, 422 NAME_REF => &SyntaxInfo { name: "NAME_REF" },