rustc: Move stability functionality into queries
This commit primarily removes the `stability` field from `TyCtxt` as well as its internal mutable state, instead using a query to build the stability index as well as primarily using queries for other related lookups. Like previous commits the calculation of the stability index is wrapped in a `with_ignore` node to avoid regressing the current tests, and otherwise this commit also introduces #44232 but somewhat intentionally so.
This commit is contained in:
parent
0182c8bbda
commit
9a231961d5
12 changed files with 213 additions and 203 deletions
|
@ -511,8 +511,8 @@ define_dep_nodes!( <'tcx>
|
|||
[] ParamEnv(DefId),
|
||||
[] DescribeDef(DefId),
|
||||
[] DefSpan(DefId),
|
||||
[] Stability(DefId),
|
||||
[] Deprecation(DefId),
|
||||
[] LookupStability(DefId),
|
||||
[] LookupDeprecationEntry(DefId),
|
||||
[] ItemBodyNestedBodies(DefId),
|
||||
[] ConstIsRvaluePromotableToStatic(DefId),
|
||||
[] ImplParent(DefId),
|
||||
|
@ -573,6 +573,7 @@ define_dep_nodes!( <'tcx>
|
|||
[] Freevars(HirId),
|
||||
[] MaybeUnusedTraitImport(HirId),
|
||||
[] MaybeUnusedExternCrates,
|
||||
[] StabilityIndex,
|
||||
);
|
||||
|
||||
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
|
||||
|
|
|
@ -878,7 +878,17 @@ impl<'hir> Map<'hir> {
|
|||
|
||||
Some(RootCrate(_)) => self.forest.krate.span,
|
||||
Some(NotPresent) | None => {
|
||||
bug!("hir::map::Map::span: id not in map: {:?}", id)
|
||||
// Some nodes, notably macro definitions, are not
|
||||
// present in the map for whatever reason, but
|
||||
// they *do* have def-ids. So if we encounter an
|
||||
// empty hole, check for that case.
|
||||
if let Some(def_index) = self.definitions.opt_def_index(id) {
|
||||
let def_path_hash = self.definitions.def_path_hash(def_index);
|
||||
self.dep_graph.read(def_path_hash.to_dep_node(DepKind::Hir));
|
||||
DUMMY_SP
|
||||
} else {
|
||||
bug!("hir::map::Map::span: id not in map: {:?}", id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,20 +15,19 @@ pub use self::StabilityLevel::*;
|
|||
|
||||
use lint;
|
||||
use hir::def::Def;
|
||||
use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, DefIndex, LOCAL_CRATE};
|
||||
use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
|
||||
use ty::{self, TyCtxt};
|
||||
use middle::privacy::AccessLevels;
|
||||
use session::Session;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use syntax::ast;
|
||||
use syntax::ast::{NodeId, Attribute};
|
||||
use syntax::feature_gate::{GateIssue, emit_feature_err, find_lang_feature_accepted_version};
|
||||
use syntax::attr::{self, Stability, Deprecation};
|
||||
use util::nodemap::{DefIdMap, FxHashSet, FxHashMap};
|
||||
use util::nodemap::{FxHashSet, FxHashMap};
|
||||
|
||||
use hir;
|
||||
use hir::{Item, Generics, StructField, Variant};
|
||||
use hir::{Item, Generics, StructField, Variant, HirId};
|
||||
use hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||
|
||||
use std::mem::replace;
|
||||
|
@ -63,19 +62,18 @@ pub struct DeprecationEntry {
|
|||
pub attr: Deprecation,
|
||||
/// The def id where the attr was originally attached. `None` for non-local
|
||||
/// `DefId`'s.
|
||||
origin: Option<DefIndex>,
|
||||
origin: Option<HirId>,
|
||||
}
|
||||
|
||||
impl DeprecationEntry {
|
||||
fn local(attr: Deprecation, id: DefId) -> DeprecationEntry {
|
||||
assert!(id.is_local());
|
||||
fn local(attr: Deprecation, id: HirId) -> DeprecationEntry {
|
||||
DeprecationEntry {
|
||||
attr,
|
||||
origin: Some(id.index),
|
||||
origin: Some(id),
|
||||
}
|
||||
}
|
||||
|
||||
fn external(attr: Deprecation) -> DeprecationEntry {
|
||||
pub fn external(attr: Deprecation) -> DeprecationEntry {
|
||||
DeprecationEntry {
|
||||
attr,
|
||||
origin: None,
|
||||
|
@ -94,17 +92,14 @@ impl DeprecationEntry {
|
|||
pub struct Index<'tcx> {
|
||||
/// This is mostly a cache, except the stabilities of local items
|
||||
/// are filled by the annotator.
|
||||
stab_map: DefIdMap<Option<&'tcx Stability>>,
|
||||
depr_map: DefIdMap<Option<DeprecationEntry>>,
|
||||
stab_map: FxHashMap<HirId, &'tcx Stability>,
|
||||
depr_map: FxHashMap<HirId, DeprecationEntry>,
|
||||
|
||||
/// Maps for each crate whether it is part of the staged API.
|
||||
staged_api: FxHashMap<CrateNum, bool>,
|
||||
|
||||
/// Features enabled for this crate.
|
||||
active_features: FxHashSet<Symbol>,
|
||||
|
||||
/// Features used by this crate. Updated before and during typeck.
|
||||
used_features: FxHashMap<Symbol, attr::StabilityLevel>
|
||||
}
|
||||
|
||||
// A private tree-walker for producing an Index.
|
||||
|
@ -178,8 +173,8 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let def_id = self.tcx.hir.local_def_id(id);
|
||||
self.index.stab_map.insert(def_id, Some(stab));
|
||||
let hir_id = self.tcx.hir.node_to_hir_id(id);
|
||||
self.index.stab_map.insert(hir_id, stab);
|
||||
|
||||
let orig_parent_stab = replace(&mut self.parent_stab, Some(stab));
|
||||
visit_children(self);
|
||||
|
@ -188,8 +183,8 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
|
|||
debug!("annotate: not found, parent = {:?}", self.parent_stab);
|
||||
if let Some(stab) = self.parent_stab {
|
||||
if stab.level.is_unstable() {
|
||||
let def_id = self.tcx.hir.local_def_id(id);
|
||||
self.index.stab_map.insert(def_id, Some(stab));
|
||||
let hir_id = self.tcx.hir.node_to_hir_id(id);
|
||||
self.index.stab_map.insert(hir_id, stab);
|
||||
}
|
||||
}
|
||||
visit_children(self);
|
||||
|
@ -209,8 +204,8 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
|
|||
// -Zforce-unstable-if-unmarked is set.
|
||||
if let Some(stab) = self.parent_stab {
|
||||
if stab.level.is_unstable() {
|
||||
let def_id = self.tcx.hir.local_def_id(id);
|
||||
self.index.stab_map.insert(def_id, Some(stab));
|
||||
let hir_id = self.tcx.hir.node_to_hir_id(id);
|
||||
self.index.stab_map.insert(hir_id, stab);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,16 +215,17 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// `Deprecation` is just two pointers, no need to intern it
|
||||
let def_id = self.tcx.hir.local_def_id(id);
|
||||
let depr_entry = Some(DeprecationEntry::local(depr, def_id));
|
||||
self.index.depr_map.insert(def_id, depr_entry.clone());
|
||||
let hir_id = self.tcx.hir.node_to_hir_id(id);
|
||||
let depr_entry = DeprecationEntry::local(depr, hir_id);
|
||||
self.index.depr_map.insert(hir_id, depr_entry.clone());
|
||||
|
||||
let orig_parent_depr = replace(&mut self.parent_depr, depr_entry);
|
||||
let orig_parent_depr = replace(&mut self.parent_depr,
|
||||
Some(depr_entry));
|
||||
visit_children(self);
|
||||
self.parent_depr = orig_parent_depr;
|
||||
} else if let parent_depr @ Some(_) = self.parent_depr.clone() {
|
||||
let def_id = self.tcx.hir.local_def_id(id);
|
||||
self.index.depr_map.insert(def_id, parent_depr);
|
||||
} else if let Some(parent_depr) = self.parent_depr.clone() {
|
||||
let hir_id = self.tcx.hir.node_to_hir_id(id);
|
||||
self.index.depr_map.insert(hir_id, parent_depr);
|
||||
visit_children(self);
|
||||
} else {
|
||||
visit_children(self);
|
||||
|
@ -322,10 +318,10 @@ struct MissingStabilityAnnotations<'a, 'tcx: 'a> {
|
|||
|
||||
impl<'a, 'tcx: 'a> MissingStabilityAnnotations<'a, 'tcx> {
|
||||
fn check_missing_stability(&self, id: NodeId, span: Span) {
|
||||
let def_id = self.tcx.hir.local_def_id(id);
|
||||
let stab = self.tcx.stability.borrow().stab_map.get(&def_id).cloned();
|
||||
let hir_id = self.tcx.hir.node_to_hir_id(id);
|
||||
let stab = self.tcx.stability().local_stability(hir_id);
|
||||
let is_error = !self.tcx.sess.opts.test &&
|
||||
(stab == None || stab == Some(None)) &&
|
||||
stab.is_none() &&
|
||||
self.access_levels.is_reachable(id);
|
||||
if is_error {
|
||||
self.tcx.sess.span_err(span, "This node does not have a stability attribute");
|
||||
|
@ -386,60 +382,70 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> Index<'tcx> {
|
||||
/// Construct the stability index for a crate being compiled.
|
||||
pub fn build(&mut self, tcx: TyCtxt<'a, 'tcx, '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;
|
||||
let mut staged_api = FxHashMap();
|
||||
staged_api.insert(LOCAL_CRATE, is_staged_api);
|
||||
let mut index = Index {
|
||||
staged_api,
|
||||
stab_map: FxHashMap(),
|
||||
depr_map: FxHashMap(),
|
||||
active_features: FxHashSet(),
|
||||
};
|
||||
|
||||
let ref active_lib_features = tcx.sess.features.borrow().declared_lib_features;
|
||||
|
||||
// Put the active features into a map for quick lookup
|
||||
self.active_features = active_lib_features.iter().map(|&(ref s, _)| s.clone()).collect();
|
||||
index.active_features = active_lib_features.iter().map(|&(ref s, _)| s.clone()).collect();
|
||||
|
||||
let krate = tcx.hir.krate();
|
||||
let mut annotator = Annotator {
|
||||
tcx,
|
||||
index: self,
|
||||
parent_stab: None,
|
||||
parent_depr: None,
|
||||
in_trait_impl: false,
|
||||
};
|
||||
{
|
||||
let krate = tcx.hir.krate();
|
||||
let mut annotator = Annotator {
|
||||
tcx,
|
||||
index: &mut index,
|
||||
parent_stab: None,
|
||||
parent_depr: None,
|
||||
in_trait_impl: false,
|
||||
};
|
||||
|
||||
// If the `-Z force-unstable-if-unmarked` flag is passed then we provide
|
||||
// a parent stability annotation which indicates that this is private
|
||||
// with the `rustc_private` feature. This is intended for use when
|
||||
// compiling librustc crates themselves so we can leverage crates.io
|
||||
// while maintaining the invariant that all sysroot crates are unstable
|
||||
// by default and are unable to be used.
|
||||
if tcx.sess.opts.debugging_opts.force_unstable_if_unmarked {
|
||||
let reason = "this crate is being loaded from the sysroot, and \
|
||||
unstable location; did you mean to load this crate \
|
||||
from crates.io via `Cargo.toml` instead?";
|
||||
let stability = tcx.intern_stability(Stability {
|
||||
level: attr::StabilityLevel::Unstable {
|
||||
reason: Some(Symbol::intern(reason)),
|
||||
issue: 27812,
|
||||
},
|
||||
feature: Symbol::intern("rustc_private"),
|
||||
rustc_depr: None,
|
||||
});
|
||||
annotator.parent_stab = Some(stability);
|
||||
// If the `-Z force-unstable-if-unmarked` flag is passed then we provide
|
||||
// a parent stability annotation which indicates that this is private
|
||||
// with the `rustc_private` feature. This is intended for use when
|
||||
// compiling librustc crates themselves so we can leverage crates.io
|
||||
// while maintaining the invariant that all sysroot crates are unstable
|
||||
// by default and are unable to be used.
|
||||
if tcx.sess.opts.debugging_opts.force_unstable_if_unmarked {
|
||||
let reason = "this crate is being loaded from the sysroot, and \
|
||||
unstable location; did you mean to load this crate \
|
||||
from crates.io via `Cargo.toml` instead?";
|
||||
let stability = tcx.intern_stability(Stability {
|
||||
level: attr::StabilityLevel::Unstable {
|
||||
reason: Some(Symbol::intern(reason)),
|
||||
issue: 27812,
|
||||
},
|
||||
feature: Symbol::intern("rustc_private"),
|
||||
rustc_depr: None,
|
||||
});
|
||||
annotator.parent_stab = Some(stability);
|
||||
}
|
||||
|
||||
annotator.annotate(ast::CRATE_NODE_ID,
|
||||
&krate.attrs,
|
||||
krate.span,
|
||||
AnnotationKind::Required,
|
||||
|v| intravisit::walk_crate(v, krate));
|
||||
}
|
||||
|
||||
annotator.annotate(ast::CRATE_NODE_ID, &krate.attrs, krate.span, AnnotationKind::Required,
|
||||
|v| intravisit::walk_crate(v, krate));
|
||||
return index
|
||||
}
|
||||
|
||||
pub fn new(sess: &Session) -> Index<'tcx> {
|
||||
let is_staged_api =
|
||||
sess.opts.debugging_opts.force_unstable_if_unmarked ||
|
||||
sess.features.borrow().staged_api;
|
||||
let mut staged_api = FxHashMap();
|
||||
staged_api.insert(LOCAL_CRATE, is_staged_api);
|
||||
Index {
|
||||
staged_api,
|
||||
stab_map: DefIdMap(),
|
||||
depr_map: DefIdMap(),
|
||||
active_features: FxHashSet(),
|
||||
used_features: FxHashMap(),
|
||||
}
|
||||
pub fn local_stability(&self, id: HirId) -> Option<&'tcx Stability> {
|
||||
self.stab_map.get(&id).cloned()
|
||||
}
|
||||
|
||||
pub fn local_deprecation_entry(&self, id: HirId) -> Option<DeprecationEntry> {
|
||||
self.depr_map.get(&id).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -547,10 +553,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
return
|
||||
}
|
||||
|
||||
if let Some(&Stability { ref level, ref feature, .. }) = stability {
|
||||
self.stability.borrow_mut().used_features.insert(feature.clone(), level.clone());
|
||||
}
|
||||
|
||||
// Issue 38412: private items lack stability markers.
|
||||
if self.skip_stability_check_due_to_privacy(def_id) {
|
||||
return
|
||||
|
@ -558,7 +560,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
match stability {
|
||||
Some(&Stability { level: attr::Unstable {ref reason, issue}, ref feature, .. }) => {
|
||||
if self.stability.borrow().active_features.contains(feature) {
|
||||
if self.stability().active_features.contains(feature) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -672,49 +674,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
/// Lookup the stability for a node, loading external crate
|
||||
/// metadata as necessary.
|
||||
pub fn lookup_stability(self, id: DefId) -> Option<&'gcx Stability> {
|
||||
if let Some(st) = self.stability.borrow().stab_map.get(&id) {
|
||||
return *st;
|
||||
}
|
||||
|
||||
let st = self.lookup_stability_uncached(id);
|
||||
self.stability.borrow_mut().stab_map.insert(id, st);
|
||||
st
|
||||
}
|
||||
|
||||
pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
|
||||
self.lookup_deprecation_entry(id).map(|depr| depr.attr)
|
||||
}
|
||||
|
||||
pub fn lookup_deprecation_entry(self, id: DefId) -> Option<DeprecationEntry> {
|
||||
if let Some(depr) = self.stability.borrow().depr_map.get(&id) {
|
||||
return depr.clone();
|
||||
}
|
||||
|
||||
let depr = self.lookup_deprecation_uncached(id);
|
||||
self.stability.borrow_mut().depr_map.insert(id, depr.clone());
|
||||
depr
|
||||
}
|
||||
|
||||
fn lookup_stability_uncached(self, id: DefId) -> Option<&'gcx Stability> {
|
||||
debug!("lookup(id={:?})", id);
|
||||
if id.is_local() {
|
||||
None // The stability cache is filled partially lazily
|
||||
} else {
|
||||
self.stability(id).map(|st| self.intern_stability(st))
|
||||
}
|
||||
}
|
||||
|
||||
fn lookup_deprecation_uncached(self, id: DefId) -> Option<DeprecationEntry> {
|
||||
debug!("lookup(id={:?})", id);
|
||||
if id.is_local() {
|
||||
None // The stability cache is filled partially lazily
|
||||
} else {
|
||||
self.deprecation(id).map(DeprecationEntry::external)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Given the list of enabled features that were not language features (i.e. that
|
||||
|
@ -725,7 +687,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
|
||||
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
|
||||
|
||||
if tcx.stability.borrow().staged_api[&LOCAL_CRATE] {
|
||||
if tcx.stability().staged_api[&LOCAL_CRATE] {
|
||||
let krate = tcx.hir.krate();
|
||||
let mut missing = MissingStabilityAnnotations {
|
||||
tcx,
|
||||
|
@ -741,10 +703,6 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
= declared_lib_features.clone().into_iter().collect();
|
||||
remaining_lib_features.remove(&Symbol::intern("proc_macro"));
|
||||
|
||||
fn format_stable_since_msg(version: &str) -> String {
|
||||
format!("this feature has been stable since {}. Attribute no longer needed", version)
|
||||
}
|
||||
|
||||
for &(ref stable_lang_feature, span) in &sess.features.borrow().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");
|
||||
|
@ -754,25 +712,23 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
&format_stable_since_msg(version));
|
||||
}
|
||||
|
||||
let index = tcx.stability.borrow();
|
||||
for (used_lib_feature, level) in &index.used_features {
|
||||
match remaining_lib_features.remove(used_lib_feature) {
|
||||
Some(span) => {
|
||||
if let &attr::StabilityLevel::Stable { since: ref version } = level {
|
||||
tcx.lint_node(lint::builtin::STABLE_FEATURES,
|
||||
ast::CRATE_NODE_ID,
|
||||
span,
|
||||
&format_stable_since_msg(&version.as_str()));
|
||||
}
|
||||
}
|
||||
None => ( /* used but undeclared, handled during the previous ast visit */ )
|
||||
}
|
||||
}
|
||||
|
||||
for &span in remaining_lib_features.values() {
|
||||
tcx.lint_node(lint::builtin::UNUSED_FEATURES,
|
||||
ast::CRATE_NODE_ID,
|
||||
span,
|
||||
"unused or unknown feature");
|
||||
}
|
||||
// FIXME(#44232) the `used_features` table no longer exists, so we don't
|
||||
// lint about unknown or unused features. We should reenable
|
||||
// this one day!
|
||||
//
|
||||
// let index = tcx.stability();
|
||||
// for (used_lib_feature, level) in &index.used_features {
|
||||
// remaining_lib_features.remove(used_lib_feature);
|
||||
// }
|
||||
//
|
||||
// for &span in remaining_lib_features.values() {
|
||||
// tcx.lint_node(lint::builtin::UNUSED_FEATURES,
|
||||
// ast::CRATE_NODE_ID,
|
||||
// span,
|
||||
// "unused or unknown feature");
|
||||
// }
|
||||
}
|
||||
|
||||
fn format_stable_since_msg(version: &str) -> String {
|
||||
format!("this feature has been stable since {}. Attribute no longer needed", version)
|
||||
}
|
||||
|
|
|
@ -855,9 +855,6 @@ pub struct GlobalCtxt<'tcx> {
|
|||
/// about.
|
||||
pub used_mut_nodes: RefCell<NodeSet>,
|
||||
|
||||
/// Maps any item's def-id to its stability index.
|
||||
pub stability: RefCell<stability::Index<'tcx>>,
|
||||
|
||||
/// Caches the results of trait selection. This cache is used
|
||||
/// for things that do not have to do with the parameters in scope.
|
||||
pub selection_cache: traits::SelectionCache<'tcx>,
|
||||
|
@ -989,7 +986,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
resolutions: ty::Resolutions,
|
||||
named_region_map: resolve_lifetime::NamedRegionMap,
|
||||
hir: hir_map::Map<'tcx>,
|
||||
stability: stability::Index<'tcx>,
|
||||
crate_name: &str,
|
||||
f: F) -> R
|
||||
where F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'tcx>) -> R
|
||||
|
@ -1086,7 +1082,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
normalized_cache: RefCell::new(FxHashMap()),
|
||||
inhabitedness_cache: RefCell::new(FxHashMap()),
|
||||
used_mut_nodes: RefCell::new(NodeSet()),
|
||||
stability: RefCell::new(stability),
|
||||
selection_cache: traits::SelectionCache::new(),
|
||||
evaluation_cache: traits::EvaluationCache::new(),
|
||||
rvalue_promotable_to_static: RefCell::new(NodeMap()),
|
||||
|
@ -1118,6 +1113,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
self.get_lang_items(LOCAL_CRATE)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn stability(self) -> Rc<stability::Index<'tcx>> {
|
||||
self.dep_graph.with_ignore(|| {
|
||||
self.stability_index(LOCAL_CRATE)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> {
|
||||
|
@ -2012,6 +2013,9 @@ struct NamedRegionMap {
|
|||
}
|
||||
|
||||
pub fn provide(providers: &mut ty::maps::Providers) {
|
||||
// FIXME(#44234) - almost all of these queries have no sub-queries and
|
||||
// therefore no actual inputs, they're just reading tables calculated in
|
||||
// resolve! Does this work? Unsure! That's what the issue is about
|
||||
providers.in_scope_traits = |tcx, id| tcx.gcx.trait_map.get(&id).cloned();
|
||||
providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).cloned();
|
||||
providers.named_region = |tcx, id| tcx.gcx.named_region_map.defs.get(&id).cloned();
|
||||
|
@ -2035,4 +2039,19 @@ pub fn provide(providers: &mut ty::maps::Providers) {
|
|||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
Rc::new(tcx.maybe_unused_extern_crates.clone())
|
||||
};
|
||||
|
||||
providers.stability_index = |tcx, cnum| {
|
||||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
Rc::new(stability::Index::new(tcx))
|
||||
};
|
||||
providers.lookup_stability = |tcx, id| {
|
||||
assert_eq!(id.krate, LOCAL_CRATE);
|
||||
let id = tcx.hir.definitions().def_index_to_hir_id(id.index);
|
||||
tcx.stability().local_stability(id)
|
||||
};
|
||||
providers.lookup_deprecation_entry = |tcx, id| {
|
||||
assert_eq!(id.krate, LOCAL_CRATE);
|
||||
let id = tcx.hir.definitions().def_index_to_hir_id(id.index);
|
||||
tcx.stability().local_deprecation_entry(id)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ use middle::privacy::AccessLevels;
|
|||
use middle::region;
|
||||
use middle::region::RegionMaps;
|
||||
use middle::resolve_lifetime::{Region, ObjectLifetimeDefault};
|
||||
use middle::stability::{self, DeprecationEntry};
|
||||
use middle::lang_items::{LanguageItems, LangItem};
|
||||
use mir;
|
||||
use mir::transform::{MirSuite, MirPassIndex};
|
||||
|
@ -434,13 +435,13 @@ impl<'tcx> QueryDescription for queries::def_span<'tcx> {
|
|||
}
|
||||
|
||||
|
||||
impl<'tcx> QueryDescription for queries::stability<'tcx> {
|
||||
impl<'tcx> QueryDescription for queries::lookup_stability<'tcx> {
|
||||
fn describe(_: TyCtxt, _: DefId) -> String {
|
||||
bug!("stability")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription for queries::deprecation<'tcx> {
|
||||
impl<'tcx> QueryDescription for queries::lookup_deprecation_entry<'tcx> {
|
||||
fn describe(_: TyCtxt, _: DefId) -> String {
|
||||
bug!("deprecation")
|
||||
}
|
||||
|
@ -748,6 +749,12 @@ impl<'tcx> QueryDescription for queries::maybe_unused_extern_crates<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription for queries::stability_index<'tcx> {
|
||||
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
|
||||
format!("calculating the stability index for the local crate")
|
||||
}
|
||||
}
|
||||
|
||||
// If enabled, send a message to the profile-queries thread
|
||||
macro_rules! profq_msg {
|
||||
($tcx:expr, $msg:expr) => {
|
||||
|
@ -1272,8 +1279,8 @@ define_maps! { <'tcx>
|
|||
|
||||
[] fn describe_def: DescribeDef(DefId) -> Option<Def>,
|
||||
[] fn def_span: DefSpan(DefId) -> Span,
|
||||
[] fn stability: Stability(DefId) -> Option<attr::Stability>,
|
||||
[] fn deprecation: Deprecation(DefId) -> Option<attr::Deprecation>,
|
||||
[] fn lookup_stability: LookupStability(DefId) -> Option<&'tcx attr::Stability>,
|
||||
[] fn lookup_deprecation_entry: LookupDeprecationEntry(DefId) -> Option<DeprecationEntry>,
|
||||
[] fn item_attrs: ItemAttrs(DefId) -> Rc<[ast::Attribute]>,
|
||||
[] fn fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
|
||||
[] fn impl_parent: ImplParent(DefId) -> Option<DefId>,
|
||||
|
@ -1337,37 +1344,39 @@ define_maps! { <'tcx>
|
|||
[] fn all_trait_implementations: AllTraitImplementations(CrateNum)
|
||||
-> Rc<Vec<DefId>>,
|
||||
|
||||
[] is_dllimport_foreign_item: IsDllimportForeignItem(DefId) -> bool,
|
||||
[] is_statically_included_foreign_item: IsStaticallyIncludedForeignItem(DefId) -> bool,
|
||||
[] native_library_kind: NativeLibraryKind(DefId)
|
||||
[] fn is_dllimport_foreign_item: IsDllimportForeignItem(DefId) -> bool,
|
||||
[] fn is_statically_included_foreign_item: IsStaticallyIncludedForeignItem(DefId) -> bool,
|
||||
[] fn native_library_kind: NativeLibraryKind(DefId)
|
||||
-> Option<NativeLibraryKind>,
|
||||
[] link_args: link_args_node(CrateNum) -> Rc<Vec<String>>,
|
||||
[] fn link_args: link_args_node(CrateNum) -> Rc<Vec<String>>,
|
||||
|
||||
[] named_region: NamedRegion(HirId) -> Option<Region>,
|
||||
[] is_late_bound: IsLateBound(HirId) -> bool,
|
||||
[] object_lifetime_defaults: ObjectLifetimeDefaults(HirId)
|
||||
[] fn named_region: NamedRegion(HirId) -> Option<Region>,
|
||||
[] fn is_late_bound: IsLateBound(HirId) -> bool,
|
||||
[] fn object_lifetime_defaults: ObjectLifetimeDefaults(HirId)
|
||||
-> Option<Rc<Vec<ObjectLifetimeDefault>>>,
|
||||
|
||||
[] visibility: Visibility(DefId) -> ty::Visibility,
|
||||
[] dep_kind: DepKind(CrateNum) -> DepKind,
|
||||
[] crate_name: CrateName(CrateNum) -> Symbol,
|
||||
[] item_children: ItemChildren(DefId) -> Rc<Vec<Export>>,
|
||||
[] extern_mod_stmt_cnum: ExternModStmtCnum(HirId) -> Option<CrateNum>,
|
||||
[] fn visibility: Visibility(DefId) -> ty::Visibility,
|
||||
[] fn dep_kind: DepKind(CrateNum) -> DepKind,
|
||||
[] fn crate_name: CrateName(CrateNum) -> Symbol,
|
||||
[] fn item_children: ItemChildren(DefId) -> Rc<Vec<Export>>,
|
||||
[] fn extern_mod_stmt_cnum: ExternModStmtCnum(HirId) -> Option<CrateNum>,
|
||||
|
||||
[] get_lang_items: get_lang_items_node(CrateNum) -> Rc<LanguageItems>,
|
||||
[] defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefIndex, usize)>>,
|
||||
[] missing_lang_items: MissingLangItems(CrateNum) -> Rc<Vec<LangItem>>,
|
||||
[] extern_const_body: ExternConstBody(DefId) -> &'tcx hir::Body,
|
||||
[] visible_parent_map: visible_parent_map_node(CrateNum)
|
||||
[] fn get_lang_items: get_lang_items_node(CrateNum) -> Rc<LanguageItems>,
|
||||
[] fn defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefIndex, usize)>>,
|
||||
[] fn missing_lang_items: MissingLangItems(CrateNum) -> Rc<Vec<LangItem>>,
|
||||
[] fn extern_const_body: ExternConstBody(DefId) -> &'tcx hir::Body,
|
||||
[] fn visible_parent_map: visible_parent_map_node(CrateNum)
|
||||
-> Rc<DefIdMap<DefId>>,
|
||||
[] missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool,
|
||||
[] used_crate_source: UsedCrateSource(CrateNum) -> Rc<CrateSource>,
|
||||
[] postorder_cnums: postorder_cnums_node(CrateNum) -> Rc<Vec<CrateNum>>,
|
||||
[] fn missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool,
|
||||
[] fn used_crate_source: UsedCrateSource(CrateNum) -> Rc<CrateSource>,
|
||||
[] fn postorder_cnums: postorder_cnums_node(CrateNum) -> Rc<Vec<CrateNum>>,
|
||||
|
||||
[] freevars: Freevars(HirId) -> Option<Rc<Vec<hir::Freevar>>>,
|
||||
[] maybe_unused_trait_import: MaybeUnusedTraitImport(HirId) -> bool,
|
||||
[] maybe_unused_extern_crates: maybe_unused_extern_crates_node(CrateNum)
|
||||
[] fn freevars: Freevars(HirId) -> Option<Rc<Vec<hir::Freevar>>>,
|
||||
[] fn maybe_unused_trait_import: MaybeUnusedTraitImport(HirId) -> bool,
|
||||
[] fn maybe_unused_extern_crates: maybe_unused_extern_crates_node(CrateNum)
|
||||
-> Rc<Vec<(HirId, Span)>>,
|
||||
|
||||
[] fn stability_index: stability_index_node(CrateNum) -> Rc<stability::Index<'tcx>>,
|
||||
}
|
||||
|
||||
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
|
||||
|
@ -1473,3 +1482,7 @@ fn postorder_cnums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
|
|||
fn maybe_unused_extern_crates_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
|
||||
DepConstructor::MaybeUnusedExternCrates
|
||||
}
|
||||
|
||||
fn stability_index_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
|
||||
DepConstructor::StabilityIndex
|
||||
}
|
||||
|
|
|
@ -934,8 +934,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
|||
"static item recursion checking",
|
||||
|| static_recursion::check_crate(sess, &hir_map))?;
|
||||
|
||||
let index = stability::Index::new(&sess);
|
||||
|
||||
let mut local_providers = ty::maps::Providers::default();
|
||||
borrowck::provide(&mut local_providers);
|
||||
mir::provide(&mut local_providers);
|
||||
|
@ -1022,7 +1020,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
|||
resolutions,
|
||||
named_region_map,
|
||||
hir_map,
|
||||
index,
|
||||
name,
|
||||
|tcx| {
|
||||
let incremental_hashes_map =
|
||||
|
@ -1034,10 +1031,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
|||
"load_dep_graph",
|
||||
|| rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map));
|
||||
|
||||
time(time_passes, "stability index", || {
|
||||
tcx.stability.borrow_mut().build(tcx)
|
||||
});
|
||||
|
||||
time(time_passes,
|
||||
"stability checking",
|
||||
|| stability::check_unstable_api_usage(tcx));
|
||||
|
|
|
@ -19,6 +19,7 @@ use rustc::middle::cstore::{CrateStore, DepKind,
|
|||
MetadataLoader, LinkMeta,
|
||||
LoadedMacro, EncodedMetadata,
|
||||
EncodedMetadataHashes, NativeLibraryKind};
|
||||
use rustc::middle::stability::DeprecationEntry;
|
||||
use rustc::hir::def;
|
||||
use rustc::session::Session;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
|
@ -142,8 +143,12 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
|||
is_default_impl => { cdata.is_default_impl(def_id.index) }
|
||||
describe_def => { cdata.get_def(def_id.index) }
|
||||
def_span => { cdata.get_span(def_id.index, &tcx.sess) }
|
||||
stability => { cdata.get_stability(def_id.index) }
|
||||
deprecation => { cdata.get_deprecation(def_id.index) }
|
||||
lookup_stability => {
|
||||
cdata.get_stability(def_id.index).map(|s| tcx.intern_stability(s))
|
||||
}
|
||||
lookup_deprecation_entry => {
|
||||
cdata.get_deprecation(def_id.index).map(DeprecationEntry::external)
|
||||
}
|
||||
item_attrs => { cdata.get_item_attrs(def_id.index, &tcx.dep_graph) }
|
||||
// FIXME(#38501) We've skipped a `read` on the `HirBody` of
|
||||
// a `fn` when encoding, so the dep-tracking wouldn't work.
|
||||
|
@ -242,6 +247,9 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME(#44234) - almost all of these queries have no sub-queries and
|
||||
// therefore no actual inputs, they're just reading tables calculated in
|
||||
// resolve! Does this work? Unsure! That's what the issue is about
|
||||
*providers = Providers {
|
||||
is_const_fn,
|
||||
is_dllimport_foreign_item: |tcx, id| {
|
||||
|
|
|
@ -99,7 +99,8 @@
|
|||
|
||||
// For #![crate_id], see issue #43142. (I cannot bear to enshrine current behavior in a test)
|
||||
|
||||
#![feature ( x0600)] //~ WARN unused or unknown feature
|
||||
// FIXME(#44232) we should warn that this isn't used.
|
||||
#![feature ( x0600)]
|
||||
|
||||
// For #![no_start], see issue #43144. (I cannot bear to enshrine current behavior in a test)
|
||||
|
||||
|
|
|
@ -8,21 +8,21 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -F unused_features
|
||||
// aux-build:lint_output_format.rs
|
||||
|
||||
// FIXME(#44232) we should warn that this isn't used.
|
||||
#![feature(foo)]
|
||||
//~^ ERROR unused or unknown feature
|
||||
//~| NOTE requested on the command line with `-F unused-features`
|
||||
|
||||
#![feature(test_feature)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
extern crate lint_output_format;
|
||||
use lint_output_format::{foo, bar};
|
||||
//~^ WARNING use of deprecated item: text
|
||||
//~| NOTE #[warn(deprecated)] on by default
|
||||
|
||||
fn main() {
|
||||
#[rustc_error]
|
||||
fn main() { //~ ERROR: compilation successful
|
||||
let _x = foo();
|
||||
//~^ WARNING use of deprecated item: text
|
||||
//~| NOTE #[warn(deprecated)] on by default
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
|
||||
// Tests the default for the unused_features lint
|
||||
|
||||
#![deny(warnings)]
|
||||
// FIXME(#44232) we should warn that this isn't used.
|
||||
#![feature(this_is_not_a_feature)]
|
||||
|
||||
#![feature(this_is_not_a_feature)] //~ ERROR: unused or unknown feature
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
fn main() { }
|
||||
#[rustc_error]
|
||||
fn main() { } //~ ERROR: compilation successful
|
||||
|
|
|
@ -8,8 +8,12 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![deny(unused_features)]
|
||||
#![warn(unused_features)]
|
||||
|
||||
#![feature(this_is_not_a_feature)] //~ ERROR: unused or unknown feature
|
||||
// FIXME(#44232) we should warn that this isn't used.
|
||||
#![feature(this_is_not_a_feature)]
|
||||
|
||||
fn main() {}
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_error]
|
||||
fn main() {} //~ ERROR: compilation successful
|
||||
|
|
|
@ -12,8 +12,11 @@
|
|||
// language and lib features.
|
||||
|
||||
#![deny(stable_features)]
|
||||
|
||||
#![feature(test_accepted_feature)] //~ ERROR this feature has been stable since 1.0.0
|
||||
#![feature(rust1)] //~ ERROR this feature has been stable since 1.0.0
|
||||
|
||||
// FIXME(#44232) we should error that this isn't used.
|
||||
#![feature(rust1)]
|
||||
|
||||
fn main() {
|
||||
let _foo: Vec<()> = Vec::new();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue