From: Pierre-Emmanuel Patry <[email protected]>

No check was performed and the value was assumed non null.
Path conversion returned an empty path for "Self" due to a hack in
generics Self injection that prevented any "Self!" macro from beeing
recognized correctly.

gcc/rust/ChangeLog:

        * parse/rust-parse-impl.h (Parser::parse_stmt_or_expr): Add null check
        on parse_macro_invocation_partial call.
        * ast/rust-path.cc (Path::convert_to_simple_path): Do not exclude
        capitalized "Self".

gcc/testsuite/ChangeLog:

        * rust/compile/issue-3974.rs: New test.

Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
---
 gcc/rust/ast/rust-path.cc                |  3 +--
 gcc/rust/parse/rust-parse-impl.h         | 11 ++++++++---
 gcc/testsuite/rust/compile/issue-3974.rs |  8 ++++++++
 3 files changed, 17 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3974.rs

diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc
index 60ca4355cf0..068e364d184 100644
--- a/gcc/rust/ast/rust-path.cc
+++ b/gcc/rust/ast/rust-path.cc
@@ -167,8 +167,7 @@ Path::convert_to_simple_path (bool 
with_opening_scope_resolution) const
   for (const auto &segment : segments)
     {
       // return empty path if doesn't meet simple path segment requirements
-      if (segment.is_error () || segment.has_generic_args ()
-         || segment.as_string () == "Self")
+      if (segment.is_error () || segment.has_generic_args ())
        return SimplePath::create_empty ();
 
       // create segment and add to vector
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 38bf85e49d8..5694ec5951d 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -11761,6 +11761,8 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr ()
            std::unique_ptr<AST::MacroInvocation> invoc
              = parse_macro_invocation_partial (std::move (path),
                                                std::move (outer_attrs));
+           if (invoc == nullptr)
+             return ExprOrStmt::create_error ();
 
            if (restrictions.consume_semi && maybe_skip_token (SEMICOLON))
              {
@@ -11772,9 +11774,12 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr ()
 
            TokenId after_macro = lexer.peek_token ()->get_id ();
 
-           if (invoc->get_invoc_data ().get_delim_tok_tree ().get_delim_type ()
-                 == AST::CURLY
-               && after_macro != DOT && after_macro != QUESTION_MARK)
+           AST::DelimType delim_type = invoc->get_invoc_data ()
+                                         .get_delim_tok_tree ()
+                                         .get_delim_type ();
+
+           if (delim_type == AST::CURLY && after_macro != DOT
+               && after_macro != QUESTION_MARK)
              {
                rust_debug ("braced macro statement");
                return ExprOrStmt (
diff --git a/gcc/testsuite/rust/compile/issue-3974.rs 
b/gcc/testsuite/rust/compile/issue-3974.rs
new file mode 100644
index 00000000000..dfd693a51b1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3974.rs
@@ -0,0 +1,8 @@
+impl<'a, F> RunUntil<'a, F> {
+    // { dg-error "could not resolve type path" "" { target *-*-* } .-1 }
+    fn project<'pin>() -> Projection<'pin, 'a, F> {
+        // { dg-error "could not resolve type path" "" { target *-*-* } .-1 }
+        Self!()
+        // { dg-error "could not resolve macro invocation" "" { target *-*-* } 
.-1 }
+    }
+}
-- 
2.50.1

Reply via email to