public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] parser: Allow parsing multiple reference types
@ 2023-02-07 17:53 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2023-02-07 17:53 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:cddb1f2d9f965aa6386a71369109edd61506118e

commit cddb1f2d9f965aa6386a71369109edd61506118e
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date:   Wed Feb 1 11:40:13 2023 +0100

    parser: Allow parsing multiple reference types
    
    The parser now recursively tries to parse a reference type after seeing
    a `&` or `&&` token.
    
    gcc/rust/ChangeLog:
    
            * parse/rust-parse-impl.h (Parser::parse_type): Handle double ampersan
            properly
            (Parser::parse_reference_type): Call into `parse_reference_type_inner`
            and wrap double reference types in another `AST::ReferenceType` node
            (Parser::parse_reference_type_inner): Add parsing implementation
            which does not care about the leading token (& or  &&)
            (Parser::parse_type_no_bounds): Handle double ampersand properly
            * parse/rust-parse.h: Declare `parse_reference_type_inner`
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/multi_reference_type.rs: New test.

Diff:
---
 gcc/rust/parse/rust-parse-impl.h                   | 33 ++++++++++++++++++----
 gcc/rust/parse/rust-parse.h                        |  2 ++
 gcc/testsuite/rust/compile/multi_reference_type.rs | 12 ++++++++
 3 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index c19fe9b6ec4..19743c6c7f0 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -9239,6 +9239,7 @@ Parser<ManagedTokenSource>::parse_type (bool save_errors)
       // raw pointer type
       return parse_raw_pointer_type ();
     case AMP: // does this also include AMP_AMP?
+    case LOGICAL_AND:
       // reference type
       return parse_reference_type ();
       case LIFETIME: {
@@ -9889,14 +9890,10 @@ Parser<ManagedTokenSource>::parse_bare_function_type (
 			       std::move (return_type), best_try_locus));
 }
 
-// Parses a reference type (mutable or immutable, with given lifetime).
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::ReferenceType>
-Parser<ManagedTokenSource>::parse_reference_type ()
+Parser<ManagedTokenSource>::parse_reference_type_inner (Location locus)
 {
-  Location locus = lexer.peek_token ()->get_locus ();
-  skip_token (AMP);
-
   // parse optional lifetime
   AST::Lifetime lifetime = AST::Lifetime::error ();
   if (lexer.peek_token ()->get_id () == LIFETIME)
@@ -9935,6 +9932,29 @@ Parser<ManagedTokenSource>::parse_reference_type ()
 			    std::move (lifetime)));
 }
 
+// Parses a reference type (mutable or immutable, with given lifetime).
+template <typename ManagedTokenSource>
+std::unique_ptr<AST::ReferenceType>
+Parser<ManagedTokenSource>::parse_reference_type ()
+{
+  auto t = lexer.peek_token ();
+  auto locus = t->get_locus ();
+
+  switch (t->get_id ())
+    {
+    case AMP:
+      skip_token (AMP);
+      return parse_reference_type_inner (locus);
+    case LOGICAL_AND:
+      skip_token (LOGICAL_AND);
+      return std::unique_ptr<AST::ReferenceType> (
+	new AST::ReferenceType (false, parse_reference_type_inner (locus),
+				locus));
+    default:
+      gcc_unreachable ();
+    }
+}
+
 // Parses a raw (unsafe) pointer type.
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::RawPointerType>
@@ -10082,7 +10102,8 @@ Parser<ManagedTokenSource>::parse_type_no_bounds ()
     case ASTERISK:
       // raw pointer type
       return parse_raw_pointer_type ();
-    case AMP: // does this also include AMP_AMP?
+    case AMP: // does this also include AMP_AMP? Yes! Which is... LOGICAL_AND?
+    case LOGICAL_AND:
       // reference type
       return parse_reference_type ();
     case LIFETIME:
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 5c0fcc3f174..2f767bb2a53 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -604,6 +604,8 @@ private:
   std::unique_ptr<AST::TypeNoBounds> parse_type_no_bounds ();
   std::unique_ptr<AST::TypeNoBounds> parse_slice_or_array_type ();
   std::unique_ptr<AST::RawPointerType> parse_raw_pointer_type ();
+  std::unique_ptr<AST::ReferenceType>
+  parse_reference_type_inner (Location locus);
   std::unique_ptr<AST::ReferenceType> parse_reference_type ();
   std::unique_ptr<AST::BareFunctionType>
   parse_bare_function_type (std::vector<AST::LifetimeParam> for_lifetimes);
diff --git a/gcc/testsuite/rust/compile/multi_reference_type.rs b/gcc/testsuite/rust/compile/multi_reference_type.rs
new file mode 100644
index 00000000000..5ad7d84adbc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/multi_reference_type.rs
@@ -0,0 +1,12 @@
+fn main() {
+    let a = 15u8;
+    let a: &u8 = &a;
+    let a: &&u8 = &a;
+    let a: &&&u8 = &a;
+    let _: &&&&u8 = &a;
+
+    let _: &&u8;
+    let _: &mut &u8;
+    let _: &&mut u8;
+    let _: &mut &mut &u8;
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-02-07 17:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-07 17:53 [gcc/devel/rust/master] parser: Allow parsing multiple reference types Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).