rustc: Move features
from Session
to GlobalCtxt
Removes two pieces of mutable state. Follow up to #114622.
This commit is contained in:
parent
a07bc13e14
commit
7353c96be8
30 changed files with 130 additions and 93 deletions
|
@ -3805,6 +3805,7 @@ dependencies = [
|
|||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_expand",
|
||||
"rustc_feature",
|
||||
"rustc_fluent_macro",
|
||||
"rustc_fs_util",
|
||||
"rustc_hir",
|
||||
|
|
|
@ -13,6 +13,7 @@ use rustc_ast::*;
|
|||
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 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
}
|
||||
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,
|
||||
|
|
|
@ -514,10 +514,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
|
|||
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()
|
||||
|
|
|
@ -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 @@ where
|
|||
}
|
||||
}
|
||||
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 @@ where
|
|||
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"]
|
||||
|
|
|
@ -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: ..."
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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`,
|
||||
|
|
|
@ -5,6 +5,7 @@ use rustc_ast::{self as ast, attr, NodeId};
|
|||
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 {
|
||||
|
|
|
@ -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, ...)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -18,6 +18,7 @@ use rustc_errors::{
|
|||
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 @@ impl 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 @@ impl SyntaxExtension {
|
|||
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],
|
||||
|
|
|
@ -796,7 +796,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
| 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 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ impl InvocationCollectorNode for P<ast::Item> {
|
|||
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 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
// 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 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
|||
|
||||
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 @@ impl<'feat> ExpansionConfig<'feat> {
|
|||
proc_macro_backtrace: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn proc_macro_hygiene(&self) -> bool {
|
||||
self.features.is_some_and(|features| features.proc_macro_hygiene)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use rustc_ast_pretty::pprust;
|
|||
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()
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -11,6 +11,7 @@ use rustc_data_structures::steal::Steal;
|
|||
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(()),
|
||||
|
|
|
@ -234,9 +234,6 @@ impl<'tcx> Queries<'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 @@ impl<'tcx> Queries<'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)
|
||||
})
|
||||
|
|
|
@ -2237,7 +2237,7 @@ declare_lint_pass!(
|
|||
|
||||
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()
|
||||
|
|
|
@ -27,6 +27,7 @@ use rustc_data_structures::fx::FxHashMap;
|
|||
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 @@ pub trait LintContext: Sized {
|
|||
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 @@ impl<'a> EarlyContext<'a> {
|
|||
EarlyContext {
|
||||
builder: LintLevelsBuilder::new(
|
||||
sess,
|
||||
features,
|
||||
warn_about_weird_lints,
|
||||
lint_store,
|
||||
registered_tools,
|
||||
|
|
|
@ -20,6 +20,7 @@ use rustc_ast::ptr::P;
|
|||
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 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::
|
|||
|
||||
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,
|
||||
|
|
|
@ -12,6 +12,7 @@ use rustc_ast as ast;
|
|||
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 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'
|
|||
|
||||
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 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||
self.sess
|
||||
}
|
||||
|
||||
pub(crate) fn features(&self) -> &Features {
|
||||
self.features
|
||||
}
|
||||
|
||||
pub(crate) fn lint_store(&self) -> &LintStore {
|
||||
self.store
|
||||
}
|
||||
|
@ -716,7 +726,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||
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 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||
#[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(
|
||||
|
|
|
@ -842,7 +842,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||
.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 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
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,
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::rmeta::AttrFlags;
|
|||
|
||||
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::hygiene::{ExpnHash, ExpnId};
|
|||
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 @@ impl CStore {
|
|||
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);
|
||||
|
|
|
@ -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,
|
||||
]);
|
||||
)
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
|||
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;
|
||||
|
|
|
@ -171,7 +171,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
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),
|
||||
|
|
|
@ -1282,7 +1282,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
|
||||
let registered_tools = tcx.registered_tools(());
|
||||
|
||||
let features = tcx.sess.features_untracked();
|
||||
let features = tcx.features();
|
||||
|
||||
let mut resolver = Resolver {
|
||||
tcx,
|
||||
|
|
|
@ -920,7 +920,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
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]`.
|
||||
|
|
|
@ -17,7 +17,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
|||
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 @@ impl Session {
|
|||
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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue