Skip to content

Commit 5f3abbc

Browse files
committed
Auto merge of rust-lang#114723 - petrochenkov:noplugin2, r=davidtwco
rustc: Move `features` from `Session` to `GlobalCtxt` Removes one more piece of mutable state. Follow up to rust-lang#114622. The rule I used for passing feature in function signatures: - if a crate already depends on `rustc_middle`, then `Session` is replaced with `TyCtxt` - otherwise session and features are passed as a pair `sess: &Session, features: &Features` The code in `rustc_lint` is ultimately used for implementing a trait from `rustc_expand`, so it also doesn't use tcx despite the dependency on `rustc_middle`.
2 parents 1702d0f + 7353c96 commit 5f3abbc

File tree

30 files changed

+130
-93
lines changed

30 files changed

+130
-93
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3805,6 +3805,7 @@ dependencies = [
38053805
"rustc_data_structures",
38063806
"rustc_errors",
38073807
"rustc_expand",
3808+
"rustc_feature",
38083809
"rustc_fluent_macro",
38093810
"rustc_fs_util",
38103811
"rustc_hir",

compiler/rustc_ast_passes/src/ast_validation.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_ast::*;
1313
use rustc_ast::{walk_list, StaticItem};
1414
use rustc_ast_pretty::pprust::{self, State};
1515
use rustc_data_structures::fx::FxIndexMap;
16+
use rustc_feature::Features;
1617
use rustc_macros::Subdiagnostic;
1718
use rustc_parse::validate_attr;
1819
use rustc_session::lint::builtin::{
@@ -45,6 +46,7 @@ enum DisallowTildeConstContext<'a> {
4546

4647
struct AstValidator<'a> {
4748
session: &'a Session,
49+
features: &'a Features,
4850

4951
/// The span of the `extern` in an `extern { ... }` block, if any.
5052
extern_mod: Option<&'a Item>,
@@ -1023,7 +1025,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10231025
}
10241026
self.check_type_no_bounds(bounds, "this context");
10251027

1026-
if self.session.features_untracked().lazy_type_alias {
1028+
if self.features.lazy_type_alias {
10271029
if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) {
10281030
self.err_handler().emit_err(err);
10291031
}
@@ -1500,9 +1502,15 @@ fn deny_equality_constraints(
15001502
this.err_handler().emit_err(err);
15011503
}
15021504

1503-
pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool {
1505+
pub fn check_crate(
1506+
session: &Session,
1507+
features: &Features,
1508+
krate: &Crate,
1509+
lints: &mut LintBuffer,
1510+
) -> bool {
15041511
let mut validator = AstValidator {
15051512
session,
1513+
features,
15061514
extern_mod: None,
15071515
in_trait_impl: false,
15081516
in_const_trait_impl: false,

compiler/rustc_ast_passes/src/feature_gate.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -514,10 +514,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
514514
}
515515
}
516516

517-
pub fn check_crate(krate: &ast::Crate, sess: &Session) {
518-
maybe_stage_features(sess, krate);
519-
check_incompatible_features(sess);
520-
let mut visitor = PostExpansionVisitor { sess, features: &sess.features_untracked() };
517+
pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
518+
maybe_stage_features(sess, features, krate);
519+
check_incompatible_features(sess, features);
520+
let mut visitor = PostExpansionVisitor { sess, features };
521521

522522
let spans = sess.parse_sess.gated_spans.spans.borrow();
523523
macro_rules! gate_all {
@@ -600,12 +600,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
600600
visit::walk_crate(&mut visitor, krate);
601601
}
602602

603-
fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
603+
fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate) {
604604
// checks if `#![feature]` has been used to enable any lang feature
605605
// does not check the same for lib features unless there's at least one
606606
// declared lang feature
607607
if !sess.opts.unstable_features.is_nightly_build() {
608-
let lang_features = &sess.features_untracked().declared_lang_features;
608+
let lang_features = &features.declared_lang_features;
609609
if lang_features.len() == 0 {
610610
return;
611611
}
@@ -640,9 +640,7 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
640640
}
641641
}
642642

643-
fn check_incompatible_features(sess: &Session) {
644-
let features = sess.features_untracked();
645-
643+
fn check_incompatible_features(sess: &Session, features: &Features) {
646644
let declared_features = features
647645
.declared_lang_features
648646
.iter()

compiler/rustc_attr/src/builtin.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -800,18 +800,15 @@ pub struct Deprecation {
800800
}
801801

802802
/// Finds the deprecation attribute. `None` if none exists.
803-
pub fn find_deprecation(sess: &Session, attrs: &[Attribute]) -> Option<(Deprecation, Span)> {
804-
find_deprecation_generic(sess, attrs.iter())
805-
}
806-
807-
fn find_deprecation_generic<'a, I>(sess: &Session, attrs_iter: I) -> Option<(Deprecation, Span)>
808-
where
809-
I: Iterator<Item = &'a Attribute>,
810-
{
803+
pub fn find_deprecation(
804+
sess: &Session,
805+
features: &Features,
806+
attrs: &[Attribute],
807+
) -> Option<(Deprecation, Span)> {
811808
let mut depr: Option<(Deprecation, Span)> = None;
812-
let is_rustc = sess.features_untracked().staged_api;
809+
let is_rustc = features.staged_api;
813810

814-
'outer: for attr in attrs_iter {
811+
'outer: for attr in attrs {
815812
if !attr.has_name(sym::deprecated) {
816813
continue;
817814
}
@@ -872,7 +869,7 @@ where
872869
}
873870
}
874871
sym::suggestion => {
875-
if !sess.features_untracked().deprecated_suggestion {
872+
if !features.deprecated_suggestion {
876873
sess.emit_err(session_diagnostics::DeprecatedItemSuggestion {
877874
span: mi.span,
878875
is_nightly: sess.is_nightly_build().then_some(()),
@@ -890,7 +887,7 @@ where
890887
meta.span(),
891888
AttrError::UnknownMetaItem(
892889
pprust::path_to_string(&mi.path),
893-
if sess.features_untracked().deprecated_suggestion {
890+
if features.deprecated_suggestion {
894891
&["since", "note", "suggestion"]
895892
} else {
896893
&["since", "note"]

compiler/rustc_builtin_macros/src/assert.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub fn expand_assert<'cx>(
6969
// If `generic_assert` is enabled, generates rich captured outputs
7070
//
7171
// FIXME(c410-f3r) See https://github.com/rust-lang/rust/issues/96949
72-
else if let Some(features) = cx.ecfg.features && features.generic_assert {
72+
else if cx.ecfg.features.generic_assert {
7373
context::Context::new(cx, call_site_span).build(cond_expr, panic_path())
7474
}
7575
// If `generic_assert` is not enabled, only outputs a literal "assertion failed: ..."

compiler/rustc_builtin_macros/src/cfg.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn expand_cfg(
2424
&cfg,
2525
&cx.sess.parse_sess,
2626
cx.current_expansion.lint_node_id,
27-
cx.ecfg.features,
27+
Some(cx.ecfg.features),
2828
);
2929
MacEager::expr(cx.expr_bool(sp, matches_cfg))
3030
}

compiler/rustc_builtin_macros/src/cfg_eval.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ pub(crate) fn expand(
3131

3232
pub(crate) fn cfg_eval(
3333
sess: &Session,
34-
features: Option<&Features>,
34+
features: &Features,
3535
annotatable: Annotatable,
3636
lint_node_id: NodeId,
3737
) -> Annotatable {
38+
let features = Some(features);
3839
CfgEval { cfg: &mut StripUnconfigured { sess, features, config_tokens: true, lint_node_id } }
3940
.configure_annotatable(annotatable)
4041
// Since the item itself has already been configured by the `InvocationCollector`,

compiler/rustc_builtin_macros/src/proc_macro_harness.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_ast::{self as ast, attr, NodeId};
55
use rustc_ast_pretty::pprust;
66
use rustc_expand::base::{parse_macro_name_and_helper_attrs, ExtCtxt, ResolverExpand};
77
use rustc_expand::expand::{AstFragment, ExpansionConfig};
8+
use rustc_feature::Features;
89
use rustc_session::Session;
910
use rustc_span::hygiene::AstPass;
1011
use rustc_span::source_map::SourceMap;
@@ -46,13 +47,14 @@ struct CollectProcMacros<'a> {
4647
pub fn inject(
4748
krate: &mut ast::Crate,
4849
sess: &Session,
50+
features: &Features,
4951
resolver: &mut dyn ResolverExpand,
5052
is_proc_macro_crate: bool,
5153
has_proc_macro_decls: bool,
5254
is_test_crate: bool,
5355
handler: &rustc_errors::Handler,
5456
) {
55-
let ecfg = ExpansionConfig::default("proc_macro".to_string());
57+
let ecfg = ExpansionConfig::default("proc_macro".to_string(), features);
5658
let mut cx = ExtCtxt::new(sess, ecfg, resolver, None);
5759

5860
let mut collect = CollectProcMacros {

compiler/rustc_builtin_macros/src/standard_library_imports.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_ast::{self as ast, attr};
22
use rustc_expand::base::{ExtCtxt, ResolverExpand};
33
use rustc_expand::expand::ExpansionConfig;
4+
use rustc_feature::Features;
45
use rustc_session::Session;
56
use rustc_span::edition::Edition::*;
67
use rustc_span::hygiene::AstPass;
@@ -13,6 +14,7 @@ pub fn inject(
1314
pre_configured_attrs: &[ast::Attribute],
1415
resolver: &mut dyn ResolverExpand,
1516
sess: &Session,
17+
features: &Features,
1618
) -> usize {
1719
let orig_num_items = krate.items.len();
1820
let edition = sess.parse_sess.edition;
@@ -39,7 +41,7 @@ pub fn inject(
3941
let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
4042
let call_site = DUMMY_SP.with_call_site_ctxt(expn_id.to_expn_id());
4143

42-
let ecfg = ExpansionConfig::default("std_lib_injection".to_string());
44+
let ecfg = ExpansionConfig::default("std_lib_injection".to_string(), features);
4345
let cx = ExtCtxt::new(sess, ecfg, resolver, None);
4446

4547
// .rev() to preserve ordering above in combination with insert(0, ...)

compiler/rustc_builtin_macros/src/test_harness.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@ struct TestCtxt<'a> {
4141

4242
/// Traverse the crate, collecting all the test functions, eliding any
4343
/// existing main functions, and synthesizing a main test harness
44-
pub fn inject(krate: &mut ast::Crate, sess: &Session, resolver: &mut dyn ResolverExpand) {
44+
pub fn inject(
45+
krate: &mut ast::Crate,
46+
sess: &Session,
47+
features: &Features,
48+
resolver: &mut dyn ResolverExpand,
49+
) {
4550
let span_diagnostic = sess.diagnostic();
4651
let panic_strategy = sess.panic_strategy();
4752
let platform_panic_strategy = sess.target.panic_strategy;
@@ -76,7 +81,7 @@ pub fn inject(krate: &mut ast::Crate, sess: &Session, resolver: &mut dyn Resolve
7681
resolver,
7782
reexport_test_harness_main,
7883
krate,
79-
&sess.features_untracked(),
84+
features,
8085
panic_strategy,
8186
test_runner,
8287
)
@@ -243,9 +248,7 @@ fn generate_test_harness(
243248
panic_strategy: PanicStrategy,
244249
test_runner: Option<ast::Path>,
245250
) {
246-
let mut econfig = ExpansionConfig::default("test".to_string());
247-
econfig.features = Some(features);
248-
251+
let econfig = ExpansionConfig::default("test".to_string(), features);
249252
let ext_cx = ExtCtxt::new(sess, econfig, resolver, None);
250253

251254
let expn_id = ext_cx.resolver.expansion_for_ast_pass(

compiler/rustc_expand/src/base.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc_errors::{
1818
Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic,
1919
MultiSpan, PResult,
2020
};
21+
use rustc_feature::Features;
2122
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
2223
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, RegisteredTools};
2324
use rustc_parse::{self, parser, MACRO_ARGUMENTS};
@@ -767,6 +768,7 @@ impl SyntaxExtension {
767768
/// and other properties converted from attributes.
768769
pub fn new(
769770
sess: &Session,
771+
features: &Features,
770772
kind: SyntaxExtensionKind,
771773
span: Span,
772774
helper_attrs: Vec<Symbol>,
@@ -816,7 +818,7 @@ impl SyntaxExtension {
816818
allow_internal_unstable: (!allow_internal_unstable.is_empty())
817819
.then(|| allow_internal_unstable.into()),
818820
stability: stability.map(|(s, _)| s),
819-
deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d),
821+
deprecation: attr::find_deprecation(&sess, features, attrs).map(|(d, _)| d),
820822
helper_attrs,
821823
edition,
822824
builtin_name,
@@ -957,6 +959,7 @@ pub trait LintStoreExpand {
957959
fn pre_expansion_lint(
958960
&self,
959961
sess: &Session,
962+
features: &Features,
960963
registered_tools: &RegisteredTools,
961964
node_id: NodeId,
962965
attrs: &[Attribute],

compiler/rustc_expand/src/expand.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
796796
| Annotatable::FieldDef(..)
797797
| Annotatable::Variant(..) => panic!("unexpected annotatable"),
798798
};
799-
if self.cx.ecfg.proc_macro_hygiene() {
799+
if self.cx.ecfg.features.proc_macro_hygiene {
800800
return;
801801
}
802802
feature_err(
@@ -834,7 +834,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
834834
}
835835
}
836836

837-
if !self.cx.ecfg.proc_macro_hygiene() {
837+
if !self.cx.ecfg.features.proc_macro_hygiene {
838838
annotatable
839839
.visit_with(&mut GateProcMacroInput { parse_sess: &self.cx.sess.parse_sess });
840840
}
@@ -1122,6 +1122,7 @@ impl InvocationCollectorNode for P<ast::Item> {
11221122
if let Some(lint_store) = ecx.lint_store {
11231123
lint_store.pre_expansion_lint(
11241124
ecx.sess,
1125+
ecx.ecfg.features,
11251126
ecx.resolver.registered_tools(),
11261127
ecx.current_expansion.lint_node_id,
11271128
&attrs,
@@ -1580,7 +1581,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
15801581
fn cfg(&self) -> StripUnconfigured<'_> {
15811582
StripUnconfigured {
15821583
sess: &self.cx.sess,
1583-
features: self.cx.ecfg.features,
1584+
features: Some(self.cx.ecfg.features),
15841585
config_tokens: false,
15851586
lint_node_id: self.cx.current_expansion.lint_node_id,
15861587
}
@@ -1676,7 +1677,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
16761677
// Detect use of feature-gated or invalid attributes on macro invocations
16771678
// since they will not be detected after macro expansion.
16781679
fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
1679-
let features = self.cx.ecfg.features.unwrap();
1680+
let features = self.cx.ecfg.features;
16801681
let mut attrs = attrs.iter().peekable();
16811682
let mut span: Option<Span> = None;
16821683
while let Some(attr) = attrs.next() {
@@ -1976,7 +1977,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
19761977

19771978
pub struct ExpansionConfig<'feat> {
19781979
pub crate_name: String,
1979-
pub features: Option<&'feat Features>,
1980+
pub features: &'feat Features,
19801981
pub recursion_limit: Limit,
19811982
pub trace_mac: bool,
19821983
/// If false, strip `#[test]` nodes
@@ -1987,20 +1988,16 @@ pub struct ExpansionConfig<'feat> {
19871988
pub proc_macro_backtrace: bool,
19881989
}
19891990

1990-
impl<'feat> ExpansionConfig<'feat> {
1991-
pub fn default(crate_name: String) -> ExpansionConfig<'static> {
1991+
impl ExpansionConfig<'_> {
1992+
pub fn default(crate_name: String, features: &Features) -> ExpansionConfig<'_> {
19921993
ExpansionConfig {
19931994
crate_name,
1994-
features: None,
1995+
features,
19951996
recursion_limit: Limit::new(1024),
19961997
trace_mac: false,
19971998
should_test: false,
19981999
span_debug: false,
19992000
proc_macro_backtrace: false,
20002001
}
20012002
}
2002-
2003-
fn proc_macro_hygiene(&self) -> bool {
2004-
self.features.is_some_and(|features| features.proc_macro_hygiene)
2005-
}
20062003
}

0 commit comments

Comments
 (0)