aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src/grammar
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-04 10:25:23 +0100
committerAleksey Kladov <[email protected]>2018-09-04 10:25:23 +0100
commite44a6bcc8208f9d906febf9278120b75a6af67f9 (patch)
tree0b6a9e8d5c9527d9bd1ed266213d591ea957623c /crates/libsyntax2/src/grammar
parent3a017aaa52fc41316b5dd2cd90b5171ca869697a (diff)
for types in bounds
Diffstat (limited to 'crates/libsyntax2/src/grammar')
-rw-r--r--crates/libsyntax2/src/grammar/type_params.rs18
-rw-r--r--crates/libsyntax2/src/grammar/types.rs15
2 files changed, 21 insertions, 12 deletions
diff --git a/crates/libsyntax2/src/grammar/type_params.rs b/crates/libsyntax2/src/grammar/type_params.rs
index 3fb4bd356..79bc95ce4 100644
--- a/crates/libsyntax2/src/grammar/type_params.rs
+++ b/crates/libsyntax2/src/grammar/type_params.rs
@@ -70,15 +70,15 @@ pub(super) fn bounds_without_colon(p: &mut Parser) {
70 loop { 70 loop {
71 let has_paren = p.eat(L_PAREN); 71 let has_paren = p.eat(L_PAREN);
72 p.eat(QUESTION); 72 p.eat(QUESTION);
73 if p.at(FOR_KW) { 73 match p.current() {
74 //TODO 74 LIFETIME => p.bump(),
75 } 75 FOR_KW => {
76 if p.at(LIFETIME) { 76 types::for_type(p)
77 p.bump(); 77 }
78 } else if paths::is_path_start(p) { 78 _ if paths::is_path_start(p) => {
79 paths::type_path(p); 79 types::path_type(p)
80 } else { 80 }
81 break; 81 _ => break,
82 } 82 }
83 if has_paren { 83 if has_paren {
84 p.expect(R_PAREN); 84 p.expect(R_PAREN);
diff --git a/crates/libsyntax2/src/grammar/types.rs b/crates/libsyntax2/src/grammar/types.rs
index a52355b50..27e5b086e 100644
--- a/crates/libsyntax2/src/grammar/types.rs
+++ b/crates/libsyntax2/src/grammar/types.rs
@@ -191,12 +191,17 @@ fn fn_pointer_type(p: &mut Parser) {
191 191
192// test for_type 192// test for_type
193// type A = for<'a> fn() -> (); 193// type A = for<'a> fn() -> ();
194fn for_type(p: &mut Parser) { 194pub(super) fn for_type(p: &mut Parser) {
195 assert!(p.at(FOR_KW)); 195 assert!(p.at(FOR_KW));
196 let m = p.start(); 196 let m = p.start();
197 p.bump(); 197 p.bump();
198 type_params::opt_type_param_list(p); 198 type_params::opt_type_param_list(p);
199 type_(p); 199 match p.current() {
200 FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p),
201 _ if paths::is_path_start(p) => path_type_(p, false),
202 _ => p.error("expected a path"),
203
204 }
200 m.complete(p, FOR_TYPE); 205 m.complete(p, FOR_TYPE);
201} 206}
202 207
@@ -226,12 +231,16 @@ fn dyn_trait_type(p: &mut Parser) {
226// type C = self::Foo; 231// type C = self::Foo;
227// type D = super::Foo; 232// type D = super::Foo;
228pub(super) fn path_type(p: &mut Parser) { 233pub(super) fn path_type(p: &mut Parser) {
234 path_type_(p, true)
235}
236
237pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) {
229 assert!(paths::is_path_start(p) || p.at(L_ANGLE)); 238 assert!(paths::is_path_start(p) || p.at(L_ANGLE));
230 let m = p.start(); 239 let m = p.start();
231 paths::type_path(p); 240 paths::type_path(p);
232 // test path_type_with_bounds 241 // test path_type_with_bounds
233 // fn foo() -> Box<T + 'f> {} 242 // fn foo() -> Box<T + 'f> {}
234 if p.eat(PLUS) { 243 if allow_bounds && p.eat(PLUS) {
235 type_params::bounds_without_colon(p); 244 type_params::bounds_without_colon(p);
236 } 245 }
237 m.complete(p, PATH_TYPE); 246 m.complete(p, PATH_TYPE);