]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix Self macro invocation parsing failure
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Tue, 12 Aug 2025 15:40:27 +0000 (17:40 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 19:58:39 +0000 (20:58 +0100)
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 <pierre-emmanuel.patry@embecosm.com>
gcc/rust/ast/rust-path.cc
gcc/rust/parse/rust-parse-impl.h
gcc/testsuite/rust/compile/issue-3974.rs [new file with mode: 0644]

index 60ca4355cf07427ca3ac8b14d5b8bc4a27e911af..068e364d1848946976f0210eb86f7aa975774dbc 100644 (file)
@@ -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
index 38bf85e49d8ba9ca2405b6787241e09d74c07b62..5694ec5951db80f57f820d23a4c2e5e2b197e098 100644 (file)
@@ -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 (file)
index 0000000..dfd693a
--- /dev/null
@@ -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 }
+    }
+}