From 435416e8459e8d89bb3c28aa61ceb1cd7099a89d Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Patry Date: Thu, 5 Feb 2026 13:58:11 +0100 Subject: [PATCH] gccrs: Add early cfg strip step before feature collection Features are now collected early rather than later during the feature gating visitor. This requires the introduction of an early cfg strip in order to collect #![cfg(xxxx), feature(yyyy)] correctly. gcc/rust/ChangeLog: * Make-lang.in: Add rust-early-cfg-strip object file. * expand/rust-cfg-strip.h (expand_cfg_attrs): Declare function prototype. * rust-session-manager.cc (Session::compile_crate): Reorder feature collection and add early cfg strip. * expand/rust-early-cfg-strip.cc: New file. * expand/rust-early-cfg-strip.h: New file. Signed-off-by: Pierre-Emmanuel Patry --- gcc/rust/Make-lang.in | 1 + gcc/rust/expand/rust-cfg-strip.h | 2 ++ gcc/rust/expand/rust-early-cfg-strip.cc | 38 +++++++++++++++++++++++ gcc/rust/expand/rust-early-cfg-strip.h | 41 +++++++++++++++++++++++++ gcc/rust/rust-session-manager.cc | 14 +++++++-- 5 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 gcc/rust/expand/rust-early-cfg-strip.cc create mode 100644 gcc/rust/expand/rust-early-cfg-strip.h diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index b5d837f4685..bd5eb8654fc 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -94,6 +94,7 @@ GRS_OBJS = \ rust/rust-compile-resolve-path.o \ rust/rust-macro-expand.o \ rust/rust-cfg-strip.o \ + rust/rust-early-cfg-strip.o \ rust/rust-expand-visitor.o \ rust/rust-ast-builder.o \ rust/rust-derive.o \ diff --git a/gcc/rust/expand/rust-cfg-strip.h b/gcc/rust/expand/rust-cfg-strip.h index dfe724a778f..e372744f62d 100644 --- a/gcc/rust/expand/rust-cfg-strip.h +++ b/gcc/rust/expand/rust-cfg-strip.h @@ -24,6 +24,8 @@ namespace Rust { +void expand_cfg_attrs (AST::AttrVec &attrs); + // forward declare struct ExpansionCfg; diff --git a/gcc/rust/expand/rust-early-cfg-strip.cc b/gcc/rust/expand/rust-early-cfg-strip.cc new file mode 100644 index 00000000000..bc0e4b5b0d4 --- /dev/null +++ b/gcc/rust/expand/rust-early-cfg-strip.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2026 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + +#include "rust-early-cfg-strip.h" +#include "rust-cfg-strip.h" + +namespace Rust { + +void +EarlyCfgStrip::go (AST::Crate &crate) +{ + visit (crate); +} + +void +EarlyCfgStrip::visit (AST::Crate &crate) +{ + expand_cfg_attrs (crate.inner_attrs); + + AST::DefaultASTVisitor::visit (crate); +} + +} // namespace Rust diff --git a/gcc/rust/expand/rust-early-cfg-strip.h b/gcc/rust/expand/rust-early-cfg-strip.h new file mode 100644 index 00000000000..b342aee90c4 --- /dev/null +++ b/gcc/rust/expand/rust-early-cfg-strip.h @@ -0,0 +1,41 @@ +// Copyright (C) 2026 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + +#ifndef RUST_EARLY_CFG_STRIP_H +#define RUST_EARLY_CFG_STRIP_H + +#include "rust-ast-visitor.h" + +namespace Rust { + +/** + * Some parts cannot be stripped during the expansion passes + */ +class EarlyCfgStrip : AST::DefaultASTVisitor +{ +public: + using DefaultASTVisitor::visit; + + void go (AST::Crate &crate); + + void visit (AST::Crate &crate) override; +}; + +} // namespace Rust + +#endif diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index 67adb103cee..cf3237ccd71 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -52,6 +52,7 @@ #include "rust-early-name-resolver-2.0.h" #include "rust-late-name-resolver-2.0.h" #include "rust-resolve-builtins.h" +#include "rust-early-cfg-strip.h" #include "rust-cfg-strip.h" #include "rust-expand-visitor.h" #include "rust-unicode.h" @@ -669,7 +670,15 @@ Session::compile_crate (const char *filename) Analysis::AttributeChecker ().go (parsed_crate); - if (!has_attribute (parsed_crate, std::string (Values::Attributes::NO_CORE))) + EarlyCfgStrip ().go (parsed_crate); + + auto parsed_crate_features + = Features::FeatureCollector{}.collect (parsed_crate); + + // Do not inject core if some errors were emitted + if (!saw_errors () + && !has_attribute (parsed_crate, + std::string (Values::Attributes::NO_CORE))) { parsed_crate.inject_extern_crate ("core"); } @@ -702,8 +711,7 @@ Session::compile_crate (const char *filename) // feature gating if (last_step == CompileOptions::CompileStep::FeatureGating) return; - auto parsed_crate_features - = Features::FeatureCollector{}.collect (parsed_crate); + FeatureGate (parsed_crate_features).check (parsed_crate); if (last_step == CompileOptions::CompileStep::NameResolution)