aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2023-02-17 14:24:07 +0100
committerCohenArthur <arthur.cohen@embecosm.com>2023-02-20 12:52:12 +0000
commit87e7c9dedacd4d12636e6c626aab14bcecf686f2 (patch)
treea59726e8366764f7f6002c0e1ca8364a1b4d342f
parent57b64a64261ed1d1774af61a1e36eeac604abcde (diff)
downloadgcc-87e7c9dedacd4d12636e6c626aab14bcecf686f2.zip
gcc-87e7c9dedacd4d12636e6c626aab14bcecf686f2.tar.gz
gcc-87e7c9dedacd4d12636e6c626aab14bcecf686f2.tar.bz2
parser: Allow `LEFT_SHIFT` to start `parse_type`
Similarly to the last commit, we need to allow `LEFT_SHIFT` tokens to start a qualified path type and split them into two `LEFT_ANGLE` tokens. gcc/rust/ChangeLog: * parse/rust-parse-impl.h (Parser::parse_type): Allow LEFT_SHIFT to start a type and then split it in `parse_qualified_path_type` gcc/testsuite/ChangeLog: * rust/compile/parse_associated_type_as_generic_arg3.rs: New test.
-rw-r--r--gcc/rust/parse/rust-parse-impl.h15
-rw-r--r--gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg3.rs59
2 files changed, 70 insertions, 4 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 3bf26bc..2cb5e3e 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -6842,11 +6842,13 @@ Parser<ManagedTokenSource>::parse_qualified_path_type (
if (locus == Linemap::unknown_location ())
{
locus = lexer.peek_token ()->get_locus ();
+
+ if (lexer.peek_token ()->get_id () == LEFT_SHIFT)
+ lexer.split_current_token (LEFT_ANGLE, LEFT_ANGLE);
+
+ // skip after somewhere?
if (!skip_token (LEFT_ANGLE))
- {
- // skip after somewhere?
- return AST::QualifiedPathType::create_error ();
- }
+ return AST::QualifiedPathType::create_error ();
}
// parse type (required)
@@ -9218,6 +9220,7 @@ Parser<ManagedTokenSource>::parse_type (bool save_errors)
case LEFT_SQUARE:
// slice type or array type - requires further disambiguation
return parse_slice_or_array_type ();
+ case LEFT_SHIFT:
case LEFT_ANGLE: {
// qualified path in type
AST::QualifiedPathInType path = parse_qualified_path_in_type ();
@@ -10084,6 +10087,7 @@ Parser<ManagedTokenSource>::parse_type_no_bounds ()
case LEFT_SQUARE:
// slice type or array type - requires further disambiguation
return parse_slice_or_array_type ();
+ case LEFT_SHIFT:
case LEFT_ANGLE: {
// qualified path in type
AST::QualifiedPathInType path = parse_qualified_path_in_type ();
@@ -10597,6 +10601,7 @@ Parser<ManagedTokenSource>::parse_range_pattern_bound ()
return std::unique_ptr<AST::RangePatternBoundPath> (
new AST::RangePatternBoundPath (std::move (path)));
}
+ case LEFT_SHIFT:
case LEFT_ANGLE: {
// qualified path in expression
AST::QualifiedPathInExpression path
@@ -10727,6 +10732,7 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
case LEFT_SQUARE:
// slice pattern
return parse_slice_pattern ();
+ case LEFT_SHIFT:
case LEFT_ANGLE: {
// qualified path in expression or qualified range pattern bound
AST::QualifiedPathInExpression path
@@ -12760,6 +12766,7 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
* tokens and whatever. */
/* FIXME: could also be path expression (and hence macro expression,
* struct/enum expr) */
+ case LEFT_SHIFT:
case LEFT_ANGLE: {
// qualified path
// HACK: add outer attrs to path
diff --git a/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg3.rs b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg3.rs
new file mode 100644
index 0000000..f1cc9e7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg3.rs
@@ -0,0 +1,59 @@
+// { dg-additional-options "-fsyntax-only" }
+
+trait Bar {
+ type B;
+
+ fn bar();
+}
+
+trait Foo {
+ type A;
+
+ fn foo();
+}
+
+trait Toto {
+ type C;
+
+ fn toto();
+}
+
+trait Tata {
+ type D;
+ fn tata();
+}
+
+impl Toto for u32 {
+ type C = f32;
+
+ fn toto() {}
+}
+
+impl Tata for f32 {
+ type D = u32;
+
+ fn tata() {}
+}
+
+struct S;
+
+impl Bar for i32 {
+ type B = u32;
+
+ fn bar() {}
+}
+
+impl Foo for S {
+ type A = i32;
+
+ fn foo() {}
+}
+
+enum Maybe<T> {
+ Something(T),
+ Nothing,
+}
+
+fn foo() -> Maybe<<<<<S as Foo>::A as Bar>::B as Toto>::C as Tata>::D> {
+ Maybe::Something(15)
+}