Skip to content

Commit 128aa26

Browse files
committed
Auto merge of #41368 - nikomatsakis:incr-comp-dep-tracking-map, r=eddyb
make *most* maps private Currently we access the `DepTrackingMap` fields directly rather than using the query accessors. This seems bad. This branch removes several such uses, but not all, and extends the macro so that queries can hide their maps (so we can prevent regressions). The extension to the macro is kind of ugly :/ but couldn't find a simple way to do it otherwise (I guess I could use a nested macro...). Anyway I figure it's only temporary. r? @eddyb
2 parents ad1461e + d7d3f19 commit 128aa26

File tree

12 files changed

+251
-172
lines changed

12 files changed

+251
-172
lines changed

src/librustc/middle/dead.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -475,14 +475,13 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
475475
// This is done to handle the case where, for example, the static
476476
// method of a private type is used, but the type itself is never
477477
// called directly.
478-
if let Some(impl_list) =
479-
self.tcx.maps.inherent_impls.borrow().get(&self.tcx.hir.local_def_id(id)) {
480-
for &impl_did in impl_list.iter() {
481-
for &item_did in &self.tcx.associated_item_def_ids(impl_did)[..] {
482-
if let Some(item_node_id) = self.tcx.hir.as_local_node_id(item_did) {
483-
if self.live_symbols.contains(&item_node_id) {
484-
return true;
485-
}
478+
let def_id = self.tcx.hir.local_def_id(id);
479+
let inherent_impls = self.tcx.inherent_impls(def_id);
480+
for &impl_did in inherent_impls.iter() {
481+
for &item_did in &self.tcx.associated_item_def_ids(impl_did)[..] {
482+
if let Some(item_node_id) = self.tcx.hir.as_local_node_id(item_did) {
483+
if self.live_symbols.contains(&item_node_id) {
484+
return true;
486485
}
487486
}
488487
}

src/librustc/ty/item_path.rs

+31-12
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,19 @@ use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
1313
use ty::{self, Ty, TyCtxt};
1414
use syntax::ast;
1515
use syntax::symbol::Symbol;
16+
use syntax_pos::DUMMY_SP;
1617

1718
use std::cell::Cell;
1819

1920
thread_local! {
20-
static FORCE_ABSOLUTE: Cell<bool> = Cell::new(false)
21+
static FORCE_ABSOLUTE: Cell<bool> = Cell::new(false);
22+
static FORCE_IMPL_FILENAME_LINE: Cell<bool> = Cell::new(false);
2123
}
2224

23-
/// Enforces that item_path_str always returns an absolute path.
24-
/// This is useful when building symbols that contain types,
25-
/// where we want the crate name to be part of the symbol.
25+
/// Enforces that item_path_str always returns an absolute path and
26+
/// also enables "type-based" impl paths. This is used when building
27+
/// symbols that contain types, where we want the crate name to be
28+
/// part of the symbol.
2629
pub fn with_forced_absolute_paths<F: FnOnce() -> R, R>(f: F) -> R {
2730
FORCE_ABSOLUTE.with(|force| {
2831
let old = force.get();
@@ -33,6 +36,20 @@ pub fn with_forced_absolute_paths<F: FnOnce() -> R, R>(f: F) -> R {
3336
})
3437
}
3538

39+
/// Force us to name impls with just the filename/line number. We
40+
/// normally try to use types. But at some points, notably while printing
41+
/// cycle errors, this can result in extra or suboptimal error output,
42+
/// so this variable disables that check.
43+
pub fn with_forced_impl_filename_line<F: FnOnce() -> R, R>(f: F) -> R {
44+
FORCE_IMPL_FILENAME_LINE.with(|force| {
45+
let old = force.get();
46+
force.set(true);
47+
let result = f();
48+
force.set(old);
49+
result
50+
})
51+
}
52+
3653
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
3754
/// Returns a string identifying this def-id. This string is
3855
/// suitable for user output. It is relative to the current crate
@@ -199,14 +216,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
199216
{
200217
let parent_def_id = self.parent_def_id(impl_def_id).unwrap();
201218

202-
let use_types = if !impl_def_id.is_local() {
203-
// always have full types available for extern crates
204-
true
205-
} else {
206-
// for local crates, check whether type info is
207-
// available; typeck might not have completed yet
208-
self.maps.impl_trait_ref.borrow().contains_key(&impl_def_id) &&
209-
self.maps.type_of.borrow().contains_key(&impl_def_id)
219+
// Always use types for non-local impls, where types are always
220+
// available, and filename/line-number is mostly uninteresting.
221+
let use_types = !impl_def_id.is_local() || {
222+
// Otherwise, use filename/line-number if forced.
223+
let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
224+
!force_no_types && {
225+
// Otherwise, use types if we can query them without inducing a cycle.
226+
ty::queries::impl_trait_ref::try_get(self, DUMMY_SP, impl_def_id).is_ok() &&
227+
ty::queries::type_of::try_get(self, DUMMY_SP, impl_def_id).is_ok()
228+
}
210229
};
211230

212231
if !use_types {

src/librustc/ty/maps.rs

+75-54
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ use middle::privacy::AccessLevels;
1717
use mir;
1818
use session::CompileResult;
1919
use ty::{self, CrateInherentImpls, Ty, TyCtxt};
20+
use ty::item_path;
2021
use ty::subst::Substs;
2122
use util::nodemap::NodeSet;
2223

2324
use rustc_data_structures::indexed_vec::IndexVec;
2425
use std::cell::{RefCell, RefMut};
26+
use std::mem;
2527
use std::ops::Deref;
2628
use std::rc::Rc;
2729
use syntax_pos::{Span, DUMMY_SP};
@@ -139,24 +141,36 @@ pub struct CycleError<'a, 'tcx: 'a> {
139141

140142
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
141143
pub fn report_cycle(self, CycleError { span, cycle }: CycleError) {
142-
assert!(!cycle.is_empty());
143-
144-
let mut err = struct_span_err!(self.sess, span, E0391,
145-
"unsupported cyclic reference between types/traits detected");
146-
err.span_label(span, &format!("cyclic reference"));
147-
148-
err.span_note(cycle[0].0, &format!("the cycle begins when {}...",
149-
cycle[0].1.describe(self)));
150-
151-
for &(span, ref query) in &cycle[1..] {
152-
err.span_note(span, &format!("...which then requires {}...",
153-
query.describe(self)));
154-
}
144+
// Subtle: release the refcell lock before invoking `describe()`
145+
// below by dropping `cycle`.
146+
let stack = cycle.to_vec();
147+
mem::drop(cycle);
148+
149+
assert!(!stack.is_empty());
150+
151+
// Disable naming impls with types in this path, since that
152+
// sometimes cycles itself, leading to extra cycle errors.
153+
// (And cycle errors around impls tend to occur during the
154+
// collect/coherence phases anyhow.)
155+
item_path::with_forced_impl_filename_line(|| {
156+
let mut err =
157+
struct_span_err!(self.sess, span, E0391,
158+
"unsupported cyclic reference between types/traits detected");
159+
err.span_label(span, &format!("cyclic reference"));
160+
161+
err.span_note(stack[0].0, &format!("the cycle begins when {}...",
162+
stack[0].1.describe(self)));
163+
164+
for &(span, ref query) in &stack[1..] {
165+
err.span_note(span, &format!("...which then requires {}...",
166+
query.describe(self)));
167+
}
155168

156-
err.note(&format!("...which then again requires {}, completing the cycle.",
157-
cycle[0].1.describe(self)));
169+
err.note(&format!("...which then again requires {}, completing the cycle.",
170+
stack[0].1.describe(self)));
158171

159-
err.emit();
172+
err.emit();
173+
});
160174
}
161175

162176
fn cycle_check<F, R>(self, span: Span, query: Query<'gcx>, compute: F)
@@ -274,11 +288,11 @@ impl<'tcx> QueryDescription for queries::describe_def<'tcx> {
274288
macro_rules! define_maps {
275289
(<$tcx:tt>
276290
$($(#[$attr:meta])*
277-
pub $name:ident: $node:ident($K:ty) -> $V:ty),*) => {
291+
[$($pub:tt)*] $name:ident: $node:ident($K:ty) -> $V:ty),*) => {
278292
pub struct Maps<$tcx> {
279293
providers: IndexVec<CrateNum, Providers<$tcx>>,
280294
query_stack: RefCell<Vec<(Span, Query<$tcx>)>>,
281-
$($(#[$attr])* pub $name: RefCell<DepTrackingMap<queries::$name<$tcx>>>),*
295+
$($(#[$attr])* $($pub)* $name: RefCell<DepTrackingMap<queries::$name<$tcx>>>),*
282296
}
283297

284298
impl<$tcx> Maps<$tcx> {
@@ -335,6 +349,11 @@ macro_rules! define_maps {
335349
-> Result<R, CycleError<'a, $tcx>>
336350
where F: FnOnce(&$V) -> R
337351
{
352+
debug!("ty::queries::{}::try_get_with(key={:?}, span={:?})",
353+
stringify!($name),
354+
key,
355+
span);
356+
338357
if let Some(result) = tcx.maps.$name.borrow().get(&key) {
339358
return Ok(f(result));
340359
}
@@ -441,52 +460,52 @@ macro_rules! define_maps {
441460
// the driver creates (using several `rustc_*` crates).
442461
define_maps! { <'tcx>
443462
/// Records the type of every item.
444-
pub type_of: ItemSignature(DefId) -> Ty<'tcx>,
463+
[] type_of: ItemSignature(DefId) -> Ty<'tcx>,
445464

446465
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
447466
/// associated generics and predicates.
448-
pub generics_of: ItemSignature(DefId) -> &'tcx ty::Generics,
449-
pub predicates_of: ItemSignature(DefId) -> ty::GenericPredicates<'tcx>,
467+
[] generics_of: ItemSignature(DefId) -> &'tcx ty::Generics,
468+
[] predicates_of: ItemSignature(DefId) -> ty::GenericPredicates<'tcx>,
450469

451470
/// Maps from the def-id of a trait to the list of
452471
/// super-predicates. This is a subset of the full list of
453472
/// predicates. We store these in a separate map because we must
454473
/// evaluate them even during type conversion, often before the
455474
/// full predicates are available (note that supertraits have
456475
/// additional acyclicity requirements).
457-
pub super_predicates_of: ItemSignature(DefId) -> ty::GenericPredicates<'tcx>,
476+
[] super_predicates_of: ItemSignature(DefId) -> ty::GenericPredicates<'tcx>,
458477

459478
/// To avoid cycles within the predicates of a single item we compute
460479
/// per-type-parameter predicates for resolving `T::AssocTy`.
461-
pub type_param_predicates: TypeParamPredicates((DefId, DefId))
480+
[] type_param_predicates: TypeParamPredicates((DefId, DefId))
462481
-> ty::GenericPredicates<'tcx>,
463482

464-
pub trait_def: ItemSignature(DefId) -> &'tcx ty::TraitDef,
465-
pub adt_def: ItemSignature(DefId) -> &'tcx ty::AdtDef,
466-
pub adt_destructor: AdtDestructor(DefId) -> Option<ty::Destructor>,
467-
pub adt_sized_constraint: SizedConstraint(DefId) -> &'tcx [Ty<'tcx>],
468-
pub adt_dtorck_constraint: DtorckConstraint(DefId) -> ty::DtorckConstraint<'tcx>,
483+
[] trait_def: ItemSignature(DefId) -> &'tcx ty::TraitDef,
484+
[] adt_def: ItemSignature(DefId) -> &'tcx ty::AdtDef,
485+
[] adt_destructor: AdtDestructor(DefId) -> Option<ty::Destructor>,
486+
[] adt_sized_constraint: SizedConstraint(DefId) -> &'tcx [Ty<'tcx>],
487+
[] adt_dtorck_constraint: DtorckConstraint(DefId) -> ty::DtorckConstraint<'tcx>,
469488

470489
/// True if this is a foreign item (i.e., linked via `extern { ... }`).
471-
pub is_foreign_item: IsForeignItem(DefId) -> bool,
490+
[] is_foreign_item: IsForeignItem(DefId) -> bool,
472491

473492
/// Maps from def-id of a type or region parameter to its
474493
/// (inferred) variance.
475-
pub variances_of: ItemSignature(DefId) -> Rc<Vec<ty::Variance>>,
494+
[pub] variances_of: ItemSignature(DefId) -> Rc<Vec<ty::Variance>>,
476495

477496
/// Maps from an impl/trait def-id to a list of the def-ids of its items
478-
pub associated_item_def_ids: AssociatedItemDefIds(DefId) -> Rc<Vec<DefId>>,
497+
[] associated_item_def_ids: AssociatedItemDefIds(DefId) -> Rc<Vec<DefId>>,
479498

480499
/// Maps from a trait item to the trait item "descriptor"
481-
pub associated_item: AssociatedItems(DefId) -> ty::AssociatedItem,
500+
[] associated_item: AssociatedItems(DefId) -> ty::AssociatedItem,
482501

483-
pub impl_trait_ref: ItemSignature(DefId) -> Option<ty::TraitRef<'tcx>>,
484-
pub impl_polarity: ItemSignature(DefId) -> hir::ImplPolarity,
502+
[] impl_trait_ref: ItemSignature(DefId) -> Option<ty::TraitRef<'tcx>>,
503+
[] impl_polarity: ItemSignature(DefId) -> hir::ImplPolarity,
485504

486505
/// Maps a DefId of a type to a list of its inherent impls.
487506
/// Contains implementations of methods that are inherent to a type.
488507
/// Methods in these implementations don't need to be exported.
489-
pub inherent_impls: InherentImpls(DefId) -> Rc<Vec<DefId>>,
508+
[] inherent_impls: InherentImpls(DefId) -> Rc<Vec<DefId>>,
490509

491510
/// Maps from the def-id of a function/method or const/static
492511
/// to its MIR. Mutation is done at an item granularity to
@@ -495,59 +514,61 @@ define_maps! { <'tcx>
495514
///
496515
/// Note that cross-crate MIR appears to be always borrowed
497516
/// (in the `RefCell` sense) to prevent accidental mutation.
498-
pub mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>>,
517+
[pub] mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>>,
499518

500519
/// Maps DefId's that have an associated Mir to the result
501520
/// of the MIR qualify_consts pass. The actual meaning of
502521
/// the value isn't known except to the pass itself.
503-
pub mir_const_qualif: Mir(DefId) -> u8,
522+
[] mir_const_qualif: Mir(DefId) -> u8,
504523

505524
/// Records the type of each closure. The def ID is the ID of the
506525
/// expression defining the closure.
507-
pub closure_kind: ItemSignature(DefId) -> ty::ClosureKind,
526+
[] closure_kind: ItemSignature(DefId) -> ty::ClosureKind,
508527

509528
/// Records the type of each closure. The def ID is the ID of the
510529
/// expression defining the closure.
511-
pub closure_type: ItemSignature(DefId) -> ty::PolyFnSig<'tcx>,
530+
[] closure_type: ItemSignature(DefId) -> ty::PolyFnSig<'tcx>,
512531

513532
/// Caches CoerceUnsized kinds for impls on custom types.
514-
pub coerce_unsized_info: ItemSignature(DefId)
533+
[] coerce_unsized_info: ItemSignature(DefId)
515534
-> ty::adjustment::CoerceUnsizedInfo,
516535

517-
pub typeck_item_bodies: typeck_item_bodies_dep_node(CrateNum) -> CompileResult,
536+
[] typeck_item_bodies: typeck_item_bodies_dep_node(CrateNum) -> CompileResult,
518537

519-
pub typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
538+
[] typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
520539

521-
pub coherent_trait: coherent_trait_dep_node((CrateNum, DefId)) -> (),
540+
[] has_typeck_tables: TypeckTables(DefId) -> bool,
522541

523-
pub borrowck: BorrowCheck(DefId) -> (),
542+
[] coherent_trait: coherent_trait_dep_node((CrateNum, DefId)) -> (),
543+
544+
[] borrowck: BorrowCheck(DefId) -> (),
524545

525546
/// Gets a complete map from all types to their inherent impls.
526547
/// Not meant to be used directly outside of coherence.
527548
/// (Defined only for LOCAL_CRATE)
528-
pub crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum) -> CrateInherentImpls,
549+
[] crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum) -> CrateInherentImpls,
529550

530551
/// Checks all types in the krate for overlap in their inherent impls. Reports errors.
531552
/// Not meant to be used directly outside of coherence.
532553
/// (Defined only for LOCAL_CRATE)
533-
pub crate_inherent_impls_overlap_check: crate_inherent_impls_dep_node(CrateNum) -> (),
554+
[] crate_inherent_impls_overlap_check: crate_inherent_impls_dep_node(CrateNum) -> (),
534555

535556
/// Results of evaluating const items or constants embedded in
536557
/// other items (such as enum variant explicit discriminants).
537-
pub const_eval: const_eval_dep_node((DefId, &'tcx Substs<'tcx>))
558+
[] const_eval: const_eval_dep_node((DefId, &'tcx Substs<'tcx>))
538559
-> const_val::EvalResult<'tcx>,
539560

540561
/// Performs the privacy check and computes "access levels".
541-
pub privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc<AccessLevels>,
562+
[] privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc<AccessLevels>,
542563

543-
pub reachable_set: reachability_dep_node(CrateNum) -> Rc<NodeSet>,
564+
[] reachable_set: reachability_dep_node(CrateNum) -> Rc<NodeSet>,
544565

545-
pub mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>,
566+
[] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>,
546567

547-
pub def_symbol_name: SymbolName(DefId) -> ty::SymbolName,
548-
pub symbol_name: symbol_name_dep_node(ty::Instance<'tcx>) -> ty::SymbolName,
568+
[] def_symbol_name: SymbolName(DefId) -> ty::SymbolName,
569+
[] symbol_name: symbol_name_dep_node(ty::Instance<'tcx>) -> ty::SymbolName,
549570

550-
pub describe_def: meta_data_node(DefId) -> Option<Def>
571+
[] describe_def: meta_data_node(DefId) -> Option<Def>
551572
}
552573

553574
fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
@@ -582,4 +603,4 @@ fn const_eval_dep_node((def_id, _): (DefId, &Substs)) -> DepNode<DefId> {
582603

583604
fn meta_data_node(def_id: DefId) -> DepNode<DefId> {
584605
DepNode::MetaData(def_id)
585-
}
606+
}

0 commit comments

Comments
 (0)