Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 12f6c50

Browse files
committedMar 27, 2017
Rollup merge of rust-lang#40683 - nikomatsakis:incr-comp-coerce-unsized-info, r=eddyb
on-demand-ify `custom_coerce_unsized_kind` and `inherent-impls` This "on-demand" task both checks for errors and computes the custom unsized kind, if any. This task is only defined on impls of `CoerceUnsized`; invoking it on any other kind of impl results in a bug. This is just to avoid having an `Option`, could easily be changed. r? @eddyb
2 parents 666bb19 + a29ae30 commit 12f6c50

File tree

17 files changed

+306
-220
lines changed

17 files changed

+306
-220
lines changed
 

‎src/librustc/dep_graph/dep_node.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ pub enum DepNode<D: Clone + Debug> {
7575
CoherenceCheckImpl(D),
7676
CoherenceOverlapCheck(D),
7777
CoherenceOverlapCheckSpecial(D),
78-
CoherenceOverlapInherentCheck(D),
7978
CoherenceOrphanCheck(D),
8079
Variance,
8180
WfCheck(D),
@@ -252,7 +251,6 @@ impl<D: Clone + Debug> DepNode<D> {
252251
CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
253252
CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
254253
CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
255-
CoherenceOverlapInherentCheck(ref d) => op(d).map(CoherenceOverlapInherentCheck),
256254
CoherenceOrphanCheck(ref d) => op(d).map(CoherenceOrphanCheck),
257255
WfCheck(ref d) => op(d).map(WfCheck),
258256
TypeckItemType(ref d) => op(d).map(TypeckItemType),

‎src/librustc/dep_graph/dep_tracking_map.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,6 @@ impl<M: DepTrackingMapConfig> DepTrackingMap<M> {
8181
pub fn keys(&self) -> Vec<M::Key> {
8282
self.map.keys().cloned().collect()
8383
}
84-
85-
/// Append `elem` to the vector stored for `k`, creating a new vector if needed.
86-
/// This is considered a write to `k`.
87-
///
88-
/// NOTE: Caution is required when using this method. You should
89-
/// be sure that nobody is **reading from the vector** while you
90-
/// are writing to it. Eventually, it'd be nice to remove this.
91-
pub fn push<E: Clone>(&mut self, k: M::Key, elem: E)
92-
where M: DepTrackingMapConfig<Value=Vec<E>>
93-
{
94-
self.write(&k);
95-
self.map.entry(k)
96-
.or_insert(Vec::new())
97-
.push(elem);
98-
}
9984
}
10085

10186
impl<M: DepTrackingMapConfig> MemoizationMap for RefCell<DepTrackingMap<M>> {

‎src/librustc/middle/cstore.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ pub trait CrateStore {
176176
fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
177177
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
178178
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
179-
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
180179

181180
// trait info
182181
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
@@ -310,7 +309,6 @@ impl CrateStore for DummyCrateStore {
310309
{ bug!("item_generics_cloned") }
311310
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
312311
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name> { bug!("fn_arg_names") }
313-
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
314312

315313
// trait info
316314
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }

‎src/librustc/ty/adjustment.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,21 @@ pub enum AutoBorrow<'tcx> {
139139
RawPtr(hir::Mutability),
140140
}
141141

142+
/// Information for `CoerceUnsized` impls, storing information we
143+
/// have computed about the coercion.
144+
///
145+
/// This struct can be obtained via the `coerce_impl_info` query.
146+
/// Demanding this struct also has the side-effect of reporting errors
147+
/// for inappropriate impls.
148+
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
149+
pub struct CoerceUnsizedInfo {
150+
/// If this is a "custom coerce" impl, then what kind of custom
151+
/// coercion is it? This applies to impls of `CoerceUnsized` for
152+
/// structs, primarily, where we store a bit of info about which
153+
/// fields need to be coerced.
154+
pub custom_kind: Option<CustomCoerceUnsized>
155+
}
156+
142157
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
143158
pub enum CustomCoerceUnsized {
144159
/// Records the index of the field being coerced.

‎src/librustc/ty/maps.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
1313
use middle::const_val::ConstVal;
1414
use middle::privacy::AccessLevels;
1515
use mir;
16-
use ty::{self, Ty, TyCtxt};
16+
use ty::{self, CrateInherentImpls, Ty, TyCtxt};
1717

1818
use rustc_data_structures::indexed_vec::IndexVec;
1919
use std::cell::{RefCell, RefMut};
@@ -177,9 +177,15 @@ impl<'tcx> QueryDescription for queries::coherent_trait<'tcx> {
177177
}
178178
}
179179

180-
impl<'tcx> QueryDescription for queries::coherent_inherent_impls<'tcx> {
180+
impl<'tcx> QueryDescription for queries::crate_inherent_impls<'tcx> {
181+
fn describe(_: TyCtxt, k: CrateNum) -> String {
182+
format!("all inherent impls defined in crate `{:?}`", k)
183+
}
184+
}
185+
186+
impl<'tcx> QueryDescription for queries::crate_inherent_impls_overlap_check<'tcx> {
181187
fn describe(_: TyCtxt, _: CrateNum) -> String {
182-
format!("coherence checking all inherent impls")
188+
format!("check for overlap between inherent impls defined in this crate")
183189
}
184190
}
185191

@@ -375,7 +381,7 @@ define_maps! { <'tcx>
375381
/// Maps a DefId of a type to a list of its inherent impls.
376382
/// Contains implementations of methods that are inherent to a type.
377383
/// Methods in these implementations don't need to be exported.
378-
pub inherent_impls: InherentImpls(DefId) -> Vec<DefId>,
384+
pub inherent_impls: InherentImpls(DefId) -> Rc<Vec<DefId>>,
379385

380386
/// Maps from the def-id of a function/method or const/static
381387
/// to its MIR. Mutation is done at an item granularity to
@@ -400,14 +406,22 @@ define_maps! { <'tcx>
400406
pub closure_type: ItemSignature(DefId) -> ty::PolyFnSig<'tcx>,
401407

402408
/// Caches CoerceUnsized kinds for impls on custom types.
403-
pub custom_coerce_unsized_kind: ItemSignature(DefId)
404-
-> ty::adjustment::CustomCoerceUnsized,
409+
pub coerce_unsized_info: ItemSignature(DefId)
410+
-> ty::adjustment::CoerceUnsizedInfo,
405411

406412
pub typeck_tables: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
407413

408414
pub coherent_trait: coherent_trait_dep_node((CrateNum, DefId)) -> (),
409415

410-
pub coherent_inherent_impls: coherent_inherent_impls_dep_node(CrateNum) -> (),
416+
/// Gets a complete map from all types to their inherent impls.
417+
/// Not meant to be used directly outside of coherence.
418+
/// (Defined only for LOCAL_CRATE)
419+
pub crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum) -> CrateInherentImpls,
420+
421+
/// Checks all types in the krate for overlap in their inherent impls. Reports errors.
422+
/// Not meant to be used directly outside of coherence.
423+
/// (Defined only for LOCAL_CRATE)
424+
pub crate_inherent_impls_overlap_check: crate_inherent_impls_dep_node(CrateNum) -> (),
411425

412426
/// Results of evaluating monomorphic constants embedded in
413427
/// other items, such as enum variant explicit discriminants.
@@ -423,7 +437,7 @@ fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
423437
DepNode::CoherenceCheckTrait(def_id)
424438
}
425439

426-
fn coherent_inherent_impls_dep_node(_: CrateNum) -> DepNode<DefId> {
440+
fn crate_inherent_impls_dep_node(_: CrateNum) -> DepNode<DefId> {
427441
DepNode::Coherence
428442
}
429443

‎src/librustc/ty/mod.rs

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use ty::subst::{Subst, Substs};
3131
use ty::util::IntTypeExt;
3232
use ty::walk::TypeWalker;
3333
use util::common::MemoizationMap;
34-
use util::nodemap::{NodeSet, FxHashMap};
34+
use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
3535

3636
use serialize::{self, Encodable, Encoder};
3737
use std::borrow::Cow;
@@ -2057,8 +2057,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
20572057
})
20582058
}
20592059

2060-
pub fn custom_coerce_unsized_kind(self, did: DefId) -> adjustment::CustomCoerceUnsized {
2061-
queries::custom_coerce_unsized_kind::get(self, DUMMY_SP, did)
2060+
pub fn coerce_unsized_info(self, did: DefId) -> adjustment::CoerceUnsizedInfo {
2061+
queries::coerce_unsized_info::get(self, DUMMY_SP, did)
20622062
}
20632063

20642064
pub fn associated_item(self, def_id: DefId) -> AssociatedItem {
@@ -2348,34 +2348,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
23482348
def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
23492349
}
23502350

2351-
/// Populates the type context with all the inherent implementations for
2352-
/// the given type if necessary.
2353-
pub fn populate_inherent_implementations_for_type_if_necessary(self,
2354-
span: Span,
2355-
type_id: DefId) {
2356-
if type_id.is_local() {
2357-
// Make sure coherence of inherent impls ran already.
2358-
ty::queries::coherent_inherent_impls::force(self, span, LOCAL_CRATE);
2359-
return
2360-
}
2361-
2362-
// The type is not local, hence we are reading this out of
2363-
// metadata and don't need to track edges.
2364-
let _ignore = self.dep_graph.in_ignore();
2365-
2366-
if self.populated_external_types.borrow().contains(&type_id) {
2367-
return
2368-
}
2369-
2370-
debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
2371-
type_id);
2372-
2373-
let inherent_impls = self.sess.cstore.inherent_implementations_for_type(type_id);
2374-
2375-
self.maps.inherent_impls.borrow_mut().insert(type_id, inherent_impls);
2376-
self.populated_external_types.borrow_mut().insert(type_id);
2377-
}
2378-
23792351
/// Populates the type context with all the implementations for the given
23802352
/// trait if necessary.
23812353
pub fn populate_implementations_for_trait_if_necessary(self, trait_id: DefId) {
@@ -2640,3 +2612,16 @@ pub fn provide(providers: &mut ty::maps::Providers) {
26402612
..*providers
26412613
};
26422614
}
2615+
2616+
2617+
/// A map for the local crate mapping each type to a vector of its
2618+
/// inherent impls. This is not meant to be used outside of coherence;
2619+
/// rather, you should request the vector for a specific type via
2620+
/// `ty::queries::inherent_impls::get(def_id)` so as to minimize your
2621+
/// dependencies (constructing this map requires touching the entire
2622+
/// crate).
2623+
#[derive(Clone, Debug)]
2624+
pub struct CrateInherentImpls {
2625+
pub inherent_impls: DefIdMap<Rc<Vec<DefId>>>,
2626+
}
2627+

‎src/librustc_metadata/cstore_impl.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ provide! { <'tcx> tcx, def_id, cdata
8888
}
8989
associated_item => { cdata.get_associated_item(def_id.index) }
9090
impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) }
91-
custom_coerce_unsized_kind => {
92-
cdata.get_custom_coerce_unsized_kind(def_id.index).unwrap_or_else(|| {
93-
bug!("custom_coerce_unsized_kind: `{:?}` is missing its kind", def_id);
91+
coerce_unsized_info => {
92+
cdata.get_coerce_unsized_info(def_id.index).unwrap_or_else(|| {
93+
bug!("coerce_unsized_info: `{:?}` is missing its info", def_id);
9494
})
9595
}
9696
mir => {
@@ -109,6 +109,7 @@ provide! { <'tcx> tcx, def_id, cdata
109109
typeck_tables => { cdata.item_body_tables(def_id.index, tcx) }
110110
closure_kind => { cdata.closure_kind(def_id.index) }
111111
closure_type => { cdata.closure_ty(def_id.index, tcx) }
112+
inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
112113
}
113114

114115
impl CrateStore for cstore::CStore {
@@ -162,12 +163,6 @@ impl CrateStore for cstore::CStore {
162163
self.get_crate_data(did.krate).get_fn_arg_names(did.index)
163164
}
164165

165-
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>
166-
{
167-
self.dep_graph.read(DepNode::MetaData(def_id));
168-
self.get_crate_data(def_id.krate).get_inherent_implementations_for_type(def_id.index)
169-
}
170-
171166
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
172167
{
173168
if let Some(def_id) = filter {

‎src/librustc_metadata/decoder.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -643,10 +643,10 @@ impl<'a, 'tcx> CrateMetadata {
643643
self.get_impl_data(id).polarity
644644
}
645645

646-
pub fn get_custom_coerce_unsized_kind(&self,
647-
id: DefIndex)
648-
-> Option<ty::adjustment::CustomCoerceUnsized> {
649-
self.get_impl_data(id).coerce_unsized_kind
646+
pub fn get_coerce_unsized_info(&self,
647+
id: DefIndex)
648+
-> Option<ty::adjustment::CoerceUnsizedInfo> {
649+
self.get_impl_data(id).coerce_unsized_info
650650
}
651651

652652
pub fn get_impl_trait(&self,

‎src/librustc_metadata/encoder.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
693693
let data = ImplData {
694694
polarity: hir::ImplPolarity::Positive,
695695
parent_impl: None,
696-
coerce_unsized_kind: None,
696+
coerce_unsized_info: None,
697697
trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref)),
698698
};
699699

@@ -713,13 +713,21 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
713713
None
714714
};
715715

716+
// if this is an impl of `CoerceUnsized`, create its
717+
// "unsized info", else just store None
718+
let coerce_unsized_info =
719+
trait_ref.and_then(|t| {
720+
if Some(t.def_id) == tcx.lang_items.coerce_unsized_trait() {
721+
Some(ty::queries::coerce_unsized_info::get(tcx, item.span, def_id))
722+
} else {
723+
None
724+
}
725+
});
726+
716727
let data = ImplData {
717728
polarity: polarity,
718729
parent_impl: parent,
719-
coerce_unsized_kind: tcx.maps.custom_coerce_unsized_kind
720-
.borrow()
721-
.get(&def_id)
722-
.cloned(),
730+
coerce_unsized_info: coerce_unsized_info,
723731
trait_ref: trait_ref.map(|trait_ref| self.lazy(&trait_ref)),
724732
};
725733

‎src/librustc_metadata/schema.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,9 @@ pub struct TraitData<'tcx> {
285285
pub struct ImplData<'tcx> {
286286
pub polarity: hir::ImplPolarity,
287287
pub parent_impl: Option<DefId>,
288-
pub coerce_unsized_kind: Option<ty::adjustment::CustomCoerceUnsized>,
288+
289+
/// This is `Some` only for impls of `CoerceUnsized`.
290+
pub coerce_unsized_info: Option<ty::adjustment::CoerceUnsizedInfo>,
289291
pub trait_ref: Option<Lazy<ty::TraitRef<'tcx>>>,
290292
}
291293

‎src/librustc_trans/monomorphize.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx
287287

288288
match fulfill_obligation(scx, DUMMY_SP, trait_ref) {
289289
traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => {
290-
scx.tcx().custom_coerce_unsized_kind(impl_def_id)
290+
scx.tcx().coerce_unsized_info(impl_def_id).custom_kind.unwrap()
291291
}
292292
vtable => {
293293
bug!("invalid CoerceUnsized vtable: {:?}", vtable);

‎src/librustc_typeck/check/method/probe.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -479,14 +479,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
479479
}
480480

481481
fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) {
482-
// Read the inherent implementation candidates for this type from the
483-
// metadata if necessary.
484-
self.tcx.populate_inherent_implementations_for_type_if_necessary(self.span, def_id);
485-
486-
if let Some(impl_infos) = self.tcx.maps.inherent_impls.borrow().get(&def_id) {
487-
for &impl_def_id in impl_infos.iter() {
488-
self.assemble_inherent_impl_probe(impl_def_id);
489-
}
482+
let impl_def_ids = ty::queries::inherent_impls::get(self.tcx, self.span, def_id);
483+
for &impl_def_id in impl_def_ids.iter() {
484+
self.assemble_inherent_impl_probe(impl_def_id);
490485
}
491486
}
492487

0 commit comments

Comments
 (0)
Please sign in to comment.