rustc: Move features from Session to GlobalCtxt

Removes two pieces of mutable state.
Follow up to #114622.
This commit is contained in:
Vadim Petrochenkov 2023-08-09 20:28:00 +08:00
parent a07bc13e14
commit 7353c96be8
30 changed files with 130 additions and 93 deletions

View file

@ -3805,6 +3805,7 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_expand",
"rustc_feature",
"rustc_fluent_macro",
"rustc_fs_util",
"rustc_hir",

View file

@ -13,6 +13,7 @@
use rustc_ast::{walk_list, StaticItem};
use rustc_ast_pretty::pprust::{self, State};
use rustc_data_structures::fx::FxIndexMap;
use rustc_feature::Features;
use rustc_macros::Subdiagnostic;
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::{
@ -45,6 +46,7 @@ enum DisallowTildeConstContext<'a> {
struct AstValidator<'a> {
session: &'a Session,
features: &'a Features,
/// The span of the `extern` in an `extern { ... }` block, if any.
extern_mod: Option<&'a Item>,
@ -1023,7 +1025,7 @@ fn visit_item(&mut self, item: &'a Item) {
}
self.check_type_no_bounds(bounds, "this context");
if self.session.features_untracked().lazy_type_alias {
if self.features.lazy_type_alias {
if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) {
self.err_handler().emit_err(err);
}
@ -1500,9 +1502,15 @@ fn deny_equality_constraints(
this.err_handler().emit_err(err);
}
pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool {
pub fn check_crate(
session: &Session,
features: &Features,
krate: &Crate,
lints: &mut LintBuffer,
) -> bool {
let mut validator = AstValidator {
session,
features,
extern_mod: None,
in_trait_impl: false,
in_const_trait_impl: false,

View file

@ -514,10 +514,10 @@ fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
}
}
pub fn check_crate(krate: &ast::Crate, sess: &Session) {
maybe_stage_features(sess, krate);
check_incompatible_features(sess);
let mut visitor = PostExpansionVisitor { sess, features: &sess.features_untracked() };
pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
maybe_stage_features(sess, features, krate);
check_incompatible_features(sess, features);
let mut visitor = PostExpansionVisitor { sess, features };
let spans = sess.parse_sess.gated_spans.spans.borrow();
macro_rules! gate_all {
@ -600,12 +600,12 @@ macro_rules! gate_all {
visit::walk_crate(&mut visitor, krate);
}
fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate) {
// checks if `#![feature]` has been used to enable any lang feature
// does not check the same for lib features unless there's at least one
// declared lang feature
if !sess.opts.unstable_features.is_nightly_build() {
let lang_features = &sess.features_untracked().declared_lang_features;
let lang_features = &features.declared_lang_features;
if lang_features.len() == 0 {
return;
}
@ -640,9 +640,7 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
}
}
fn check_incompatible_features(sess: &Session) {
let features = sess.features_untracked();
fn check_incompatible_features(sess: &Session, features: &Features) {
let declared_features = features
.declared_lang_features
.iter()

View file

@ -800,18 +800,15 @@ pub struct Deprecation {
}
/// Finds the deprecation attribute. `None` if none exists.
pub fn find_deprecation(sess: &Session, attrs: &[Attribute]) -> Option<(Deprecation, Span)> {
find_deprecation_generic(sess, attrs.iter())
}
fn find_deprecation_generic<'a, I>(sess: &Session, attrs_iter: I) -> Option<(Deprecation, Span)>
where
I: Iterator<Item = &'a Attribute>,
{
pub fn find_deprecation(
sess: &Session,
features: &Features,
attrs: &[Attribute],
) -> Option<(Deprecation, Span)> {
let mut depr: Option<(Deprecation, Span)> = None;
let is_rustc = sess.features_untracked().staged_api;
let is_rustc = features.staged_api;
'outer: for attr in attrs_iter {
'outer: for attr in attrs {
if !attr.has_name(sym::deprecated) {
continue;
}
@ -872,7 +869,7 @@ fn find_deprecation_generic<'a, I>(sess: &Session, attrs_iter: I) -> Option<(Dep
}
}
sym::suggestion => {
if !sess.features_untracked().deprecated_suggestion {
if !features.deprecated_suggestion {
sess.emit_err(session_diagnostics::DeprecatedItemSuggestion {
span: mi.span,
is_nightly: sess.is_nightly_build().then_some(()),
@ -890,7 +887,7 @@ fn find_deprecation_generic<'a, I>(sess: &Session, attrs_iter: I) -> Option<(Dep
meta.span(),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
if sess.features_untracked().deprecated_suggestion {
if features.deprecated_suggestion {
&["since", "note", "suggestion"]
} else {
&["since", "note"]

View file

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

View file

@ -24,7 +24,7 @@ pub fn expand_cfg(
&cfg,
&cx.sess.parse_sess,
cx.current_expansion.lint_node_id,
cx.ecfg.features,
Some(cx.ecfg.features),
);
MacEager::expr(cx.expr_bool(sp, matches_cfg))
}

View file

@ -31,10 +31,11 @@ pub(crate) fn expand(
pub(crate) fn cfg_eval(
sess: &Session,
features: Option<&Features>,
features: &Features,
annotatable: Annotatable,
lint_node_id: NodeId,
) -> Annotatable {
let features = Some(features);
CfgEval { cfg: &mut StripUnconfigured { sess, features, config_tokens: true, lint_node_id } }
.configure_annotatable(annotatable)
// Since the item itself has already been configured by the `InvocationCollector`,

View file

@ -5,6 +5,7 @@
use rustc_ast_pretty::pprust;
use rustc_expand::base::{parse_macro_name_and_helper_attrs, ExtCtxt, ResolverExpand};
use rustc_expand::expand::{AstFragment, ExpansionConfig};
use rustc_feature::Features;
use rustc_session::Session;
use rustc_span::hygiene::AstPass;
use rustc_span::source_map::SourceMap;
@ -46,13 +47,14 @@ struct CollectProcMacros<'a> {
pub fn inject(
krate: &mut ast::Crate,
sess: &Session,
features: &Features,
resolver: &mut dyn ResolverExpand,
is_proc_macro_crate: bool,
has_proc_macro_decls: bool,
is_test_crate: bool,
handler: &rustc_errors::Handler,
) {
let ecfg = ExpansionConfig::default("proc_macro".to_string());
let ecfg = ExpansionConfig::default("proc_macro".to_string(), features);
let mut cx = ExtCtxt::new(sess, ecfg, resolver, None);
let mut collect = CollectProcMacros {

View file

@ -1,6 +1,7 @@
use rustc_ast::{self as ast, attr};
use rustc_expand::base::{ExtCtxt, ResolverExpand};
use rustc_expand::expand::ExpansionConfig;
use rustc_feature::Features;
use rustc_session::Session;
use rustc_span::edition::Edition::*;
use rustc_span::hygiene::AstPass;
@ -13,6 +14,7 @@ pub fn inject(
pre_configured_attrs: &[ast::Attribute],
resolver: &mut dyn ResolverExpand,
sess: &Session,
features: &Features,
) -> usize {
let orig_num_items = krate.items.len();
let edition = sess.parse_sess.edition;
@ -39,7 +41,7 @@ pub fn inject(
let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
let call_site = DUMMY_SP.with_call_site_ctxt(expn_id.to_expn_id());
let ecfg = ExpansionConfig::default("std_lib_injection".to_string());
let ecfg = ExpansionConfig::default("std_lib_injection".to_string(), features);
let cx = ExtCtxt::new(sess, ecfg, resolver, None);
// .rev() to preserve ordering above in combination with insert(0, ...)

View file

@ -41,7 +41,12 @@ struct TestCtxt<'a> {
/// Traverse the crate, collecting all the test functions, eliding any
/// existing main functions, and synthesizing a main test harness
pub fn inject(krate: &mut ast::Crate, sess: &Session, resolver: &mut dyn ResolverExpand) {
pub fn inject(
krate: &mut ast::Crate,
sess: &Session,
features: &Features,
resolver: &mut dyn ResolverExpand,
) {
let span_diagnostic = sess.diagnostic();
let panic_strategy = sess.panic_strategy();
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
resolver,
reexport_test_harness_main,
krate,
&sess.features_untracked(),
features,
panic_strategy,
test_runner,
)
@ -243,9 +248,7 @@ fn generate_test_harness(
panic_strategy: PanicStrategy,
test_runner: Option<ast::Path>,
) {
let mut econfig = ExpansionConfig::default("test".to_string());
econfig.features = Some(features);
let econfig = ExpansionConfig::default("test".to_string(), features);
let ext_cx = ExtCtxt::new(sess, econfig, resolver, None);
let expn_id = ext_cx.resolver.expansion_for_ast_pass(

View file

@ -18,6 +18,7 @@
Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic,
MultiSpan, PResult,
};
use rustc_feature::Features;
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, RegisteredTools};
use rustc_parse::{self, parser, MACRO_ARGUMENTS};
@ -767,6 +768,7 @@ pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
/// and other properties converted from attributes.
pub fn new(
sess: &Session,
features: &Features,
kind: SyntaxExtensionKind,
span: Span,
helper_attrs: Vec<Symbol>,
@ -816,7 +818,7 @@ pub fn new(
allow_internal_unstable: (!allow_internal_unstable.is_empty())
.then(|| allow_internal_unstable.into()),
stability: stability.map(|(s, _)| s),
deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d),
deprecation: attr::find_deprecation(&sess, features, attrs).map(|(d, _)| d),
helper_attrs,
edition,
builtin_name,
@ -957,6 +959,7 @@ pub trait LintStoreExpand {
fn pre_expansion_lint(
&self,
sess: &Session,
features: &Features,
registered_tools: &RegisteredTools,
node_id: NodeId,
attrs: &[Attribute],

View file

@ -796,7 +796,7 @@ fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
| Annotatable::FieldDef(..)
| Annotatable::Variant(..) => panic!("unexpected annotatable"),
};
if self.cx.ecfg.proc_macro_hygiene() {
if self.cx.ecfg.features.proc_macro_hygiene {
return;
}
feature_err(
@ -834,7 +834,7 @@ fn visit_item(&mut self, item: &'ast ast::Item) {
}
}
if !self.cx.ecfg.proc_macro_hygiene() {
if !self.cx.ecfg.features.proc_macro_hygiene {
annotatable
.visit_with(&mut GateProcMacroInput { parse_sess: &self.cx.sess.parse_sess });
}
@ -1122,6 +1122,7 @@ fn wrap_flat_map_node_noop_flat_map(
if let Some(lint_store) = ecx.lint_store {
lint_store.pre_expansion_lint(
ecx.sess,
ecx.ecfg.features,
ecx.resolver.registered_tools(),
ecx.current_expansion.lint_node_id,
&attrs,
@ -1580,7 +1581,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
fn cfg(&self) -> StripUnconfigured<'_> {
StripUnconfigured {
sess: &self.cx.sess,
features: self.cx.ecfg.features,
features: Some(self.cx.ecfg.features),
config_tokens: false,
lint_node_id: self.cx.current_expansion.lint_node_id,
}
@ -1676,7 +1677,7 @@ fn take_first_attr(
// Detect use of feature-gated or invalid attributes on macro invocations
// since they will not be detected after macro expansion.
fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
let features = self.cx.ecfg.features.unwrap();
let features = self.cx.ecfg.features;
let mut attrs = attrs.iter().peekable();
let mut span: Option<Span> = None;
while let Some(attr) = attrs.next() {
@ -1976,7 +1977,7 @@ fn visit_id(&mut self, id: &mut NodeId) {
pub struct ExpansionConfig<'feat> {
pub crate_name: String,
pub features: Option<&'feat Features>,
pub features: &'feat Features,
pub recursion_limit: Limit,
pub trace_mac: bool,
/// If false, strip `#[test]` nodes
@ -1987,11 +1988,11 @@ pub struct ExpansionConfig<'feat> {
pub proc_macro_backtrace: bool,
}
impl<'feat> ExpansionConfig<'feat> {
pub fn default(crate_name: String) -> ExpansionConfig<'static> {
impl ExpansionConfig<'_> {
pub fn default(crate_name: String, features: &Features) -> ExpansionConfig<'_> {
ExpansionConfig {
crate_name,
features: None,
features,
recursion_limit: Limit::new(1024),
trace_mac: false,
should_test: false,
@ -1999,8 +2000,4 @@ pub fn default(crate_name: String) -> ExpansionConfig<'static> {
proc_macro_backtrace: false,
}
}
fn proc_macro_hygiene(&self) -> bool {
self.features.is_some_and(|features| features.proc_macro_hygiene)
}
}

View file

@ -16,6 +16,7 @@
use rustc_attr::{self as attr, TransparencyError};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_errors::{Applicability, ErrorGuaranteed};
use rustc_feature::Features;
use rustc_lint_defs::builtin::{
RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
};
@ -375,6 +376,7 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>(
/// Converts a macro item into a syntax extension.
pub fn compile_declarative_macro(
sess: &Session,
features: &Features,
def: &ast::Item,
edition: Edition,
) -> (SyntaxExtension, Vec<(usize, Span)>) {
@ -382,6 +384,7 @@ pub fn compile_declarative_macro(
let mk_syn_ext = |expander| {
SyntaxExtension::new(
sess,
features,
SyntaxExtensionKind::LegacyBang(expander),
def.span,
Vec::new(),
@ -503,7 +506,7 @@ pub fn compile_declarative_macro(
true,
&sess.parse_sess,
def.id,
sess.features_untracked(),
features,
edition,
)
.pop()
@ -527,7 +530,7 @@ pub fn compile_declarative_macro(
false,
&sess.parse_sess,
def.id,
sess.features_untracked(),
features,
edition,
)
.pop()

View file

@ -15,6 +15,7 @@ rustc_attr = { path = "../rustc_attr" }
rustc_borrowck = { path = "../rustc_borrowck" }
rustc_builtin_macros = { path = "../rustc_builtin_macros" }
rustc_expand = { path = "../rustc_expand" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_fs_util = { path = "../rustc_fs_util" }
rustc_macros = { path = "../rustc_macros" }

View file

@ -11,6 +11,7 @@
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
use rustc_errors::PResult;
use rustc_expand::base::{ExtCtxt, LintStoreExpand};
use rustc_feature::Features;
use rustc_fs_util::try_canonicalize;
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore};
@ -98,6 +99,7 @@ pub(crate) fn create_lint_store(
fn pre_expansion_lint<'a>(
sess: &Session,
features: &Features,
lint_store: &LintStore,
registered_tools: &RegisteredTools,
check_node: impl EarlyCheckNode<'a>,
@ -107,6 +109,7 @@ fn pre_expansion_lint<'a>(
|| {
rustc_lint::check_ast_node(
sess,
features,
true,
lint_store,
registered_tools,
@ -125,13 +128,14 @@ impl LintStoreExpand for LintStoreExpandImpl<'_> {
fn pre_expansion_lint(
&self,
sess: &Session,
features: &Features,
registered_tools: &RegisteredTools,
node_id: ast::NodeId,
attrs: &[ast::Attribute],
items: &[rustc_ast::ptr::P<ast::Item>],
name: Symbol,
) {
pre_expansion_lint(sess, self.0, registered_tools, (node_id, attrs, items), name);
pre_expansion_lint(sess, features, self.0, registered_tools, (node_id, attrs, items), name);
}
}
@ -147,10 +151,18 @@ fn configure_and_expand(
) -> ast::Crate {
let tcx = resolver.tcx();
let sess = tcx.sess;
let features = tcx.features();
let lint_store = unerased_lint_store(tcx);
let crate_name = tcx.crate_name(LOCAL_CRATE);
let lint_check_node = (&krate, pre_configured_attrs);
pre_expansion_lint(sess, lint_store, tcx.registered_tools(()), lint_check_node, crate_name);
pre_expansion_lint(
sess,
features,
lint_store,
tcx.registered_tools(()),
lint_check_node,
crate_name,
);
rustc_builtin_macros::register_builtin_macros(resolver);
let num_standard_library_imports = sess.time("crate_injection", || {
@ -159,6 +171,7 @@ fn configure_and_expand(
pre_configured_attrs,
resolver,
sess,
features,
)
});
@ -198,16 +211,15 @@ fn configure_and_expand(
}
// Create the config for macro expansion
let features = sess.features_untracked();
let recursion_limit = get_recursion_limit(pre_configured_attrs, sess);
let cfg = rustc_expand::expand::ExpansionConfig {
features: Some(features),
crate_name: crate_name.to_string(),
features,
recursion_limit,
trace_mac: sess.opts.unstable_opts.trace_macros,
should_test: sess.is_test_crate(),
span_debug: sess.opts.unstable_opts.span_debug,
proc_macro_backtrace: sess.opts.unstable_opts.proc_macro_backtrace,
..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
};
let lint_store = LintStoreExpandImpl(lint_store);
@ -241,11 +253,16 @@ fn configure_and_expand(
});
sess.time("maybe_building_test_harness", || {
rustc_builtin_macros::test_harness::inject(&mut krate, sess, resolver)
rustc_builtin_macros::test_harness::inject(&mut krate, sess, features, resolver)
});
let has_proc_macro_decls = sess.time("AST_validation", || {
rustc_ast_passes::ast_validation::check_crate(sess, &krate, resolver.lint_buffer())
rustc_ast_passes::ast_validation::check_crate(
sess,
features,
&krate,
resolver.lint_buffer(),
)
});
let crate_types = tcx.crate_types();
@ -270,6 +287,7 @@ fn configure_and_expand(
rustc_builtin_macros::proc_macro_harness::inject(
&mut krate,
sess,
features,
resolver,
is_proc_macro_crate,
has_proc_macro_decls,
@ -300,7 +318,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
// Needs to go *after* expansion to be able to check the results of macro expansion.
sess.time("complete_gated_feature_checking", || {
rustc_ast_passes::feature_gate::check_crate(&krate, sess);
rustc_ast_passes::feature_gate::check_crate(&krate, sess, tcx.features());
});
// Add all buffered lints from the `ParseSess` to the `Session`.
@ -329,6 +347,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
let lint_store = unerased_lint_store(tcx);
rustc_lint::check_ast_node(
sess,
tcx.features(),
false,
lint_store,
tcx.registered_tools(()),

View file

@ -234,9 +234,6 @@ pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>
debug_assert_eq!(_id, CRATE_DEF_ID);
let untracked = Untracked { cstore, source_span, definitions };
// FIXME: Move features from session to tcx and make them immutable.
sess.init_features(rustc_expand::config::features(sess, &pre_configured_attrs));
let qcx = passes::create_global_ctxt(
self.compiler,
crate_types,
@ -254,11 +251,13 @@ pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>
feed.crate_name(crate_name);
let feed = tcx.feed_unit_query();
feed.features_query(
tcx.arena.alloc(rustc_expand::config::features(sess, &pre_configured_attrs)),
);
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
feed.metadata_loader(
tcx.arena.alloc(Steal::new(self.codegen_backend().metadata_loader())),
);
feed.features_query(tcx.sess.features_untracked());
});
Ok(qcx)
})

View file

@ -2237,7 +2237,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
impl EarlyLintPass for IncompleteInternalFeatures {
fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
let features = cx.sess().features_untracked();
let features = cx.builder.features();
features
.declared_lang_features
.iter()

View file

@ -27,6 +27,7 @@
use rustc_data_structures::sync;
use rustc_errors::{add_elided_lifetime_in_path_suggestion, DiagnosticBuilder, DiagnosticMessage};
use rustc_errors::{Applicability, DecorateLint, MultiSpan, SuggestionStyle};
use rustc_feature::Features;
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def_id::{CrateNum, DefId};
@ -1071,6 +1072,7 @@ fn fulfill_expectation(&self, expectation: LintExpectationId) {
impl<'a> EarlyContext<'a> {
pub(crate) fn new(
sess: &'a Session,
features: &'a Features,
warn_about_weird_lints: bool,
lint_store: &'a LintStore,
registered_tools: &'a RegisteredTools,
@ -1079,6 +1081,7 @@ pub(crate) fn new(
EarlyContext {
builder: LintLevelsBuilder::new(
sess,
features,
warn_about_weird_lints,
lint_store,
registered_tools,

View file

@ -20,6 +20,7 @@
use rustc_ast::visit::{self as ast_visit, Visitor};
use rustc_ast::{self as ast, walk_list, HasAttrs};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_feature::Features;
use rustc_middle::ty::RegisteredTools;
use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
use rustc_session::Session;
@ -381,6 +382,7 @@ fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>)
pub fn check_ast_node<'a>(
sess: &Session,
features: &Features,
pre_expansion: bool,
lint_store: &LintStore,
registered_tools: &RegisteredTools,
@ -390,6 +392,7 @@ pub fn check_ast_node<'a>(
) {
let context = EarlyContext::new(
sess,
features,
!pre_expansion,
lint_store,
registered_tools,

View file

@ -12,6 +12,7 @@
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan};
use rustc_feature::Features;
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::HirId;
@ -119,6 +120,7 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
let mut builder = LintLevelsBuilder {
sess: tcx.sess,
features: tcx.features(),
provider: QueryMapExpectationsWrapper {
tcx,
cur: hir::CRATE_HIR_ID,
@ -148,6 +150,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
let mut levels = LintLevelsBuilder {
sess: tcx.sess,
features: tcx.features(),
provider: LintLevelQueryMap {
tcx,
cur: owner.into(),
@ -435,6 +438,7 @@ fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
pub struct LintLevelsBuilder<'s, P> {
sess: &'s Session,
features: &'s Features,
provider: P,
warn_about_weird_lints: bool,
store: &'s LintStore,
@ -448,12 +452,14 @@ pub(crate) struct BuilderPush {
impl<'s> LintLevelsBuilder<'s, TopDown> {
pub(crate) fn new(
sess: &'s Session,
features: &'s Features,
warn_about_weird_lints: bool,
store: &'s LintStore,
registered_tools: &'s RegisteredTools,
) -> Self {
let mut builder = LintLevelsBuilder {
sess,
features,
provider: TopDown { sets: LintLevelSets::new(), cur: COMMAND_LINE },
warn_about_weird_lints,
store,
@ -526,6 +532,10 @@ pub(crate) fn sess(&self) -> &Session {
self.sess
}
pub(crate) fn features(&self) -> &Features {
self.features
}
pub(crate) fn lint_store(&self) -> &LintStore {
self.store
}
@ -716,7 +726,7 @@ fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id:
ast::MetaItemKind::NameValue(ref name_value) => {
if item.path == sym::reason {
if let ast::LitKind::Str(rationale, _) = name_value.kind {
if !self.sess.features_untracked().lint_reasons {
if !self.features.lint_reasons {
feature_err(
&self.sess.parse_sess,
sym::lint_reasons,
@ -992,7 +1002,7 @@ fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id:
#[track_caller]
fn check_gated_lint(&self, lint_id: LintId, span: Span) -> bool {
if let Some(feature) = lint_id.lint.feature_gate {
if !self.sess.features_untracked().enabled(feature) {
if !self.features.enabled(feature) {
let lint = builtin::UNKNOWN_LINTS;
let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS);
struct_lint_level(

View file

@ -842,7 +842,7 @@ fn get_span(self, index: DefIndex, sess: &Session) -> Span {
.decode((self, sess))
}
fn load_proc_macro(self, id: DefIndex, sess: &Session) -> SyntaxExtension {
fn load_proc_macro(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> SyntaxExtension {
let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
ProcMacro::CustomDerive { trait_name, attributes, client } => {
let helper_attrs =
@ -861,9 +861,11 @@ fn load_proc_macro(self, id: DefIndex, sess: &Session) -> SyntaxExtension {
}
};
let sess = tcx.sess;
let attrs: Vec<_> = self.get_item_attrs(id, sess).collect();
SyntaxExtension::new(
sess,
tcx.features(),
kind,
self.get_span(id, sess),
helper_attrs,

View file

@ -6,6 +6,7 @@
use rustc_ast as ast;
use rustc_attr::Deprecation;
use rustc_data_structures::sync::Lrc;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
@ -23,7 +24,6 @@
use rustc_span::symbol::{kw, Symbol};
use rustc_span::Span;
use rustc_data_structures::sync::Lrc;
use std::any::Any;
use super::{Decodable, DecodeContext, DecodeIterator};
@ -522,12 +522,13 @@ pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> {
self.get_crate_data(def.krate).get_ctor(def.index)
}
pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
pub fn load_macro_untracked(&self, id: DefId, tcx: TyCtxt<'_>) -> LoadedMacro {
let sess = tcx.sess;
let _prof_timer = sess.prof.generic_activity("metadata_load_macro");
let data = self.get_crate_data(id.krate);
if data.root.is_proc_macro_crate() {
return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess));
return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, tcx));
}
let span = data.get_span(id.index, sess);

View file

@ -131,6 +131,7 @@ macro_rules! arena_types {
[] closure_kind_origin: (rustc_span::Span, rustc_middle::hir::place::Place<'tcx>),
[] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem,
[] mod_child: rustc_middle::metadata::ModChild,
[] features: rustc_feature::Features,
]);
)
}

View file

@ -115,7 +115,7 @@ fn annotate<F>(
let attrs = self.tcx.hir().attrs(self.tcx.hir().local_def_id_to_hir_id(def_id));
debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs);
let depr = attr::find_deprecation(&self.tcx.sess, attrs);
let depr = attr::find_deprecation(self.tcx.sess, self.tcx.features(), attrs);
let mut is_deprecated = false;
if let Some((depr, span)) = &depr {
is_deprecated = true;

View file

@ -171,7 +171,7 @@ pub(crate) fn get_macro_by_def_id(&mut self, def_id: DefId) -> MacroData {
return macro_data.clone();
}
let load_macro_untracked = self.cstore().load_macro_untracked(def_id, &self.tcx.sess);
let load_macro_untracked = self.cstore().load_macro_untracked(def_id, self.tcx);
let (ext, macro_rules) = match load_macro_untracked {
LoadedMacro::MacroDef(item, edition) => (
Lrc::new(self.compile_macro(&item, edition).0),

View file

@ -1282,7 +1282,7 @@ pub fn new(
let registered_tools = tcx.registered_tools(());
let features = tcx.sess.features_untracked();
let features = tcx.features();
let mut resolver = Resolver {
tcx,

View file

@ -920,7 +920,8 @@ pub(crate) fn compile_macro(
item: &ast::Item,
edition: Edition,
) -> (SyntaxExtension, Vec<(usize, Span)>) {
let (mut result, mut rule_spans) = compile_declarative_macro(self.tcx.sess, item, edition);
let (mut result, mut rule_spans) =
compile_declarative_macro(self.tcx.sess, self.tcx.features(), item, edition);
if let Some(builtin_name) = result.builtin_name {
// The macro was marked with `#[rustc_builtin_macro]`.

View file

@ -17,7 +17,7 @@
use rustc_data_structures::jobserver::{self, Client};
use rustc_data_structures::profiling::{duration_to_secs_str, SelfProfiler, SelfProfilerRef};
use rustc_data_structures::sync::{
self, AtomicU64, AtomicUsize, Lock, Lrc, OnceCell, OneThread, Ordering, Ordering::SeqCst,
self, AtomicU64, AtomicUsize, Lock, Lrc, OneThread, Ordering, Ordering::SeqCst,
};
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter;
use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
@ -152,8 +152,6 @@ pub struct Session {
/// Input, input file path and output file path to this compilation process.
pub io: CompilerIO,
features: OnceCell<rustc_feature::Features>,
incr_comp_session: OneThread<RefCell<IncrCompSession>>,
/// Used for incremental compilation tests. Will only be populated if
/// `-Zquery-dep-graph` is specified.
@ -705,21 +703,6 @@ pub fn instrument_coverage_except_unused_functions(&self) -> bool {
self.opts.cg.instrument_coverage() == InstrumentCoverage::ExceptUnusedFunctions
}
/// Gets the features enabled for the current compilation session.
/// DO NOT USE THIS METHOD if there is a TyCtxt available, as it circumvents
/// dependency tracking. Use tcx.features() instead.
#[inline]
pub fn features_untracked(&self) -> &rustc_feature::Features {
self.features.get().unwrap()
}
pub fn init_features(&self, features: rustc_feature::Features) {
match self.features.set(features) {
Ok(()) => {}
Err(_) => panic!("`features` was initialized twice"),
}
}
pub fn is_sanitizer_cfi_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
}
@ -1464,7 +1447,6 @@ pub fn build_session(
parse_sess,
sysroot,
io,
features: OnceCell::new(),
incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
cgu_reuse_tracker,
prof,

View file

@ -200,7 +200,7 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT
let fqn = if let ItemType::Macro = kind {
// Check to see if it is a macro 2.0 or built-in macro
if matches!(
CStore::from_tcx(cx.tcx).load_macro_untracked(did, cx.sess()),
CStore::from_tcx(cx.tcx).load_macro_untracked(did, cx.tcx),
LoadedMacro::MacroDef(def, _)
if matches!(&def.kind, ast::ItemKind::MacroDef(ast_def)
if !ast_def.macro_rules)
@ -680,7 +680,7 @@ fn build_macro(
import_def_id: Option<DefId>,
macro_kind: MacroKind,
) -> clean::ItemKind {
match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) {
match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.tcx) {
LoadedMacro::MacroDef(item_def, _) => match macro_kind {
MacroKind::Bang => {
if let ast::ItemKind::MacroDef(ref def) = item_def.kind {

View file

@ -604,7 +604,7 @@ fn generate_macro_def_id_path(
}
// Check to see if it is a macro 2.0 or built-in macro.
// More information in <https://rust-lang.github.io/rfcs/1584-macros.html>.
let is_macro_2 = match cstore.load_macro_untracked(def_id, tcx.sess) {
let is_macro_2 = match cstore.load_macro_untracked(def_id, tcx) {
LoadedMacro::MacroDef(def, _) => {
// If `ast_def.macro_rules` is `true`, then it's not a macro 2.0.
matches!(&def.kind, ast::ItemKind::MacroDef(ast_def) if !ast_def.macro_rules)