https://gcc.gnu.org/g:947c32385e0398e8320a0192d8825bd4b997bc24
commit r16-4784-g947c32385e0398e8320a0192d8825bd4b997bc24 Author: Pierre-Emmanuel Patry <[email protected]> Date: Tue Aug 12 17:40:27 2025 +0200 gccrs: Fix Self macro invocation parsing failure 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]> Diff: --- 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(-) diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc index 60ca4355cf07..068e364d1848 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 38bf85e49d8b..5694ec5951db 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 000000000000..dfd693a51b1b --- /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 } + } +}
