diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 7a78765365db047e86492d36d152343cc0083bf5..987bb5a9a4de8338268edb42154d75a72d7336fc 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -66,7 +66,6 @@ use ich::Fingerprint; use ty::{TyCtxt, Instance, InstanceDef}; -use ty::fast_reject::SimplifiedType; use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use ich::StableHashingContext; use std::fmt; @@ -430,7 +429,6 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool { [] RegionScopeTree(DefId), [] Coherence, [] CoherenceInherentImplOverlapCheck, - [] Resolve, [] CoherenceCheckTrait(DefId), [] PrivacyAccessLevels(CrateNum), @@ -447,10 +445,8 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool { [] MirBorrowCheck(DefId), [] UnsafetyViolations(DefId), - [] RvalueCheck(DefId), [] Reachability, [] MirKeys, - [] TransWriteMetadata, [] CrateVariances, // Nodes representing bits of computed IR in the tcx. Each shared @@ -498,18 +494,9 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool { // The set of impls for a given trait. [] TraitImpls(DefId), - [] RelevantTraitImpls(DefId, SimplifiedType), [] AllLocalTraitImpls, - // Nodes representing caches. To properly handle a true cache, we - // don't use a DepTrackingMap, but rather we push a task node. - // Otherwise the write into the map would be incorrectly - // attributed to the first task that happened to fill the cache, - // which would yield an overly conservative dep-graph. - [] TraitItems(DefId), - [] ReprHints(DefId), - // Trait selection cache is a little funny. Given a trait // reference like `Foo: SomeTrait`, there could be // arbitrarily many def-ids to map on in there (e.g., `Foo`, @@ -598,7 +585,6 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool { [] MissingLangItems(CrateNum), [] ExternConstBody(DefId), [] VisibleParentMap, - [] IsDirectExternCrate(CrateNum), [] MissingExternCrateItem(CrateNum), [] UsedCrateSource(CrateNum), [] PostorderCnums, @@ -618,6 +604,9 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool { [] CodegenUnit(InternedString), [] CompileCodegenUnit(InternedString), [] OutputFilenames, + + // We use this for most things when incr. comp. is turned off. + [] Null, ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 071f233b188f8591f43be2ee65788340f6345900..80b408f67bb0ef3deb253360422e850d9f16cc62 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -460,8 +460,9 @@ pub fn try_mark_green(&self, let mut current_deps = Vec::new(); - for &dep_dep_node in prev_deps { - let dep_dep_node = &data.previous.index_to_node(dep_dep_node); + for &dep_dep_node_index in prev_deps { + let dep_dep_node = &data.previous.index_to_node(dep_dep_node_index); + let dep_dep_node_color = data.colors.borrow().get(dep_dep_node).cloned(); match dep_dep_node_color { Some(DepNodeColor::Green(node_index)) => { @@ -478,19 +479,42 @@ pub fn try_mark_green(&self, return None } None => { + if dep_dep_node.kind.is_input() { + // This input does not exist anymore. + debug_assert!(dep_dep_node.extract_def_id(tcx).is_none()); + return None; + } + // We don't know the state of this dependency. Let's try to // mark it green. if let Some(node_index) = self.try_mark_green(tcx, dep_dep_node) { current_deps.push(node_index); } else { - // We failed to mark it green. This can have various - // reasons. - return None + // We failed to mark it green, so we try to force the query. + if ::ty::maps::force_from_dep_node(tcx, dep_dep_node) { + let dep_dep_node_color = data.colors.borrow().get(dep_dep_node).cloned(); + match dep_dep_node_color { + Some(DepNodeColor::Green(node_index)) => { + current_deps.push(node_index); + } + Some(DepNodeColor::Red) => { + return None + } + None => { + bug!("try_mark_green() - Forcing the DepNode \ + should have set its color") + } + } + } else { + // The DepNode could not be forced. + return None + } } } } } + // If we got here without hitting a `return` that means that all // dependencies of this DepNode could be marked as green. Therefore we // can also mark this DepNode as green. We do so by... diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index db66c279961b0fa0fdcd73aeb8426a443908c8b5..f6c587a931000099d15304e53ca6ff6a98660791 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -56,6 +56,7 @@ #[macro_use] mod plumbing; use self::plumbing::*; +pub use self::plumbing::force_from_dep_node; mod keys; pub use self::keys::Key; diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index c7c81e3cf89baf7d7b0dee0aa142f5b0b8a5e8f5..6b1fa8f685d00feee2dbceef734f46551e61220d 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -12,7 +12,7 @@ //! that generate the actual methods on tcx which find and execute the //! provider, manage the caches, and so forth. -use dep_graph::{DepNodeIndex}; +use dep_graph::{DepNodeIndex, DepNode, DepKind}; use errors::{Diagnostic, DiagnosticBuilder}; use ty::{TyCtxt}; use ty::maps::Query; // NB: actually generated by the macros in this file @@ -232,12 +232,10 @@ fn to_dep_node(tcx: TyCtxt<'a, $tcx, 'lcx>, key: &$K) -> DepNode { DepNode::new(tcx, $node(*key)) } - fn try_get_with(tcx: TyCtxt<'a, $tcx, 'lcx>, - mut span: Span, - key: $K, - f: F) - -> Result> - where F: FnOnce(&$V) -> R + fn try_get_with(tcx: TyCtxt<'a, $tcx, 'lcx>, + mut span: Span, + key: $K) + -> Result<$V, CycleError<'a, $tcx>> { debug!("ty::queries::{}::try_get_with(key={:?}, span={:?})", stringify!($name), @@ -264,8 +262,9 @@ fn try_get_with(tcx: TyCtxt<'a, $tcx, 'lcx>, } profq_msg!(tcx, ProfileQueriesMsg::CacheHit); tcx.dep_graph.read_index(value.index); - return Ok(f(&value.value)); + return Ok((&value.value).clone()); } + // FIXME(eddyb) Get more valid Span's on queries. // def_span guard is necessary to prevent a recursive loop, // default_span calls def_span query internally. @@ -273,9 +272,43 @@ fn try_get_with(tcx: TyCtxt<'a, $tcx, 'lcx>, span = key.default_span(tcx) } + // Fast path for when incr. comp. is off. `to_dep_node` is + // expensive for some DepKinds. + if !tcx.dep_graph.is_fully_enabled() { + let null_dep_node = DepNode::new_no_params(::dep_graph::DepKind::Null); + return Self::force(tcx, key, span, null_dep_node) + .map(|(v, _)| v); + } + let dep_node = Self::to_dep_node(tcx, &key); - if !dep_node.kind.is_input() && tcx.sess.opts.build_dep_graph() { + if dep_node.kind.is_anon() { + profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin); + + let res = tcx.cycle_check(span, Query::$name(key), || { + tcx.sess.diagnostic().track_diagnostics(|| { + tcx.dep_graph.with_anon_task(dep_node.kind, || { + Self::compute_result(tcx.global_tcx(), key) + }) + }) + })?; + + profq_msg!(tcx, ProfileQueriesMsg::ProviderEnd); + let ((result, dep_node_index), diagnostics) = res; + + tcx.dep_graph.read_index(dep_node_index); + let value = QueryValue::new(result, dep_node_index, diagnostics); + + return Ok((&tcx.maps + .$name + .borrow_mut() + .map + .entry(key) + .or_insert(value) + .value).clone()); + } + + if !dep_node.kind.is_input() { use dep_graph::DepNodeColor; if let Some(DepNodeColor::Green(dep_node_index)) = tcx.dep_graph .node_color(&dep_node) { @@ -284,8 +317,7 @@ fn try_get_with(tcx: TyCtxt<'a, $tcx, 'lcx>, return Self::load_from_disk_and_cache_in_memory(tcx, key, span, - dep_node_index, - f) + dep_node_index) } if let Some(dep_node_index) = tcx.dep_graph.try_mark_green(tcx, &dep_node) { @@ -295,43 +327,17 @@ fn try_get_with(tcx: TyCtxt<'a, $tcx, 'lcx>, return Self::load_from_disk_and_cache_in_memory(tcx, key, span, - dep_node_index, - f) + dep_node_index) } } - // else, we are going to run the provider: - profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin); - - let res = tcx.cycle_check(span, Query::$name(key), || { - tcx.sess.diagnostic().track_diagnostics(|| { - if dep_node.kind.is_anon() { - tcx.dep_graph.with_anon_task(dep_node.kind, || { - Self::compute_result(tcx.global_tcx(), key) - }) - } else { - tcx.dep_graph.with_task(dep_node, - tcx, - key, - Self::compute_result) - } - }) - })?; - - profq_msg!(tcx, ProfileQueriesMsg::ProviderEnd); - let ((result, dep_node_index), diagnostics) = res; - - tcx.dep_graph.read_index(dep_node_index); - - let value = QueryValue::new(result, dep_node_index, diagnostics); - - Ok(f(&tcx.maps - .$name - .borrow_mut() - .map - .entry(key) - .or_insert(value) - .value)) + match Self::force(tcx, key, span, dep_node) { + Ok((result, dep_node_index)) => { + tcx.dep_graph.read_index(dep_node_index); + Ok(result) + } + Err(e) => Err(e) + } } fn compute_result(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> $V { @@ -339,13 +345,11 @@ fn compute_result(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> $V { provider(tcx.global_tcx(), key) } - fn load_from_disk_and_cache_in_memory(tcx: TyCtxt<'a, $tcx, 'lcx>, - key: $K, - span: Span, - dep_node_index: DepNodeIndex, - f: F) - -> Result> - where F: FnOnce(&$V) -> R + fn load_from_disk_and_cache_in_memory(tcx: TyCtxt<'a, $tcx, 'lcx>, + key: $K, + span: Span, + dep_node_index: DepNodeIndex) + -> Result<$V, CycleError<'a, $tcx>> { debug_assert!(tcx.dep_graph.is_green(dep_node_index)); @@ -361,32 +365,56 @@ fn load_from_disk_and_cache_in_memory(tcx: TyCtxt<'a, $tcx, 'lcx>, let value = QueryValue::new(result, dep_node_index, diagnostics); - Ok(f(&tcx.maps + Ok((&tcx.maps + .$name + .borrow_mut() + .map + .entry(key) + .or_insert(value) + .value).clone()) + } + + fn force(tcx: TyCtxt<'a, $tcx, 'lcx>, + key: $K, + span: Span, + dep_node: DepNode) + -> Result<($V, DepNodeIndex), CycleError<'a, $tcx>> { + debug_assert!(tcx.dep_graph.node_color(&dep_node).is_none()); + + profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin); + let res = tcx.cycle_check(span, Query::$name(key), || { + tcx.sess.diagnostic().track_diagnostics(|| { + tcx.dep_graph.with_task(dep_node, + tcx, + key, + Self::compute_result) + }) + })?; + profq_msg!(tcx, ProfileQueriesMsg::ProviderEnd); + + let ((result, dep_node_index), diagnostics) = res; + + let value = QueryValue::new(result, dep_node_index, diagnostics); + + Ok(((&tcx.maps .$name .borrow_mut() .map .entry(key) .or_insert(value) - .value)) + .value).clone(), + dep_node_index)) } + + pub fn try_get(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K) -> Result<$V, DiagnosticBuilder<'a>> { - match Self::try_get_with(tcx, span, key, Clone::clone) { + match Self::try_get_with(tcx, span, key) { Ok(e) => Ok(e), Err(e) => Err(tcx.report_cycle(e)), } } - - pub fn force(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K) { - // Ignore dependencies, since we not reading the computed value - let _task = tcx.dep_graph.in_ignore(); - - match Self::try_get_with(tcx, span, key, |_| ()) { - Ok(()) => {} - Err(e) => tcx.report_cycle(e).emit(), - } - } })* #[derive(Copy, Clone)] @@ -564,3 +592,254 @@ fn default() -> Self { } }; } + +pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, + dep_node: &DepNode) + -> bool { + use ty::maps::keys::Key; + use hir::def_id::LOCAL_CRATE; + + // We should never get into the situation of having to force this from the DepNode. + // Since we cannot reconstruct the query key, we would always end up having to evaluate + // the first caller of this query that *is* reconstructible. This might very well be + // compile_codegen_unit() in which case we'd lose all re-use. + debug_assert!(dep_node.kind != DepKind::CodegenUnit, + "calling force_from_dep_node() on DepKind::CodegenUnit"); + + if !dep_node.kind.can_reconstruct_query_key() { + return false + } + + macro_rules! def_id { + () => { + if let Some(def_id) = dep_node.extract_def_id(tcx) { + def_id + } else { + // return from the whole function + return false + } + } + }; + + macro_rules! krate { + () => { (def_id!()).krate } + }; + + macro_rules! force { + ($query:ident, $key:expr) => { + { + use $crate::util::common::{ProfileQueriesMsg, profq_msg}; + + // FIXME(eddyb) Get more valid Span's on queries. + // def_span guard is necessary to prevent a recursive loop, + // default_span calls def_span query internally. + let span = if stringify!($query) != "def_span" { + $key.default_span(tcx) + } else { + ::syntax_pos::DUMMY_SP + }; + + profq_msg!(tcx, + ProfileQueriesMsg::QueryBegin( + span.clone(), + ::ty::maps::QueryMsg::$query(profq_key!(tcx, $key)) + ) + ); + + match ::ty::maps::queries::$query::force(tcx, $key, span, *dep_node) { + Ok(_) => {}, + Err(e) => { + tcx.report_cycle(e).emit(); + } + } + } + } + }; + + match dep_node.kind { + // These are inputs that are expected to be pre-allocated and that + // should therefore always be red or green already + DepKind::AllLocalTraitImpls | + DepKind::Krate | + DepKind::CrateMetadata | + DepKind::HirBody | + DepKind::Hir | + + // This are anonymous nodes + DepKind::IsCopy | + DepKind::IsSized | + DepKind::IsFreeze | + DepKind::NeedsDrop | + DepKind::Layout | + DepKind::TraitSelect | + DepKind::ProjectionCache | + DepKind::ConstEval | + + // We don't have enough information to reconstruct the query key of + // these + DepKind::InstanceSymbolName | + DepKind::MirShim | + DepKind::BorrowCheckKrate | + DepKind::Specializes | + DepKind::ImplementationsOfTrait | + DepKind::TypeParamPredicates | + DepKind::CodegenUnit | + DepKind::CompileCodegenUnit | + + // This one is just odd + DepKind::Null | + DepKind::WorkProduct => { + bug!("force_from_dep_node() - Encountered {:?}", dep_node.kind) + } + + // These is not a queries + DepKind::CoherenceCheckTrait | + DepKind::ItemVarianceConstraints => { + return false + } + + DepKind::RegionScopeTree => { force!(region_scope_tree, def_id!()); } + + DepKind::Coherence => { force!(crate_inherent_impls, LOCAL_CRATE); } + DepKind::CoherenceInherentImplOverlapCheck => { + force!(crate_inherent_impls_overlap_check, LOCAL_CRATE) + }, + DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); } + DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); } + DepKind::MirConst => { force!(mir_const, def_id!()); } + DepKind::MirValidated => { force!(mir_validated, def_id!()); } + DepKind::MirOptimized => { force!(optimized_mir, def_id!()); } + + DepKind::BorrowCheck => { force!(borrowck, def_id!()); } + DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); } + DepKind::UnsafetyViolations => { force!(unsafety_violations, def_id!()); } + DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); } + DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); } + DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); } + DepKind::AssociatedItems => { force!(associated_item, def_id!()); } + DepKind::TypeOfItem => { force!(type_of, def_id!()); } + DepKind::GenericsOfItem => { force!(generics_of, def_id!()); } + DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); } + DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); } + DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); } + DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); } + DepKind::IsDefaultImpl => { force!(is_default_impl, def_id!()); } + DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); } + DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); } + DepKind::ClosureKind => { force!(closure_kind, def_id!()); } + DepKind::FnSignature => { force!(fn_sig, def_id!()); } + DepKind::GenSignature => { force!(generator_sig, def_id!()); } + DepKind::CoerceUnsizedInfo => { force!(coerce_unsized_info, def_id!()); } + DepKind::ItemVariances => { force!(variances_of, def_id!()); } + DepKind::IsConstFn => { force!(is_const_fn, def_id!()); } + DepKind::IsForeignItem => { force!(is_foreign_item, def_id!()); } + DepKind::SizedConstraint => { force!(adt_sized_constraint, def_id!()); } + DepKind::DtorckConstraint => { force!(adt_dtorck_constraint, def_id!()); } + DepKind::AdtDestructor => { force!(adt_destructor, def_id!()); } + DepKind::AssociatedItemDefIds => { force!(associated_item_def_ids, def_id!()); } + DepKind::InherentImpls => { force!(inherent_impls, def_id!()); } + DepKind::TypeckBodiesKrate => { force!(typeck_item_bodies, LOCAL_CRATE); } + DepKind::TypeckTables => { force!(typeck_tables_of, def_id!()); } + DepKind::HasTypeckTables => { force!(has_typeck_tables, def_id!()); } + DepKind::SymbolName => { force!(def_symbol_name, def_id!()); } + DepKind::SpecializationGraph => { force!(specialization_graph_of, def_id!()); } + DepKind::ObjectSafety => { force!(is_object_safe, def_id!()); } + DepKind::TraitImpls => { force!(trait_impls_of, def_id!()); } + + DepKind::ParamEnv => { force!(param_env, def_id!()); } + DepKind::DescribeDef => { force!(describe_def, def_id!()); } + DepKind::DefSpan => { force!(def_span, def_id!()); } + DepKind::LookupStability => { force!(lookup_stability, def_id!()); } + DepKind::LookupDeprecationEntry => { + force!(lookup_deprecation_entry, def_id!()); + } + DepKind::ItemBodyNestedBodies => { force!(item_body_nested_bodies, def_id!()); } + DepKind::ConstIsRvaluePromotableToStatic => { + force!(const_is_rvalue_promotable_to_static, def_id!()); + } + DepKind::ImplParent => { force!(impl_parent, def_id!()); } + DepKind::TraitOfItem => { force!(trait_of_item, def_id!()); } + DepKind::IsExportedSymbol => { force!(is_exported_symbol, def_id!()); } + DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); } + DepKind::ItemAttrs => { force!(item_attrs, def_id!()); } + DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); } + DepKind::DylibDepFormats => { force!(dylib_dependency_formats, krate!()); } + DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); } + DepKind::IsCompilerBuiltins => { force!(is_compiler_builtins, krate!()); } + DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); } + DepKind::ExternCrate => { force!(extern_crate, def_id!()); } + DepKind::LintLevels => { force!(lint_levels, LOCAL_CRATE); } + DepKind::InScopeTraits => { force!(in_scope_traits_map, def_id!().index); } + DepKind::ModuleExports => { force!(module_exports, def_id!()); } + DepKind::IsSanitizerRuntime => { force!(is_sanitizer_runtime, krate!()); } + DepKind::IsProfilerRuntime => { force!(is_profiler_runtime, krate!()); } + DepKind::GetPanicStrategy => { force!(panic_strategy, krate!()); } + DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); } + DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); } + DepKind::ExportedSymbolIds => { force!(exported_symbol_ids, krate!()); } + DepKind::NativeLibraries => { force!(native_libraries, krate!()); } + DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); } + DepKind::DeriveRegistrarFn => { force!(derive_registrar_fn, krate!()); } + DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); } + DepKind::CrateHash => { force!(crate_hash, krate!()); } + DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); } + + DepKind::AllTraitImplementations => { + force!(all_trait_implementations, krate!()); + } + + DepKind::IsDllimportForeignItem => { + force!(is_dllimport_foreign_item, def_id!()); + } + DepKind::IsStaticallyIncludedForeignItem => { + force!(is_statically_included_foreign_item, def_id!()); + } + DepKind::NativeLibraryKind => { force!(native_library_kind, def_id!()); } + DepKind::LinkArgs => { force!(link_args, LOCAL_CRATE); } + + DepKind::NamedRegion => { force!(named_region_map, def_id!().index); } + DepKind::IsLateBound => { force!(is_late_bound_map, def_id!().index); } + DepKind::ObjectLifetimeDefaults => { + force!(object_lifetime_defaults_map, def_id!().index); + } + + DepKind::Visibility => { force!(visibility, def_id!()); } + DepKind::DepKind => { force!(dep_kind, krate!()); } + DepKind::CrateName => { force!(crate_name, krate!()); } + DepKind::ItemChildren => { force!(item_children, def_id!()); } + DepKind::ExternModStmtCnum => { force!(extern_mod_stmt_cnum, def_id!()); } + DepKind::GetLangItems => { force!(get_lang_items, LOCAL_CRATE); } + DepKind::DefinedLangItems => { force!(defined_lang_items, krate!()); } + DepKind::MissingLangItems => { force!(missing_lang_items, krate!()); } + DepKind::ExternConstBody => { force!(extern_const_body, def_id!()); } + DepKind::VisibleParentMap => { force!(visible_parent_map, LOCAL_CRATE); } + DepKind::MissingExternCrateItem => { + force!(missing_extern_crate_item, krate!()); + } + DepKind::UsedCrateSource => { force!(used_crate_source, krate!()); } + DepKind::PostorderCnums => { force!(postorder_cnums, LOCAL_CRATE); } + DepKind::HasCloneClosures => { force!(has_clone_closures, krate!()); } + DepKind::HasCopyClosures => { force!(has_copy_closures, krate!()); } + + DepKind::Freevars => { force!(freevars, def_id!()); } + DepKind::MaybeUnusedTraitImport => { + force!(maybe_unused_trait_import, def_id!()); + } + DepKind::MaybeUnusedExternCrates => { force!(maybe_unused_extern_crates, LOCAL_CRATE); } + DepKind::StabilityIndex => { force!(stability_index, LOCAL_CRATE); } + DepKind::AllCrateNums => { force!(all_crate_nums, LOCAL_CRATE); } + DepKind::ExportedSymbols => { force!(exported_symbols, krate!()); } + DepKind::CollectAndPartitionTranslationItems => { + force!(collect_and_partition_translation_items, LOCAL_CRATE); + } + DepKind::ExportName => { force!(export_name, def_id!()); } + DepKind::ContainsExternIndicator => { + force!(contains_extern_indicator, def_id!()); + } + DepKind::IsTranslatedFunction => { force!(is_translated_function, def_id!()); } + DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); } + } + + true +} + diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 7245b2daa126081b57cd0329e55e3ec754ed9de6..322f46cf02b6332b6877c29617eae386875fd858 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -13,7 +13,7 @@ use rustc::mir::Mir; use rustc::mir::transform::{MirPassIndex, MirSuite, MirSource, MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED}; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; use rustc::ty::steal::Steal; use rustc::hir; @@ -21,7 +21,7 @@ use rustc::util::nodemap::DefIdSet; use std::rc::Rc; use syntax::ast; -use syntax_pos::{DUMMY_SP, Span}; +use syntax_pos::Span; use transform; pub mod add_validation; @@ -114,11 +114,10 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx let source = MirSource::from_local_def_id(tcx, def_id); if let MirSource::Const(_) = source { // Ensure that we compute the `mir_const_qualif` for constants at - // this point, before we steal the mir-const result. We don't - // directly need the result or `mir_const_qualif`, so we can just force it. - ty::queries::mir_const_qualif::force(tcx, DUMMY_SP, def_id); + // this point, before we steal the mir-const result. + let _ = tcx.mir_const_qualif(def_id); } - ty::queries::unsafety_violations::force(tcx, DUMMY_SP, def_id); + let _ = tcx.unsafety_violations(def_id); let mut mir = tcx.mir_const(def_id).steal(); transform::run_suite(tcx, source, MIR_VALIDATED, &mut mir); @@ -128,8 +127,8 @@ 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. - ty::queries::mir_borrowck::force(tcx, DUMMY_SP, def_id); - ty::queries::borrowck::force(tcx, DUMMY_SP, def_id); + let _ = tcx.mir_borrowck(def_id); + let _ = tcx.borrowck(def_id); let mut mir = tcx.mir_validated(def_id).steal(); let source = MirSource::from_local_def_id(tcx, def_id); diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 0568bd2f3cabd5803ec389a9a15a5e593b26b2d5..56b20047808ccd05c86fb4912b707bcbc51d658d 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -947,6 +947,19 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, shared_ccx.tcx().collect_and_partition_translation_items(LOCAL_CRATE).1; let codegen_units = (*codegen_units).clone(); + // Force all codegen_unit queries so they are already either red or green + // when compile_codegen_unit accesses them. We are not able to re-execute + // the codegen_unit query from just the DepNode, so an unknown color would + // lead to having to re-execute compile_codegen_unit, possibly + // unnecessarily. + if tcx.dep_graph.is_fully_enabled() { + for cgu in &codegen_units { + tcx.codegen_unit(cgu.name().clone()); + } + } + + assert!(codegen_units.len() <= 1 || !tcx.sess.lto()); + let ongoing_translation = write::start_async_translation( tcx, time_graph.clone(),