From: Islam-Imad <[email protected]>

The parser was accepting 'dyn' as a standalone type in contexts like:
  static STATIC_1: dyn = 1;

This invalid syntax should be rejected at parse time.

Fixes Rust-GCC/gccrs#3905

gcc/rust/ChangeLog:

        * lex/rust-lex.cc (is_whitespace): refactor if-else to switch
        * lex/rust-token.h: refactor if-else to switch
        * parse/rust-parse-impl.hxx: return nullptr when type is in invalid 
state

gcc/testsuite/ChangeLog:

        * rust/compile/issue-3904.rs: refactor the testcase to match the new 
thrown error

Signed-off-by: Islam-Imad <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/3ecd7b90c984f5f15b1a1313b943af36893f4199

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4421

 gcc/rust/lex/rust-lex.cc                 | 24 +++++++++++++++++-------
 gcc/rust/lex/rust-token.h                | 12 ++++++++++--
 gcc/rust/parse/rust-parse-impl.hxx       |  2 ++
 gcc/testsuite/rust/compile/issue-3904.rs | 10 +++++++++-
 4 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index 9edfd81ff..599358e44 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -110,13 +110,23 @@ bool
 is_whitespace (uint32_t character)
 {
   // https://doc.rust-lang.org/reference/whitespace.html
-  return character == '\t' || character == '\n' || character == '\v'
-        || character == '\f' || character == '\r' || character == ' '
-        || character == 0x0085  // next line
-        || character == 0x200e  // left-to-right mark
-        || character == 0x200f  // right-to-left mark
-        || character == 0x2028  // line separator
-        || character == 0x2029; // pragraph separator
+  switch (character)
+    {
+    case '\t':
+    case '\n':
+    case '\v':
+    case '\f':
+    case '\r':
+    case ' ':
+    case 0x0085: // next line
+    case 0x200e: // left-to-right mark
+    case 0x200f: // right-to-left mark
+    case 0x2028: // line separator
+    case 0x2029: // paragraph separator
+      return true;
+    default:
+      return false;
+    }
 }
 
 bool
diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h
index 6fcf40d5f..f6741363f 100644
--- a/gcc/rust/lex/rust-token.h
+++ b/gcc/rust/lex/rust-token.h
@@ -466,8 +466,16 @@ public:
   // Returns whether the token should have a string.
   bool should_have_str () const
   {
-    return is_literal () || token_id == IDENTIFIER || token_id == LIFETIME
-          || token_id == INNER_DOC_COMMENT || token_id == OUTER_DOC_COMMENT;
+    switch (token_id)
+      {
+      case IDENTIFIER:
+      case LIFETIME:
+      case INNER_DOC_COMMENT:
+      case OUTER_DOC_COMMENT:
+       return true;
+      default:
+       return is_literal ();
+      }
   }
 
   // Returns whether the token is a pure decimal int literal
diff --git a/gcc/rust/parse/rust-parse-impl.hxx 
b/gcc/rust/parse/rust-parse-impl.hxx
index 9766cafa1..bfa545b7c 100644
--- a/gcc/rust/parse/rust-parse-impl.hxx
+++ b/gcc/rust/parse/rust-parse-impl.hxx
@@ -2750,6 +2750,8 @@ Parser<ManagedTokenSource>::parse_trait_bound ()
 
   // handle TypePath
   AST::TypePath type_path = parse_type_path ();
+  if (type_path.is_error())
+    return nullptr;
 
   // handle closing parentheses
   if (has_parens)
diff --git a/gcc/testsuite/rust/compile/issue-3904.rs 
b/gcc/testsuite/rust/compile/issue-3904.rs
index 87a46f044..bfff70cd5 100644
--- a/gcc/testsuite/rust/compile/issue-3904.rs
+++ b/gcc/testsuite/rust/compile/issue-3904.rs
@@ -1,4 +1,12 @@
 #![feature(no_core)]
 #![no_core]
 
-static STATIC_1: dyn = *#[serde()]; // { dg-error "found unexpected token .;. 
in null denotation" "" { target *-*-* } 0 }
+trait A {}
+impl A for i32 {}
+fn main() {
+    let _a: &dyn A = &1;
+}
+
+static STATIC_1: dyn = 1; // {  dg-error "failed to parse TraitObjectType 
initial bound" "" { target *-*-* }   }
+static STATIC_2: dyn = *#[serde()]; // {  dg-error "failed to parse 
TraitObjectType initial bound" "" { target *-*-* }   }
+                                    // { dg-error "found unexpected token .;. 
in null denotation" "" { target *-*-* } .-1 }

base-commit: 291a2f40903783fe3544c3cf02065ddeed75defe
-- 
2.52.0

Reply via email to