提交 9a231961 编写于 作者: A Alex Crichton

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.
上级 0182c8bb
......@@ -511,8 +511,8 @@ pub fn to_dep_node(self, tcx: TyCtxt, kind: DepKind) -> DepNode {
[] ParamEnv(DefId),
[] DescribeDef(DefId),
[] DefSpan(DefId),
[] Stability(DefId),
[] Deprecation(DefId),
[] LookupStability(DefId),
[] LookupDeprecationEntry(DefId),
[] ItemBodyNestedBodies(DefId),
[] ConstIsRvaluePromotableToStatic(DefId),
[] ImplParent(DefId),
......@@ -573,6 +573,7 @@ pub fn to_dep_node(self, tcx: TyCtxt, kind: DepKind) -> DepNode {
[] Freevars(HirId),
[] MaybeUnusedTraitImport(HirId),
[] MaybeUnusedExternCrates,
[] StabilityIndex,
);
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
......
......@@ -878,10 +878,20 @@ pub fn span(&self, id: NodeId) -> Span {
Some(RootCrate(_)) => self.forest.krate.span,
Some(NotPresent) | None => {
// 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)
}
}
}
}
pub fn span_if_local(&self, id: DefId) -> Option<Span> {
self.as_local_node_id(id).map(|id| self.span(id))
......
......@@ -15,20 +15,19 @@
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 @@ pub fn same_origin(&self, other: &DeprecationEntry) -> bool {
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 @@ fn annotate<F>(&mut self, id: NodeId, attrs: &[Attribute],
}
}
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 @@ fn annotate<F>(&mut self, id: NodeId, attrs: &[Attribute],
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 @@ fn annotate<F>(&mut self, id: NodeId, attrs: &[Attribute],
// -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 @@ fn annotate<F>(&mut self, id: NodeId, attrs: &[Attribute],
}
// `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,17 +382,29 @@ fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
}
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,
index: &mut index,
parent_stab: None,
parent_depr: None,
in_trait_impl: false,
......@@ -423,23 +431,21 @@ pub fn build(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
annotator.parent_stab = Some(stability);
}
annotator.annotate(ast::CRATE_NODE_ID, &krate.attrs, krate.span, AnnotationKind::Required,
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 @@ pub fn check_stability(self, def_id: DefId, id: NodeId, span: Span) {
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 @@ pub fn check_stability(self, def_id: DefId, id: NodeId, span: Span) {
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 @@ fn visit_path(&mut self, path: &'tcx hir::Path, id: ast::NodeId) {
}
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 @@ fn format_stable_since_msg(version: &str) -> String {
&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 */ )
}
}
// 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");
// }
}
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 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
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 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
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 @@ pub fn lang_items(self) -> Rc<middle::lang_items::LanguageItems> {
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::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 @@ fn describe(_: TyCtxt, _: DefId) -> String {
}
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 @@ fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
}
}
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 @@ fn default() -> Self {
[] 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 @@ fn default() -> Self {
[] 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>,
[] 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 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>,
[] 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 @@
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 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
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 @@ fn is_const_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
}
}
// 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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册