diff options
Diffstat (limited to 'src/parser/grammar/paths.rs')
-rw-r--r-- | src/parser/grammar/paths.rs | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/src/parser/grammar/paths.rs b/src/parser/grammar/paths.rs index d3eb20ea1..69ed84665 100644 --- a/src/parser/grammar/paths.rs +++ b/src/parser/grammar/paths.rs | |||
@@ -8,19 +8,26 @@ pub(super) fn is_path_start(p: &Parser) -> bool { | |||
8 | } | 8 | } |
9 | 9 | ||
10 | pub(super) fn use_path(p: &mut Parser) { | 10 | pub(super) fn use_path(p: &mut Parser) { |
11 | path(p) | 11 | path(p, Mode::Use) |
12 | } | 12 | } |
13 | 13 | ||
14 | pub(super) fn type_path(p: &mut Parser) { | 14 | pub(super) fn type_path(p: &mut Parser) { |
15 | path(p) | 15 | path(p, Mode::Type) |
16 | } | 16 | } |
17 | 17 | ||
18 | fn path(p: &mut Parser) { | 18 | pub(super) fn expr_path(p: &mut Parser) { |
19 | path(p, Mode::Expr) | ||
20 | } | ||
21 | |||
22 | #[derive(Clone, Copy, Eq, PartialEq)] | ||
23 | enum Mode { Use, Type, Expr } | ||
24 | |||
25 | fn path(p: &mut Parser, mode: Mode) { | ||
19 | if !is_path_start(p) { | 26 | if !is_path_start(p) { |
20 | return; | 27 | return; |
21 | } | 28 | } |
22 | let path = p.start(); | 29 | let path = p.start(); |
23 | path_segment(p, true); | 30 | path_segment(p, mode, true); |
24 | let mut qual = path.complete(p, PATH); | 31 | let mut qual = path.complete(p, PATH); |
25 | loop { | 32 | loop { |
26 | let use_tree = match p.nth(1) { | 33 | let use_tree = match p.nth(1) { |
@@ -30,7 +37,7 @@ fn path(p: &mut Parser) { | |||
30 | if p.at(COLONCOLON) && !use_tree { | 37 | if p.at(COLONCOLON) && !use_tree { |
31 | let path = qual.precede(p); | 38 | let path = qual.precede(p); |
32 | p.bump(); | 39 | p.bump(); |
33 | path_segment(p, false); | 40 | path_segment(p, mode, false); |
34 | let path = path.complete(p, PATH); | 41 | let path = path.complete(p, PATH); |
35 | qual = path; | 42 | qual = path; |
36 | } else { | 43 | } else { |
@@ -39,13 +46,16 @@ fn path(p: &mut Parser) { | |||
39 | } | 46 | } |
40 | } | 47 | } |
41 | 48 | ||
42 | fn path_segment(p: &mut Parser, first: bool) { | 49 | fn path_segment(p: &mut Parser, mode: Mode, first: bool) { |
43 | let segment = p.start(); | 50 | let segment = p.start(); |
44 | if first { | 51 | if first { |
45 | p.eat(COLONCOLON); | 52 | p.eat(COLONCOLON); |
46 | } | 53 | } |
47 | match p.current() { | 54 | match p.current() { |
48 | IDENT => name_ref(p), | 55 | IDENT => { |
56 | name_ref(p); | ||
57 | path_generic_args(p, mode); | ||
58 | }, | ||
49 | SELF_KW | SUPER_KW => p.bump(), | 59 | SELF_KW | SUPER_KW => p.bump(), |
50 | _ => { | 60 | _ => { |
51 | p.error("expected identifier"); | 61 | p.error("expected identifier"); |
@@ -53,3 +63,11 @@ fn path_segment(p: &mut Parser, first: bool) { | |||
53 | }; | 63 | }; |
54 | segment.complete(p, PATH_SEGMENT); | 64 | segment.complete(p, PATH_SEGMENT); |
55 | } | 65 | } |
66 | |||
67 | fn path_generic_args(p: &mut Parser, mode: Mode) { | ||
68 | match mode { | ||
69 | Mode::Use => return, | ||
70 | Mode::Type => type_args::list(p, false), | ||
71 | Mode::Expr => type_args::list(p, true), | ||
72 | } | ||
73 | } | ||