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]>
---
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 9edfd81fff7..599358e44b3 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 6fcf40d5fd9..f6741363fec 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 9766cafa16a..bfa545b7c96 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 87a46f044c9..bfff70cd5be 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 }
--
2.50.1