From: Pierre-Emmanuel Patry <[email protected]>
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 <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/07c1dd1d8f65103a81d2e73ccf14fc05d0ce1f79
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4425
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 b5d837f46..bd5eb8654 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 dfe724a77..e372744f6 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 000000000..bc0e4b5b0
--- /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
+// <http://www.gnu.org/licenses/>.
+
+#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 000000000..b342aee90
--- /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
+// <http://www.gnu.org/licenses/>.
+
+#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 67adb103c..cf3237ccd 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)
--
2.53.0