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)