https://gcc.gnu.org/g:2da40ca97dc7396715e1a63a1c2b186edc92665f
commit r17-1077-g2da40ca97dc7396715e1a63a1c2b186edc92665f Author: Pierre-Emmanuel Patry <[email protected]> Date: Fri Apr 3 13:21:14 2026 +0200 gccrs: Add assert macro handler Assert macro handler was missing, insert a basic handler that desugars to a condition and a call to panic. gcc/rust/ChangeLog: * expand/rust-macro-builtins-log-debug.cc (MacroBuiltin::assert_handler): Add basic assert builtin macro handler. gcc/testsuite/ChangeLog: * rust/compile/assert_missing_panic.rs: New test. Signed-off-by: Pierre-Emmanuel Patry <[email protected]> Diff: --- gcc/rust/expand/rust-macro-builtins-log-debug.cc | 72 ++++++++++++++++++++++ gcc/testsuite/rust/compile/assert_missing_panic.rs | 12 ++++ 2 files changed, 84 insertions(+) diff --git a/gcc/rust/expand/rust-macro-builtins-log-debug.cc b/gcc/rust/expand/rust-macro-builtins-log-debug.cc index d80e7b66c5c0..cef34eb1e033 100644 --- a/gcc/rust/expand/rust-macro-builtins-log-debug.cc +++ b/gcc/rust/expand/rust-macro-builtins-log-debug.cc @@ -19,6 +19,9 @@ #include "rust-ast-fragment.h" #include "rust-macro-builtins.h" #include "rust-macro-builtins-helpers.h" +#include "rust-ast-builder.h" +#include "optional.h" +#include "rust-ast-collector.h" namespace Rust { tl::optional<AST::Fragment> @@ -27,6 +30,75 @@ MacroBuiltin::assert_handler (location_t invoc_locus, AST::InvocKind semicolon) { rust_debug ("assert!() called"); + auto tt = invoc.get_delim_tok_tree (); + MacroInvocLexer lex (tt.to_token_stream ()); + Parser<MacroInvocLexer> parser (lex); + + auto last_token_id = macro_end_token (tt, parser); + bool has_error = false; + + auto expanded_expr = try_expand_many_expr (parser, last_token_id, + invoc.get_expander (), has_error); + if (expanded_expr.size () < 1) + { + rust_error_at (invoc_locus, + "macro requires a boolean expression as an argument"); + return AST::Fragment::create_error (); + } + auto expr_to_assert = std::move (expanded_expr[0]); + expanded_expr.erase (expanded_expr.begin ()); + + if (expanded_expr.size () > 1) + { + rust_sorry_at ( + invoc_locus, + "The second form of assert with a message is not supported yet"); + + return AST::Fragment::create_error (); + } + + auto pending_invocations = check_for_eager_invocations (expanded_expr); + if (!pending_invocations.empty ()) + return make_eager_builtin_invocation (BuiltinMacro::Assert, invoc_locus, + invoc.get_delim_tok_tree (), + std::move (pending_invocations)); + + AST::Builder b (invoc_locus); + + std::vector<std::unique_ptr<AST::TokenTree>> panic_tree; + const_TokenPtr open = Token::make (TokenId::LEFT_PAREN, invoc_locus); + panic_tree.push_back (std::make_unique<AST::Token> (std::move (open))); + + const_TokenPtr close = Token::make (TokenId::RIGHT_PAREN, invoc_locus); + panic_tree.push_back (std::make_unique<AST::Token> (std::move (close))); + + auto panic = AST::MacroInvocation::Regular ( + AST::MacroInvocData (AST::SimplePath (Identifier ("panic")), + AST::DelimTokenTree (AST::DelimType::PARENS, + std::move (panic_tree), + invoc_locus)), + {} /* outer attributes */, invoc_locus, true /* semicoloned */); + auto stmt = b.statementify (std::move (panic)); + std::vector<std::unique_ptr<AST::Stmt>> stmts; + stmts.push_back (std::move (stmt)); + auto block = b.block (std::move (stmts)); + auto negated_condition = std::unique_ptr<AST::NegationExpr> ( + new AST::NegationExpr (std::move (expr_to_assert), + AST::NegationExpr::ExprType::NOT, {}, invoc_locus)); + + auto if_expr = std::make_unique<AST::IfExpr> ( + std::move (negated_condition) /* condition*/, std::move (block), + std::vector<AST::Attribute>{}, invoc_locus); + + auto node = AST::SingleASTNode (std::move (if_expr)); + + AST::TokenCollector collector; + collector.visit (node); + std::vector<std::unique_ptr<AST::Token>> tokens; + for (auto &&token : collector.collect_tokens ()) + tokens.push_back (std::make_unique<AST::Token> (token)); + + return AST::Fragment ({node}, std::move (tokens)); return AST::Fragment::create_error (); } diff --git a/gcc/testsuite/rust/compile/assert_missing_panic.rs b/gcc/testsuite/rust/compile/assert_missing_panic.rs new file mode 100644 index 000000000000..71f87aece385 --- /dev/null +++ b/gcc/testsuite/rust/compile/assert_missing_panic.rs @@ -0,0 +1,12 @@ +#![feature(rustc_attrs)] +#![feature(no_core)] +#![no_core] + +#[macro_export] +#[rustc_builtin_macro] +macro_rules! assert { + ($($arg:tt)*) => {}; +} + +const _: () = assert!(true); +// { dg-error "could not resolve macro invocation .panic." "" { target *-*-* } .-1 }
