Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turn feature-gate table into a query so it is covered by dependency tracking. #48208

Merged
merged 4 commits into from
Mar 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,9 @@ impl DepKind {
}

define_dep_nodes!( <'tcx>
// We use this for most things when incr. comp. is turned off.
[] Null,

// Represents the `Krate` as a whole (the `hir::Krate` value) (as
// distinct from the krate module). This is basically a hash of
// the entire krate, so if you read from `Krate` (e.g., by calling
Expand Down Expand Up @@ -605,8 +608,8 @@ define_dep_nodes!( <'tcx>
[input] MissingExternCrateItem(CrateNum),
[input] UsedCrateSource(CrateNum),
[input] PostorderCnums,
[input] HasCloneClosures(CrateNum),
[input] HasCopyClosures(CrateNum),
[] HasCloneClosures(CrateNum),
[] HasCopyClosures(CrateNum),

// This query is not expected to have inputs -- as a result, it's
// not a good candidate for "replay" because it's essentially a
Expand All @@ -630,8 +633,6 @@ define_dep_nodes!( <'tcx>
[] CompileCodegenUnit(InternedString),
[input] OutputFilenames,
[anon] NormalizeTy,
// We use this for most things when incr. comp. is turned off.
[] Null,

[] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },

Expand All @@ -642,6 +643,7 @@ define_dep_nodes!( <'tcx>

[] GetSymbolExportLevel(DefId),

[input] Features,
);

trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ impl<'a> LoweringContext<'a> {
{
assert!(!self.is_collecting_in_band_lifetimes);
assert!(self.lifetimes_to_define.is_empty());
self.is_collecting_in_band_lifetimes = self.sess.features.borrow().in_band_lifetimes;
self.is_collecting_in_band_lifetimes = self.sess.features_untracked().in_band_lifetimes;

assert!(self.in_band_ty_params.is_empty());

Expand Down Expand Up @@ -964,7 +964,7 @@ impl<'a> LoweringContext<'a> {
let span = t.span;
match itctx {
ImplTraitContext::Existential => {
let has_feature = self.sess.features.borrow().conservative_impl_trait;
let has_feature = self.sess.features_untracked().conservative_impl_trait;
if !t.span.allows_unstable() && !has_feature {
emit_feature_err(&self.sess.parse_sess, "conservative_impl_trait",
t.span, GateIssue::Language,
Expand All @@ -988,7 +988,7 @@ impl<'a> LoweringContext<'a> {
}, lifetimes)
},
ImplTraitContext::Universal(def_id) => {
let has_feature = self.sess.features.borrow().universal_impl_trait;
let has_feature = self.sess.features_untracked().universal_impl_trait;
if !t.span.allows_unstable() && !has_feature {
emit_feature_err(&self.sess.parse_sess, "universal_impl_trait",
t.span, GateIssue::Language,
Expand Down Expand Up @@ -3713,7 +3713,7 @@ impl<'a> LoweringContext<'a> {
}

fn maybe_lint_bare_trait(&self, span: Span, id: NodeId, is_global: bool) {
if self.sess.features.borrow().dyn_trait {
if self.sess.features_untracked().dyn_trait {
self.sess.buffer_lint_with_diagnostic(
builtin::BARE_TRAIT_OBJECT, id, span,
"trait objects without an explicit `dyn` are deprecated",
Expand Down
19 changes: 19 additions & 0 deletions src/librustc/ich/impls_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use std::hash as std_hash;
use std::mem;

use syntax::ast;
use syntax::feature_gate;
use syntax::parse::token;
use syntax::symbol::InternedString;
use syntax::tokenstream;
Expand Down Expand Up @@ -460,3 +461,21 @@ fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,

(pos.0 - filemap_start.0, width as u32)
}



impl<'gcx> HashStable<StableHashingContext<'gcx>> for feature_gate::Features {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
// Unfortunately we cannot exhaustively list fields here, since the
// struct is macro generated.
self.declared_stable_lang_features.hash_stable(hcx, hasher);
self.declared_lib_features.hash_stable(hcx, hasher);

self.walk_feature_fields(|feature_name, value| {
feature_name.hash_stable(hcx, hasher);
value.hash_stable(hcx, hasher);
});
}
}
4 changes: 2 additions & 2 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
) {
debug!("report_region_errors(): {} errors to start", errors.len());

if will_later_be_reported_by_nll && self.tcx.sess.nll() {
if will_later_be_reported_by_nll && self.tcx.nll() {
// With `#![feature(nll)]`, we want to present a nice user
// experience, so don't even mention the errors from the
// AST checker.
if self.tcx.sess.features.borrow().nll {
if self.tcx.features().nll {
return;
}

Expand Down
14 changes: 6 additions & 8 deletions src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
item_sp: Span, kind: AnnotationKind, visit_children: F)
where F: FnOnce(&mut Self)
{
if self.tcx.sess.features.borrow().staged_api {
if self.tcx.features().staged_api {
// This crate explicitly wants staged API.
debug!("annotate(id = {:?}, attrs = {:?})", id, attrs);
if let Some(..) = attr::find_deprecation(self.tcx.sess.diagnostic(), attrs, item_sp) {
Expand Down Expand Up @@ -398,7 +398,7 @@ impl<'a, 'tcx> Index<'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Index<'tcx> {
let is_staged_api =
tcx.sess.opts.debugging_opts.force_unstable_if_unmarked ||
tcx.sess.features.borrow().staged_api;
tcx.features().staged_api;
let mut staged_api = FxHashMap();
staged_api.insert(LOCAL_CRATE, is_staged_api);
let mut index = Index {
Expand All @@ -408,7 +408,7 @@ impl<'a, 'tcx> Index<'tcx> {
active_features: FxHashSet(),
};

let ref active_lib_features = tcx.sess.features.borrow().declared_lib_features;
let ref active_lib_features = tcx.features().declared_lib_features;

// Put the active features into a map for quick lookup
index.active_features = active_lib_features.iter().map(|&(ref s, _)| s.clone()).collect();
Expand Down Expand Up @@ -677,7 +677,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {

// There's no good place to insert stability check for non-Copy unions,
// so semi-randomly perform it here in stability.rs
hir::ItemUnion(..) if !self.tcx.sess.features.borrow().untagged_unions => {
hir::ItemUnion(..) if !self.tcx.features().untagged_unions => {
let def_id = self.tcx.hir.local_def_id(item.id);
let adt_def = self.tcx.adt_def(def_id);
let ty = self.tcx.type_of(def_id);
Expand Down Expand Up @@ -721,8 +721,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// were expected to be library features), and the list of features used from
/// libraries, identify activated features that don't exist and error about them.
pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let sess = &tcx.sess;

let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);

if tcx.stability().staged_api[&LOCAL_CRATE] {
Expand All @@ -736,12 +734,12 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
krate.visit_all_item_likes(&mut missing.as_deep_visitor());
}

let ref declared_lib_features = sess.features.borrow().declared_lib_features;
let ref declared_lib_features = tcx.features().declared_lib_features;
let mut remaining_lib_features: FxHashMap<Symbol, Span>
= declared_lib_features.clone().into_iter().collect();
remaining_lib_features.remove(&Symbol::intern("proc_macro"));

for &(ref stable_lang_feature, span) in &sess.features.borrow().declared_stable_lang_features {
for &(ref stable_lang_feature, span) in &tcx.features().declared_stable_lang_features {
let version = find_lang_feature_accepted_version(&stable_lang_feature.as_str())
.expect("unexpectedly couldn't find version feature was stabilized");
tcx.lint_node(lint::builtin::STABLE_FEATURES,
Expand Down
66 changes: 19 additions & 47 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use lint::builtin::BuiltinLintDiagnostics;
use middle::allocator::AllocatorKind;
use middle::dependency_format;
use session::search_paths::PathKind;
use session::config::{BorrowckMode, DebugInfoLevel, OutputType, Epoch};
use session::config::{DebugInfoLevel, OutputType, Epoch};
use ty::tls;
use util::nodemap::{FxHashMap, FxHashSet};
use util::common::{duration_to_secs_str, ErrorReported};
Expand Down Expand Up @@ -93,7 +93,8 @@ pub struct Session {
/// multiple crates with the same name to coexist. See the
/// trans::back::symbol_names module for more information.
pub crate_disambiguator: RefCell<Option<CrateDisambiguator>>,
pub features: RefCell<feature_gate::Features>,

features: RefCell<Option<feature_gate::Features>>,

/// The maximum recursion limit for potentially infinitely recursive
/// operations such as auto-dereference and monomorphization.
Expand Down Expand Up @@ -194,6 +195,7 @@ impl Session {
None => bug!("accessing disambiguator before initialization"),
}
}

pub fn struct_span_warn<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
msg: &str)
Expand Down Expand Up @@ -456,16 +458,22 @@ impl Session {
self.opts.debugging_opts.print_llvm_passes
}

/// If true, we should use NLL-style region checking instead of
/// lexical style.
pub fn nll(&self) -> bool {
self.features.borrow().nll || self.opts.debugging_opts.nll
/// Get 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) -> cell::Ref<feature_gate::Features> {
let features = self.features.borrow();

if features.is_none() {
bug!("Access to Session::features before it is initialized");
}

cell::Ref::map(features, |r| r.as_ref().unwrap())
}

/// If true, we should use the MIR-based borrowck (we may *also* use
/// the AST-based borrowck).
pub fn use_mir(&self) -> bool {
self.borrowck_mode().use_mir()
pub fn init_features(&self, features: feature_gate::Features) {
*(self.features.borrow_mut()) = Some(features);
}

/// If true, we should gather causal information during NLL
Expand All @@ -475,42 +483,6 @@ impl Session {
self.opts.debugging_opts.nll_dump_cause
}

/// If true, we should enable two-phase borrows checks. This is
/// done with either `-Ztwo-phase-borrows` or with
/// `#![feature(nll)]`.
pub fn two_phase_borrows(&self) -> bool {
self.features.borrow().nll || self.opts.debugging_opts.two_phase_borrows
}

/// What mode(s) of borrowck should we run? AST? MIR? both?
/// (Also considers the `#![feature(nll)]` setting.)
pub fn borrowck_mode(&self) -> BorrowckMode {
match self.opts.borrowck_mode {
mode @ BorrowckMode::Mir |
mode @ BorrowckMode::Compare => mode,

mode @ BorrowckMode::Ast => {
if self.nll() {
BorrowckMode::Mir
} else {
mode
}
}

}
}

/// Should we emit EndRegion MIR statements? These are consumed by
/// MIR borrowck, but not when NLL is used. They are also consumed
/// by the validation stuff.
pub fn emit_end_regions(&self) -> bool {
// FIXME(#46875) -- we should not emit end regions when NLL is enabled,
// but for now we can't stop doing so because it causes false positives
self.opts.debugging_opts.emit_end_regions ||
self.opts.debugging_opts.mir_emit_validate > 0 ||
self.use_mir()
}

/// Calculates the flavor of LTO to use for this compilation.
pub fn lto(&self) -> config::Lto {
// If our target has codegen requirements ignore the command line
Expand Down Expand Up @@ -1029,7 +1001,7 @@ pub fn build_session_(sopts: config::Options,
crate_types: RefCell::new(Vec::new()),
dependency_formats: RefCell::new(FxHashMap()),
crate_disambiguator: RefCell::new(None),
features: RefCell::new(feature_gate::Features::new()),
features: RefCell::new(None),
recursion_limit: Cell::new(64),
type_length_limit: Cell::new(1048576),
next_node_id: Cell::new(NodeId::new(1)),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ pub(super) fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

// The feature gate should prevent introducing new specializations, but not
// taking advantage of upstream ones.
if !tcx.sess.features.borrow().specialization &&
if !tcx.features().specialization &&
(impl1_def_id.is_local() || impl2_def_id.is_local()) {
return false;
}
Expand Down
Loading