diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 05f331145af..cda469657ed 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -479,6 +479,7 @@ define_dep_nodes!( <'tcx> [] CheckModPrivacy(DefId), [] CheckModIntrinsics(DefId), [] CheckModLiveness(DefId), + [] CheckModImplWf(DefId), [] CollectModItemTypes(DefId), [] Reachability, diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index df111b2be31..a2947fa0d8c 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -7,7 +7,6 @@ use ty::TyCtxt; use ty::query::Providers; -use ty::query::queries; use hir; use hir::def_id::DefId; @@ -355,7 +354,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_attrs::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_attrs(tcx.hir().local_def_id(module)); } } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index a0f7954eb0c..29d3713900a 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -2,7 +2,7 @@ use hir::def::Def; use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; use ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx}; -use ty::query::{Providers, queries}; +use ty::query::Providers; use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_data_structures::indexed_vec::Idx; @@ -12,7 +12,7 @@ use hir; pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_intrinsics::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_intrinsics(tcx.hir().local_def_id(module)); } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 4ef8e1a0cf9..0724d3a262d 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -100,7 +100,7 @@ use self::VarKind::*; use hir::def::*; use hir::Node; use ty::{self, TyCtxt}; -use ty::query::{Providers, queries}; +use ty::query::Providers; use lint; use errors::Applicability; use util::nodemap::{NodeMap, HirIdMap, HirIdSet}; @@ -187,7 +187,7 @@ fn check_mod_liveness<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_liveness::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_liveness(tcx.hir().local_def_id(module)); } tcx.sess.abort_if_errors(); } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index a9193e06d89..3717ee7143c 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -9,7 +9,6 @@ use hir::def::Def; use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; use hir::intravisit::{self, Visitor, NestedVisitorMap}; use ty::query::Providers; -use ty::query::queries; use middle::privacy::AccessLevels; use session::{DiagnosticMessageId, Session}; use syntax::symbol::Symbol; @@ -459,7 +458,7 @@ impl<'a, 'tcx> Index<'tcx> { pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_unstable_api_usage::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_unstable_api_usage(tcx.hir().local_def_id(module)); } } diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index c4757574ffe..495cce4d2fe 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -51,7 +51,7 @@ pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: Self::Key) -> Cow<'static, str>; #[inline] - fn cache_on_disk(_: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool { false } @@ -136,6 +136,15 @@ impl<'tcx> QueryDescription<'tcx> for queries::check_mod_liveness<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::check_mod_impl_wf<'tcx> { + fn describe( + tcx: TyCtxt<'_, '_, '_>, + key: DefId, + ) -> Cow<'static, str> { + format!("checking that impls are well-formed in {}", key.describe_as_module(tcx)).into() + } +} + impl<'tcx> QueryDescription<'tcx> for queries::collect_mod_item_types<'tcx> { fn describe( tcx: TyCtxt<'_, '_, '_>, @@ -378,7 +387,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> { } #[inline] - fn cache_on_disk(_key: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _key: Self::Key) -> bool { true } @@ -398,7 +407,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval_raw<'tcx> { } #[inline] - fn cache_on_disk(_key: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _key: Self::Key) -> bool { true } @@ -422,7 +431,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> { } #[inline] - fn cache_on_disk(_: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool { true } @@ -496,7 +505,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_sta } #[inline] - fn cache_on_disk(_: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool { true } @@ -530,7 +539,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> } #[inline] - fn cache_on_disk(_: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool { true } @@ -868,7 +877,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> { #[inline] - fn cache_on_disk(def_id: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, def_id: Self::Key) -> bool { def_id.is_local() } @@ -885,7 +894,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> { #[inline] - fn cache_on_disk(def_id: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, def_id: Self::Key) -> bool { def_id.is_local() } @@ -924,7 +933,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> { #[inline] - fn cache_on_disk(def_id: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, def_id: Self::Key) -> bool { def_id.is_local() } @@ -974,10 +983,10 @@ impl<'tcx> QueryDescription<'tcx> for queries::backend_optimization_level<'tcx> } macro_rules! impl_disk_cacheable_query( - ($query_name:ident, |$key:tt| $cond:expr) => { + ($query_name:ident, |$tcx:tt, $key:tt| $cond:expr) => { impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> { #[inline] - fn cache_on_disk($key: Self::Key) -> bool { + fn cache_on_disk($tcx: TyCtxt<'_, 'tcx, 'tcx>, $key: Self::Key) -> bool { $cond } @@ -991,14 +1000,17 @@ macro_rules! impl_disk_cacheable_query( } ); -impl_disk_cacheable_query!(unsafety_check_result, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(borrowck, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(mir_borrowck, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(mir_const_qualif, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(check_match, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(def_symbol_name, |_| true); -impl_disk_cacheable_query!(type_of, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(predicates_of, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(used_trait_imports, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(codegen_fn_attrs, |_| true); -impl_disk_cacheable_query!(specialization_graph_of, |_| true); +impl_disk_cacheable_query!(mir_borrowck, |tcx, def_id| { + def_id.is_local() && tcx.is_closure(def_id) +}); + +impl_disk_cacheable_query!(unsafety_check_result, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(borrowck, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(mir_const_qualif, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(check_match, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(def_symbol_name, |_, _| true); +impl_disk_cacheable_query!(type_of, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(predicates_of, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(used_trait_imports, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(codegen_fn_attrs, |_, _| true); +impl_disk_cacheable_query!(specialization_graph_of, |_, _| true); diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 195bec11ee5..d4884e712b8 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -270,6 +270,8 @@ define_queries! { <'tcx> [] fn check_mod_liveness: CheckModLiveness(DefId) -> (), + [] fn check_mod_impl_wf: CheckModImplWf(DefId) -> (), + [] fn collect_mod_item_types: CollectModItemTypes(DefId) -> (), /// Caches CoerceUnsized kinds for impls on custom types. diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index a674e942b38..a3f49de0d07 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -230,7 +230,7 @@ impl<'sess> OnDiskCache<'sess> { assert!(cache.active.is_empty()); for (key, entry) in cache.results.iter() { use ty::query::config::QueryDescription; - if const_eval::cache_on_disk(key.clone()) { + if const_eval::cache_on_disk(tcx, key.clone()) { if let Ok(ref value) = entry.value { let dep_node = SerializedDepNodeIndex::new(entry.index.index()); @@ -1086,7 +1086,7 @@ fn encode_query_results<'enc, 'a, 'tcx, Q, E>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let map = Q::query_cache(tcx).borrow(); assert!(map.active.is_empty()); for (key, entry) in map.results.iter() { - if Q::cache_on_disk(key.clone()) { + if Q::cache_on_disk(tcx, key.clone()) { let dep_node = SerializedDepNodeIndex::new(entry.index.index()); // Record position of the cache entry diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index e777c883c37..69bff8d25b0 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -434,7 +434,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { debug_assert!(self.dep_graph.is_green(dep_node)); // First we try to load the result from the on-disk cache - let result = if Q::cache_on_disk(key.clone()) && + let result = if Q::cache_on_disk(self.global_tcx(), key.clone()) && self.sess.opts.debugging_opts.incremental_queries { let result = Q::try_load_from_disk(self.global_tcx(), prev_dep_node_index); @@ -969,20 +969,20 @@ macro_rules! define_queries_inner { fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value { handle_cycle_error!([$($modifiers)*][tcx]) } + })* + + #[derive(Copy, Clone)] + pub struct TyCtxtEnsure<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { + pub tcx: TyCtxt<'a, 'gcx, 'tcx>, } - impl<'a, $tcx, 'lcx> queries::$name<$tcx> { - /// Ensure that either this query has all green inputs or been executed. - /// Executing query::ensure(D) is considered a read of the dep-node D. - /// - /// This function is particularly useful when executing passes for their - /// side-effects -- e.g., in order to report errors for erroneous programs. - /// - /// Note: The optimization is only available during incr. comp. - pub fn ensure(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> () { - tcx.ensure_query::>(key); - } - })* + impl<'a, $tcx, 'lcx> TyCtxtEnsure<'a, $tcx, 'lcx> { + $($(#[$attr])* + #[inline(always)] + pub fn $name(self, key: $K) { + self.tcx.ensure_query::>(key) + })* + } #[derive(Copy, Clone)] pub struct TyCtxtAt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { @@ -999,6 +999,15 @@ macro_rules! define_queries_inner { } impl<'a, $tcx, 'lcx> TyCtxt<'a, $tcx, 'lcx> { + /// Return a transparent wrapper for `TyCtxt` which ensures queries + /// are executed instead of returing their result + #[inline(always)] + pub fn ensure(self) -> TyCtxtEnsure<'a, $tcx, 'lcx> { + TyCtxtEnsure { + tcx: self, + } + } + /// Return a transparent wrapper for `TyCtxt` which uses /// `span` as the location of queries performed through it. #[inline(always)] @@ -1251,6 +1260,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::CheckModPrivacy => { force!(check_mod_privacy, def_id!()); } DepKind::CheckModIntrinsics => { force!(check_mod_intrinsics, def_id!()); } DepKind::CheckModLiveness => { force!(check_mod_liveness, def_id!()); } + DepKind::CheckModImplWf => { force!(check_mod_impl_wf, def_id!()); } DepKind::CollectModItemTypes => { force!(collect_mod_item_types, def_id!()); } DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); } DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); } @@ -1433,7 +1443,7 @@ macro_rules! impl_load_from_cache { match self.kind { $(DepKind::$dep_kind => { let def_id = self.extract_def_id(tcx).unwrap(); - queries::$query_name::cache_on_disk(def_id) + queries::$query_name::cache_on_disk(tcx.global_tcx(), def_id) })* _ => false } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 75fc0f716a2..2fe47b2f032 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -402,7 +402,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { return None; }; - ty::query::queries::coherent_trait::ensure(self, drop_trait); + self.ensure().coherent_trait(drop_trait); let mut dtor_did = None; let ty = self.type_of(adt_did); diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 5c11d622d0a..e40c2b45089 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -57,7 +57,7 @@ pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.par_body_owners(|body_owner_def_id| { - tcx.borrowck(body_owner_def_id); + tcx.ensure().borrowck(body_owner_def_id); }); } @@ -121,7 +121,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) // Note that `mir_validated` is a "stealable" result; the // thief, `optimized_mir()`, forces borrowck, so we know that // is not yet stolen. - ty::query::queries::mir_validated::ensure(tcx, owner_def_id); + tcx.ensure().mir_validated(owner_def_id); // option dance because you can't capture an uninitialized variable // by mut-ref. diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index c586c705676..d3412ec2dd9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1283,7 +1283,7 @@ where time(sess, "MIR borrow checking", - || tcx.par_body_owners(|def_id| { tcx.mir_borrowck(def_id); })); + || tcx.par_body_owners(|def_id| { tcx.ensure().mir_borrowck(def_id); })); time(sess, "dumping chalk-like clauses", || { rustc_traits::lowering::dump_program_clauses(tcx); diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 10a4575d812..8d10227cd59 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -28,22 +28,10 @@ use syntax::ast; use syntax::ptr::P; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; -struct OuterVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } - -impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.tcx.hir()) - } - - fn visit_body(&mut self, body: &'tcx hir::Body) { - intravisit::walk_body(self, body); - let def_id = self.tcx.hir().body_owner_def_id(body.id()); - let _ = self.tcx.check_match(def_id); - } -} - pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - tcx.hir().krate().visit_all_item_likes(&mut OuterVisitor { tcx }.as_deep_visitor()); + for def_id in tcx.body_owners() { + tcx.ensure().check_match(def_id); + } tcx.sess.abort_if_errors(); } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 5a80a5fdab5..6ba35052c8a 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -228,10 +228,10 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Mir<'tcx> { // (Mir-)Borrowck uses `mir_validated`, so we have to force it to // execute before we can steal. - let _ = tcx.mir_borrowck(def_id); + tcx.ensure().mir_borrowck(def_id); if tcx.use_ast_borrowck() { - let _ = tcx.borrowck(def_id); + tcx.ensure().borrowck(def_id); } let mut mir = tcx.mir_validated(def_id).steal(); diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 0dcfc72d10b..f05a7be7d75 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -3,7 +3,6 @@ use self::Context::*; use rustc::session::Session; use rustc::ty::query::Providers; -use rustc::ty::query::queries; use rustc::ty::TyCtxt; use rustc::hir::def_id::DefId; use rustc::hir::map::Map; @@ -48,7 +47,7 @@ struct CheckLoopVisitor<'a, 'hir: 'a> { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_loops::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_loops(tcx.hir().local_def_id(module)); } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index dcbb9ff4a75..7f2b82f7e01 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -22,7 +22,7 @@ use rustc::lint; use rustc::middle::privacy::{AccessLevel, AccessLevels}; use rustc::ty::{self, TyCtxt, Ty, TraitRef, TypeFoldable, GenericParamDefKind}; use rustc::ty::fold::TypeVisitor; -use rustc::ty::query::{Providers, queries}; +use rustc::ty::query::Providers; use rustc::ty::subst::Substs; use rustc::util::nodemap::NodeSet; use rustc_data_structures::fx::FxHashSet; @@ -1722,7 +1722,7 @@ fn privacy_access_levels<'tcx>( let krate = tcx.hir().krate(); for &module in krate.modules.keys() { - queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module)); } // Build up a set of all exported items in the AST. This is a set of all diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c94713980d8..48475b3dcb8 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -109,7 +109,6 @@ use rustc::ty::{ use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::fold::TypeFoldable; use rustc::ty::query::Providers; -use rustc::ty::query::queries; use rustc::ty::subst::{UnpackedKind, Subst, Substs, UserSelfTy, UserSubsts}; use rustc::ty::util::{Representability, IntTypeExt, Discr}; use rustc::ty::layout::VariantIdx; @@ -696,14 +695,14 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> { tcx.sess.track_errors(|| { let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); - tcx.hir().krate().visit_all_item_likes(&mut visit.as_deep_visitor()); + tcx.hir().krate().visit_all_item_likes(&mut visit); }) } pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> { tcx.sess.track_errors(|| { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_item_types::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module)); } }) } @@ -722,7 +721,7 @@ fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum debug_assert!(crate_num == LOCAL_CRATE); Ok(tcx.sess.track_errors(|| { tcx.par_body_owners(|body_owner_def_id| { - ty::query::queries::typeck_tables_of::ensure(tcx, body_owner_def_id); + tcx.ensure().typeck_tables_of(body_owner_def_id); }); })?) } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 6cae8d6fc5b..97881708b0a 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -14,7 +14,7 @@ use syntax::feature_gate::{self, GateIssue}; use syntax_pos::Span; use errors::{DiagnosticBuilder, DiagnosticId}; -use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; /// Helper type of a temporary returned by `.for_item(...)`. @@ -1015,30 +1015,23 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { } } -impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { - NestedVisitorMap::None - } - - fn visit_item(&mut self, i: &hir::Item) { +impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'a, 'tcx> { + fn visit_item(&mut self, i: &'tcx hir::Item) { debug!("visit_item: {:?}", i); let def_id = self.tcx.hir().local_def_id(i.id); - ty::query::queries::check_item_well_formed::ensure(self.tcx, def_id); - intravisit::walk_item(self, i); + self.tcx.ensure().check_item_well_formed(def_id); } - fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) { + fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { debug!("visit_trait_item: {:?}", trait_item); let def_id = self.tcx.hir().local_def_id(trait_item.id); - ty::query::queries::check_trait_item_well_formed::ensure(self.tcx, def_id); - intravisit::walk_trait_item(self, trait_item) + self.tcx.ensure().check_trait_item_well_formed(def_id); } - fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) { + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { debug!("visit_impl_item: {:?}", impl_item); let def_id = self.tcx.hir().local_def_id(impl_item.id); - ty::query::queries::check_impl_item_well_formed::ensure(self.tcx, def_id); - intravisit::walk_impl_item(self, impl_item) + self.tcx.ensure().check_impl_item_well_formed(def_id); } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 8053ed130e9..853c4c85d3f 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -9,6 +9,7 @@ use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::traits; use rustc::ty::{self, TyCtxt, TypeFoldable}; use rustc::ty::query::Providers; +use rustc::util::common::time; use syntax::ast; @@ -132,20 +133,22 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { for &impl_id in impls { check_impl_overlap(tcx, impl_id); } - builtin::check_trait(tcx, def_id); + use rustc::util::common::time; + time(tcx.sess, "builtin::check_trait checking", || + builtin::check_trait(tcx, def_id)); } pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &trait_def_id in tcx.hir().krate().trait_impls.keys() { - ty::query::queries::coherent_trait::ensure(tcx, trait_def_id); + tcx.ensure().coherent_trait(trait_def_id); } - unsafety::check(tcx); - orphan::check(tcx); + time(tcx.sess, "unsafety checking", || unsafety::check(tcx)); + time(tcx.sess, "orphan checking", || orphan::check(tcx)); // these queries are executed for side-effects (error reporting): - ty::query::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE); - ty::query::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE); + tcx.ensure().crate_inherent_impls(LOCAL_CRATE); + tcx.ensure().crate_inherent_impls_overlap_check(LOCAL_CRATE); } /// Overlap: No two impls for the same trait are implemented for the diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4275022c4f6..b0b266a61a5 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -23,7 +23,6 @@ use middle::resolve_lifetime as rl; use middle::weak_lang_items; use rustc::mir::mono::Linkage; use rustc::ty::query::Providers; -use rustc::ty::query::queries; use rustc::ty::subst::Substs; use rustc::ty::util::Discr; use rustc::ty::util::IntTypeExt; @@ -58,7 +57,7 @@ struct OnlySelfBounds(bool); pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::collect_mod_item_types::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id(module)); } } diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index d5e15b28fb0..07f5fca6fe6 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -13,6 +13,7 @@ use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::def_id::DefId; use rustc::ty::{self, TyCtxt}; +use rustc::ty::query::Providers; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use std::collections::hash_map::Entry::{Occupied, Vacant}; @@ -52,7 +53,23 @@ pub fn impl_wf_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { // We will tag this as part of the WF check -- logically, it is, // but it's one that we must perform earlier than the rest of // WfCheck. - tcx.hir().krate().visit_all_item_likes(&mut ImplWfCheck { tcx }); + for &module in tcx.hir().krate().modules.keys() { + tcx.ensure().check_mod_impl_wf(tcx.hir().local_def_id(module)); + } +} + +fn check_mod_impl_wf<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { + tcx.hir().visit_item_likes_in_module( + module_def_id, + &mut ImplWfCheck { tcx } + ); +} + +pub fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + check_mod_impl_wf, + ..*providers + }; } struct ImplWfCheck<'a, 'tcx: 'a> { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 5149f460bac..d5e870bb28d 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -318,6 +318,7 @@ pub fn provide(providers: &mut Providers) { check::provide(providers); variance::provide(providers); outlives::provide(providers); + impl_wf_check::provide(providers); } pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) @@ -333,10 +334,12 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) })?; - tcx.sess.track_errors(|| { - time(tcx.sess, "outlives testing", || - outlives::test::test_inferred_outlives(tcx)); - })?; + if tcx.features().rustc_attrs { + tcx.sess.track_errors(|| { + time(tcx.sess, "outlives testing", || + outlives::test::test_inferred_outlives(tcx)); + })?; + } tcx.sess.track_errors(|| { time(tcx.sess, "impl wf inference", || @@ -348,10 +351,12 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) coherence::check_coherence(tcx)); })?; - tcx.sess.track_errors(|| { - time(tcx.sess, "variance testing", || - variance::test::test_variance(tcx)); - })?; + if tcx.features().rustc_attrs { + tcx.sess.track_errors(|| { + time(tcx.sess, "variance testing", || + variance::test::test_variance(tcx)); + })?; + } time(tcx.sess, "wf checking", || check::check_wf_new(tcx))?; diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs index 2b23388fdc9..f7ff3eb3ac9 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs @@ -5,4 +5,4 @@ #[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable #[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable -fn main() {} //~ ERROR [] +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr index 31e24f5b99f..2b90699384b 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr @@ -14,13 +14,6 @@ LL | #[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for ru | = help: add #![feature(rustc_attrs)] to the crate attributes to enable -error[E0208]: [] - --> $DIR/feature-gate-rustc-attrs-1.rs:8:1 - | -LL | fn main() {} //~ ERROR [] - | ^^^^^^^^^^^^ +error: aborting due to 2 previous errors -error: aborting due to 3 previous errors - -Some errors occurred: E0208, E0658. -For more information about an error, try `rustc --explain E0208`. +For more information about this error, try `rustc --explain E0658`.