From 49ab44102496ac8c4a05b00c584adecf583f4d87 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 13 Aug 2018 23:54:00 +0300 Subject: [PATCH] Qualified paths --- .../src/grammar/expressions/atom.rs | 2 +- .../libsyntax2/src/grammar/expressions/mod.rs | 2 +- crates/libsyntax2/src/grammar/paths.rs | 46 +++++++---- crates/libsyntax2/src/grammar/types.rs | 3 +- .../data/parser/inline/0101_qual_paths.rs | 2 + .../data/parser/inline/0101_qual_paths.txt | 78 +++++++++++++++++++ 6 files changed, 113 insertions(+), 20 deletions(-) create mode 100644 crates/libsyntax2/tests/data/parser/inline/0101_qual_paths.rs create mode 100644 crates/libsyntax2/tests/data/parser/inline/0101_qual_paths.txt diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs index e62b166548..4f03862b18 100644 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ b/crates/libsyntax2/src/grammar/expressions/atom.rs @@ -38,7 +38,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option return Some(m), None => (), } - if paths::is_path_start(p) { + if paths::is_path_start(p) || p.at(L_ANGLE) { return Some(path_expr(p, r)); } let la = p.nth(1); diff --git a/crates/libsyntax2/src/grammar/expressions/mod.rs b/crates/libsyntax2/src/grammar/expressions/mod.rs index 30a78d0c47..e56f3d30e2 100644 --- a/crates/libsyntax2/src/grammar/expressions/mod.rs +++ b/crates/libsyntax2/src/grammar/expressions/mod.rs @@ -332,7 +332,7 @@ fn arg_list(p: &mut Parser) { // let _ = format!(); // } fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { - assert!(paths::is_path_start(p)); + assert!(paths::is_path_start(p) || p.at(L_ANGLE)); let m = p.start(); paths::expr_path(p); match p.current() { diff --git a/crates/libsyntax2/src/grammar/paths.rs b/crates/libsyntax2/src/grammar/paths.rs index aa5ecf4b84..97ab1880bd 100644 --- a/crates/libsyntax2/src/grammar/paths.rs +++ b/crates/libsyntax2/src/grammar/paths.rs @@ -27,9 +27,6 @@ enum Mode { } fn path(p: &mut Parser, mode: Mode) { - if !is_path_start(p) { - return; - } let path = p.start(); path_segment(p, mode, true); let mut qual = path.complete(p, PATH); @@ -51,21 +48,36 @@ fn path(p: &mut Parser, mode: Mode) { } fn path_segment(p: &mut Parser, mode: Mode, first: bool) { - let segment = p.start(); - if first { - p.eat(COLONCOLON); + let m = p.start(); + // test qual_paths + // type X = ::Output; + // fn foo() { ::default(); } + if first && p.eat(L_ANGLE) { + types::type_(p); + if p.eat(AS_KW) { + if is_path_start(p) { + types::path_type(p); + } else { + p.error("expected a trait"); + } + } + p.expect(R_ANGLE); + } else { + if first { + p.eat(COLONCOLON); + } + match p.current() { + IDENT => { + name_ref(p); + path_generic_args(p, mode); + } + SELF_KW | SUPER_KW => p.bump(), + _ => { + p.err_and_bump("expected identifier"); + } + }; } - match p.current() { - IDENT => { - name_ref(p); - path_generic_args(p, mode); - } - SELF_KW | SUPER_KW => p.bump(), - _ => { - p.err_and_bump("expected identifier"); - } - }; - segment.complete(p, PATH_SEGMENT); + m.complete(p, PATH_SEGMENT); } fn path_generic_args(p: &mut Parser, mode: Mode) { diff --git a/crates/libsyntax2/src/grammar/types.rs b/crates/libsyntax2/src/grammar/types.rs index 88631fefee..f58b545c76 100644 --- a/crates/libsyntax2/src/grammar/types.rs +++ b/crates/libsyntax2/src/grammar/types.rs @@ -12,6 +12,7 @@ pub(super) fn type_(p: &mut Parser) { FOR_KW => for_type(p), IMPL_KW => impl_trait_type(p), DYN_KW => dyn_trait_type(p), + L_ANGLE => path_type(p), _ if paths::is_path_start(p) => path_type(p), _ => { p.err_and_bump("expected type"); @@ -214,7 +215,7 @@ fn dyn_trait_type(p: &mut Parser) { // type C = self::Foo; // type D = super::Foo; pub(super) fn path_type(p: &mut Parser) { - assert!(paths::is_path_start(p)); + assert!(paths::is_path_start(p) || p.at(L_ANGLE)); let m = p.start(); paths::type_path(p); // test path_type_with_bounds diff --git a/crates/libsyntax2/tests/data/parser/inline/0101_qual_paths.rs b/crates/libsyntax2/tests/data/parser/inline/0101_qual_paths.rs new file mode 100644 index 0000000000..d140692e21 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/inline/0101_qual_paths.rs @@ -0,0 +1,2 @@ +type X = ::Output; +fn foo() { ::default(); } diff --git a/crates/libsyntax2/tests/data/parser/inline/0101_qual_paths.txt b/crates/libsyntax2/tests/data/parser/inline/0101_qual_paths.txt new file mode 100644 index 0000000000..58b545bdd1 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/inline/0101_qual_paths.txt @@ -0,0 +1,78 @@ +FILE@[0; 71) + TYPE_DEF@[0; 26) + TYPE_KW@[0; 4) + WHITESPACE@[4; 5) + NAME@[5; 6) + IDENT@[5; 6) "X" + WHITESPACE@[6; 7) + EQ@[7; 8) + WHITESPACE@[8; 9) + PATH_TYPE@[9; 25) + PATH@[9; 25) + PATH@[9; 17) + PATH_SEGMENT@[9; 17) + L_ANGLE@[9; 10) + PATH_TYPE@[10; 11) + PATH@[10; 11) + PATH_SEGMENT@[10; 11) + NAME_REF@[10; 11) + IDENT@[10; 11) "A" + WHITESPACE@[11; 12) + AS_KW@[12; 14) + WHITESPACE@[14; 15) + PATH_TYPE@[15; 16) + PATH@[15; 16) + PATH_SEGMENT@[15; 16) + NAME_REF@[15; 16) + IDENT@[15; 16) "B" + R_ANGLE@[16; 17) + COLONCOLON@[17; 19) + PATH_SEGMENT@[19; 25) + NAME_REF@[19; 25) + IDENT@[19; 25) "Output" + SEMI@[25; 26) + WHITESPACE@[26; 27) + FN_DEF@[27; 70) + FN_KW@[27; 29) + WHITESPACE@[29; 30) + NAME@[30; 33) + IDENT@[30; 33) "foo" + PARAM_LIST@[33; 35) + L_PAREN@[33; 34) + R_PAREN@[34; 35) + WHITESPACE@[35; 36) + BLOCK_EXPR@[36; 70) + L_CURLY@[36; 37) + WHITESPACE@[37; 38) + EXPR_STMT@[38; 68) + CALL_EXPR@[38; 67) + PATH_EXPR@[38; 65) + PATH@[38; 65) + PATH@[38; 56) + PATH_SEGMENT@[38; 56) + L_ANGLE@[38; 39) + PATH_TYPE@[39; 44) + PATH@[39; 44) + PATH_SEGMENT@[39; 44) + NAME_REF@[39; 44) + IDENT@[39; 44) "usize" + WHITESPACE@[44; 45) + AS_KW@[45; 47) + WHITESPACE@[47; 48) + PATH_TYPE@[48; 55) + PATH@[48; 55) + PATH_SEGMENT@[48; 55) + NAME_REF@[48; 55) + IDENT@[48; 55) "Default" + R_ANGLE@[55; 56) + COLONCOLON@[56; 58) + PATH_SEGMENT@[58; 65) + NAME_REF@[58; 65) + IDENT@[58; 65) "default" + ARG_LIST@[65; 67) + L_PAREN@[65; 66) + R_PAREN@[66; 67) + SEMI@[67; 68) + WHITESPACE@[68; 69) + R_CURLY@[69; 70) + WHITESPACE@[70; 71)