From 57b64a64261ed1d1774af61a1e36eeac604abcde Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Thu, 16 Feb 2023 13:53:22 +0100 Subject: parser: Allow parsing of qualified type path as nested generic argument Let's take the example of lexing `Option<::Item>` and look at the first few tokens. Originally, `Option<` is properly parsed as a qualified path. Fixes #1815 Fixed #1809 Addresses #1524 gcc/rust/ChangeLog: * parse/rust-parse-impl.h (Parser::parse_path_generic_args): Split leading `LEFT_SHIFT` token into two `LEFT_ANGLE` tokens when parsing generic arguments. (Parser::parse_type_path_segment): Allow `LEFT_ANGLE` as starting token for parsing generic arguments. gcc/testsuite/ChangeLog: * rust/compile/parse_associated_type_as_generic_arg.rs: New test. * rust/compile/parse_associated_type_as_generic_arg2.rs: New test. * rust/compile/path_as_generic_arg.rs: New test. * rust/compile/nested_generic.rs: New test. --- gcc/rust/parse/rust-parse-impl.h | 4 ++++ gcc/testsuite/rust/compile/nested_generic.rs | 4 ++++ .../parse_associated_type_as_generic_arg.rs | 24 ++++++++++++++++++++++ .../parse_associated_type_as_generic_arg2.rs | 24 ++++++++++++++++++++++ gcc/testsuite/rust/compile/path_as_generic_arg.rs | 12 +++++++++++ 5 files changed, 68 insertions(+) create mode 100644 gcc/testsuite/rust/compile/nested_generic.rs create mode 100644 gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg.rs create mode 100644 gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg2.rs create mode 100644 gcc/testsuite/rust/compile/path_as_generic_arg.rs (limited to 'gcc') diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 4c39284..3bf26bc 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -6383,6 +6383,9 @@ template AST::GenericArgs Parser::parse_path_generic_args () { + if (lexer.peek_token ()->get_id () == LEFT_SHIFT) + lexer.split_current_token (LEFT_ANGLE, LEFT_ANGLE); + if (!skip_token (LEFT_ANGLE)) { // skip after somewhere? @@ -6557,6 +6560,7 @@ Parser::parse_type_path_segment () const_TokenPtr t = lexer.peek_token (); switch (t->get_id ()) { + case LEFT_SHIFT: case LEFT_ANGLE: { // parse generic args AST::GenericArgs generic_args = parse_path_generic_args (); diff --git a/gcc/testsuite/rust/compile/nested_generic.rs b/gcc/testsuite/rust/compile/nested_generic.rs new file mode 100644 index 0000000..6c31099 --- /dev/null +++ b/gcc/testsuite/rust/compile/nested_generic.rs @@ -0,0 +1,4 @@ +pub struct A(T); +pub struct B(T); + +pub fn foo(_: A>) {} diff --git a/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg.rs b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg.rs new file mode 100644 index 0000000..dc05c06 --- /dev/null +++ b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg.rs @@ -0,0 +1,24 @@ +// { dg-additional-options "-fsyntax-only" } + +trait Foo { + type A; + + fn foo(); +} + +struct S; + +impl Foo for S { + type A = i32; + + fn foo() {} +} + +enum Maybe { + Something(T), + Nothing, +} + +fn foo() -> Maybe<::A> { + Maybe::Something(15) +} diff --git a/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg2.rs b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg2.rs new file mode 100644 index 0000000..9c518a03 --- /dev/null +++ b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg2.rs @@ -0,0 +1,24 @@ +// { dg-additional-options "-fsyntax-only" } + +trait Foo { + type A; + + fn foo(); +} + +struct S; + +impl Foo for S { + type A = (); + + fn foo() {} +} + +enum Maybe { + Something(T), + Nothing, +} + +fn main() { + let a: Maybe<::A> = Maybe::Something(()); +} diff --git a/gcc/testsuite/rust/compile/path_as_generic_arg.rs b/gcc/testsuite/rust/compile/path_as_generic_arg.rs new file mode 100644 index 0000000..35b3160 --- /dev/null +++ b/gcc/testsuite/rust/compile/path_as_generic_arg.rs @@ -0,0 +1,12 @@ +pub enum Result { + Ok(T), + Err(E), +} + +pub mod module { + pub struct E; +} + +pub fn foo() -> Result<(), module::E> { + Result::Err(module::E) +} -- cgit v1.1