diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2023-02-03 12:45:58 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-03 12:45:58 +0000 |
commit | 1f96413438de938667d59557306103a809762449 (patch) | |
tree | bd1bf0a3a4869e4e9ed60bbfe299d38744430246 | |
parent | 71bd5b22726c536636628b62cdabfd489c06002e (diff) | |
parent | cddb1f2d9f965aa6386a71369109edd61506118e (diff) | |
download | gcc-1f96413438de938667d59557306103a809762449.zip gcc-1f96413438de938667d59557306103a809762449.tar.gz gcc-1f96413438de938667d59557306103a809762449.tar.bz2 |
Merge #1812
1812: parser: Allow parsing multiple reference types r=CohenArthur a=CohenArthur
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.
Addresses #1807 partly
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 33 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse.h | 2 | ||||
-rw-r--r-- | 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 f60d34f..e33a66d 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -9237,6 +9237,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: { @@ -9886,14 +9887,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) @@ -9932,6 +9929,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> @@ -10079,7 +10099,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 5c0fcc3..2f767bb 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 0000000..5ad7d84 --- /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; +} |