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)