Skip to content

Commit aecf3d8

Browse files
committed
Auto merge of #24965 - arielb1:instant-reject, r=nikomatsakis
This uses a (per-trait) hash-table to separate impls from different TraitDefs, and makes coherence go so much quicker. I will post performance numbers tomorrow. This is still WIP, as when there's an overlap error, impls can get printed in the wrong order, which causes a few issues. Should I pick the local impl with the smallest NodeId to print? Could you take a look at this @nikomatsakis?
2 parents 5c710b5 + 30a5448 commit aecf3d8

34 files changed

+431
-335
lines changed

src/librustc/metadata/csearch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
283283
// if there is one.
284284
pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
285285
def: ast::DefId)
286-
-> Option<Rc<ty::TraitRef<'tcx>>> {
286+
-> Option<ty::TraitRef<'tcx>> {
287287
let cstore = &tcx.sess.cstore;
288288
let cdata = cstore.get_crate_data(def.krate);
289289
decoder::get_impl_trait(&*cdata, def.node, tcx)

src/librustc/metadata/decoder.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ use middle::subst;
3030
use middle::ty::{ImplContainer, TraitContainer};
3131
use middle::ty::{self, Ty};
3232
use middle::astencode::vtable_decoder_helpers;
33+
use util::nodemap::FnvHashMap;
3334

35+
use std::cell::{Cell, RefCell};
3436
use std::collections::HashMap;
3537
use std::hash::{self, Hash, SipHasher};
3638
use std::io::prelude::*;
@@ -247,13 +249,13 @@ pub fn item_type<'tcx>(_item_id: ast::DefId, item: rbml::Doc,
247249
}
248250

249251
fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
250-
-> Rc<ty::TraitRef<'tcx>> {
252+
-> ty::TraitRef<'tcx> {
251253
parse_trait_ref_data(doc.data, cdata.cnum, doc.start, tcx,
252254
|_, did| translate_def_id(cdata, did))
253255
}
254256

255257
fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
256-
-> Rc<ty::TraitRef<'tcx>> {
258+
-> ty::TraitRef<'tcx> {
257259
let tp = reader::get_doc(doc, tag_item_trait_ref);
258260
doc_trait_ref(tp, tcx, cdata)
259261
}
@@ -420,6 +422,9 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
420422
generics: generics,
421423
trait_ref: item_trait_ref(item_doc, tcx, cdata),
422424
associated_type_names: associated_type_names,
425+
nonblanket_impls: RefCell::new(FnvHashMap()),
426+
blanket_impls: RefCell::new(vec![]),
427+
flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
423428
}
424429
}
425430

@@ -490,7 +495,7 @@ pub fn get_impl_polarity<'tcx>(cdata: Cmd,
490495
pub fn get_impl_trait<'tcx>(cdata: Cmd,
491496
id: ast::NodeId,
492497
tcx: &ty::ctxt<'tcx>)
493-
-> Option<Rc<ty::TraitRef<'tcx>>>
498+
-> Option<ty::TraitRef<'tcx>>
494499
{
495500
let item_doc = lookup_item(id, cdata.data());
496501
let fam = item_family(item_doc);

src/librustc/metadata/encoder.rs

+13-15
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ struct entry<T> {
103103

104104
fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder,
105105
ecx: &EncodeContext<'a, 'tcx>,
106-
trait_ref: &ty::TraitRef<'tcx>,
106+
trait_ref: ty::TraitRef<'tcx>,
107107
tag: usize) {
108108
let ty_str_ctxt = &tyencode::ctxt {
109109
diag: ecx.diag,
@@ -191,7 +191,7 @@ pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
191191
tcx: ecx.tcx,
192192
abbrevs: &ecx.type_abbrevs
193193
};
194-
tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
194+
tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, *trait_ref);
195195
}
196196

197197
pub fn write_region(ecx: &EncodeContext,
@@ -974,16 +974,14 @@ fn encode_inherent_implementations(ecx: &EncodeContext,
974974
fn encode_extension_implementations(ecx: &EncodeContext,
975975
rbml_w: &mut Encoder,
976976
trait_def_id: DefId) {
977-
match ecx.tcx.trait_impls.borrow().get(&trait_def_id) {
978-
None => {}
979-
Some(implementations) => {
980-
for &impl_def_id in &*implementations.borrow() {
981-
rbml_w.start_tag(tag_items_data_item_extension_impl);
982-
encode_def_id(rbml_w, impl_def_id);
983-
rbml_w.end_tag();
984-
}
985-
}
986-
}
977+
assert!(ast_util::is_local(trait_def_id));
978+
let def = ty::lookup_trait_def(ecx.tcx, trait_def_id);
979+
980+
def.for_each_impl(ecx.tcx, |impl_def_id| {
981+
rbml_w.start_tag(tag_items_data_item_extension_impl);
982+
encode_def_id(rbml_w, impl_def_id);
983+
rbml_w.end_tag();
984+
});
987985
}
988986

989987
fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<attr::Stability>) {
@@ -1201,7 +1199,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
12011199
encode_unsafety(rbml_w, unsafety);
12021200

12031201
let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
1204-
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
1202+
encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
12051203
rbml_w.end_tag();
12061204
}
12071205
ast::ItemImpl(unsafety, polarity, _, ref opt_trait, ref ty, ref ast_items) => {
@@ -1246,7 +1244,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
12461244
}
12471245
if opt_trait.is_some() {
12481246
let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
1249-
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
1247+
encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
12501248
}
12511249
encode_path(rbml_w, path.clone());
12521250
encode_stability(rbml_w, stab);
@@ -1314,7 +1312,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
13141312
tag_item_generics);
13151313
encode_predicates(rbml_w, ecx, &ty::lookup_super_predicates(tcx, def_id),
13161314
tag_item_super_predicates);
1317-
encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
1315+
encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
13181316
encode_name(rbml_w, item.ident.name);
13191317
encode_attributes(rbml_w, &item.attrs);
13201318
encode_visibility(rbml_w, vis);

src/librustc/metadata/tydecode.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use middle::subst;
2323
use middle::subst::VecPerParamSpace;
2424
use middle::ty::{self, AsPredicate, Ty};
2525

26-
use std::rc::Rc;
2726
use std::str;
2827
use syntax::abi;
2928
use syntax::ast;
@@ -182,7 +181,7 @@ pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos
182181

183182
pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize,
184183
tcx: &ty::ctxt<'tcx>, conv: F)
185-
-> Rc<ty::TraitRef<'tcx>> where
184+
-> ty::TraitRef<'tcx> where
186185
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
187186
{
188187
debug!("parse_trait_ref_data {}", data_log_string(data, pos));
@@ -434,19 +433,19 @@ fn parse_str(st: &mut PState, term: char) -> String {
434433
}
435434

436435
fn parse_trait_ref<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
437-
-> Rc<ty::TraitRef<'tcx>> where
436+
-> ty::TraitRef<'tcx> where
438437
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
439438
{
440439
parse_trait_ref_(st, &mut conv)
441440
}
442441

443442
fn parse_trait_ref_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
444-
-> Rc<ty::TraitRef<'tcx>> where
443+
-> ty::TraitRef<'tcx> where
445444
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
446445
{
447446
let def = parse_def_(st, NominalType, conv);
448447
let substs = st.tcx.mk_substs(parse_substs_(st, conv));
449-
Rc::new(ty::TraitRef {def_id: def, substs: substs})
448+
ty::TraitRef {def_id: def, substs: substs}
450449
}
451450

452451
fn parse_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F) -> Ty<'tcx> where

src/librustc/metadata/tyencode.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
9494
ty::ty_trait(box ty::TyTrait { ref principal,
9595
ref bounds }) => {
9696
mywrite!(w, "x[");
97-
enc_trait_ref(w, cx, &*principal.0);
97+
enc_trait_ref(w, cx, principal.0);
9898
enc_existential_bounds(w, cx, bounds);
9999
mywrite!(w, "]");
100100
}
@@ -149,7 +149,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
149149
}
150150
ty::ty_projection(ref data) => {
151151
mywrite!(w, "P[");
152-
enc_trait_ref(w, cx, &*data.trait_ref);
152+
enc_trait_ref(w, cx, data.trait_ref);
153153
mywrite!(w, "{}]", token::get_name(data.item_name));
154154
}
155155
ty::ty_err => {
@@ -309,7 +309,7 @@ fn enc_bound_region(w: &mut Encoder, cx: &ctxt, br: ty::BoundRegion) {
309309
}
310310

311311
pub fn enc_trait_ref<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
312-
s: &ty::TraitRef<'tcx>) {
312+
s: ty::TraitRef<'tcx>) {
313313
mywrite!(w, "{}|", (cx.ds)(s.def_id));
314314
enc_substs(w, cx, s.substs);
315315
}
@@ -394,7 +394,7 @@ pub fn enc_bounds<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
394394

395395
for tp in &bs.trait_bounds {
396396
mywrite!(w, "I");
397-
enc_trait_ref(w, cx, &*tp.0);
397+
enc_trait_ref(w, cx, tp.0);
398398
}
399399

400400
for tp in &bs.projection_bounds {
@@ -446,7 +446,7 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut Encoder,
446446
match *p {
447447
ty::Predicate::Trait(ref trait_ref) => {
448448
mywrite!(w, "t");
449-
enc_trait_ref(w, cx, &*trait_ref.0.trait_ref);
449+
enc_trait_ref(w, cx, trait_ref.0.trait_ref);
450450
}
451451
ty::Predicate::Equate(ty::Binder(ty::EquatePredicate(a, b))) => {
452452
mywrite!(w, "e");
@@ -473,7 +473,7 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut Encoder,
473473
fn enc_projection_predicate<'a, 'tcx>(w: &mut Encoder,
474474
cx: &ctxt<'a, 'tcx>,
475475
data: &ty::ProjectionPredicate<'tcx>) {
476-
enc_trait_ref(w, cx, &*data.projection_ty.trait_ref);
476+
enc_trait_ref(w, cx, data.projection_ty.trait_ref);
477477
mywrite!(w, "{}|", token::get_name(data.projection_ty.item_name));
478478
enc_ty(w, cx, data.ty);
479479
}

src/librustc/middle/astencode.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ use syntax;
4141
use std::cell::Cell;
4242
use std::io::SeekFrom;
4343
use std::io::prelude::*;
44-
use std::rc::Rc;
4544
use std::fmt::Debug;
4645

4746
use rbml::reader;
@@ -890,7 +889,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
890889
this.emit_enum_variant("MethodTypeParam", 2, 1, |this| {
891890
this.emit_struct("MethodParam", 2, |this| {
892891
try!(this.emit_struct_field("trait_ref", 0, |this| {
893-
Ok(this.emit_trait_ref(ecx, &*p.trait_ref))
892+
Ok(this.emit_trait_ref(ecx, &p.trait_ref))
894893
}));
895894
try!(this.emit_struct_field("method_num", 0, |this| {
896895
this.emit_uint(p.method_num)
@@ -914,7 +913,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
914913
this.emit_enum_variant("MethodTraitObject", 3, 1, |this| {
915914
this.emit_struct("MethodObject", 2, |this| {
916915
try!(this.emit_struct_field("trait_ref", 0, |this| {
917-
Ok(this.emit_trait_ref(ecx, &*o.trait_ref))
916+
Ok(this.emit_trait_ref(ecx, &o.trait_ref))
918917
}));
919918
try!(this.emit_struct_field("object_trait_id", 0, |this| {
920919
Ok(this.emit_def_id(o.object_trait_id))
@@ -1208,7 +1207,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
12081207
if let Some(trait_ref) = tcx.object_cast_map.borrow().get(&id) {
12091208
rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| {
12101209
rbml_w.id(id);
1211-
rbml_w.emit_trait_ref(ecx, &*trait_ref.0);
1210+
rbml_w.emit_trait_ref(ecx, &trait_ref.0);
12121211
})
12131212
}
12141213

@@ -1275,7 +1274,7 @@ trait rbml_decoder_decoder_helpers<'tcx> {
12751274
fn read_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Ty<'tcx>;
12761275
fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec<Ty<'tcx>>;
12771276
fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1278-
-> Rc<ty::TraitRef<'tcx>>;
1277+
-> ty::TraitRef<'tcx>;
12791278
fn read_poly_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
12801279
-> ty::PolyTraitRef<'tcx>;
12811280
fn read_type_param_def<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@@ -1469,7 +1468,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
14691468
}
14701469

14711470
fn read_trait_ref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1472-
-> Rc<ty::TraitRef<'tcx>> {
1471+
-> ty::TraitRef<'tcx> {
14731472
self.read_opaque(|this, doc| {
14741473
let ty = tydecode::parse_trait_ref_data(
14751474
doc.data,

src/librustc/middle/const_eval.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -942,8 +942,8 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
942942
let trait_substs = tcx.mk_substs(trait_substs);
943943
debug!("resolve_trait_associated_const: trait_substs={}",
944944
trait_substs.repr(tcx));
945-
let trait_ref = ty::Binder(Rc::new(ty::TraitRef { def_id: trait_id,
946-
substs: trait_substs }));
945+
let trait_ref = ty::Binder(ty::TraitRef { def_id: trait_id,
946+
substs: trait_substs });
947947

948948
ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id());
949949
let infcx = infer::new_infer_ctxt(tcx);

src/librustc/middle/implicator.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use middle::traits;
1616
use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
1717
use middle::ty_fold::{TypeFoldable, TypeFolder};
1818

19-
use std::rc::Rc;
2019
use syntax::ast;
2120
use syntax::codemap::Span;
2221

@@ -324,7 +323,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
324323
}
325324

326325
fn accumulate_from_assoc_types(&mut self,
327-
trait_ref: Rc<ty::TraitRef<'tcx>>)
326+
trait_ref: ty::TraitRef<'tcx>)
328327
{
329328
debug!("accumulate_from_assoc_types({})",
330329
trait_ref.repr(self.tcx()));
@@ -442,7 +441,7 @@ pub fn object_region_bounds<'tcx>(
442441
// Note that we preserve the overall binding levels here.
443442
assert!(!open_ty.has_escaping_regions());
444443
let substs = tcx.mk_substs(principal.0.substs.with_self_ty(open_ty));
445-
let trait_refs = vec!(ty::Binder(Rc::new(ty::TraitRef::new(principal.0.def_id, substs))));
444+
let trait_refs = vec!(ty::Binder(ty::TraitRef::new(principal.0.def_id, substs)));
446445

447446
let param_bounds = ty::ParamBounds {
448447
region_bounds: Vec::new(),

src/librustc/middle/infer/error_reporting.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ use middle::ty::{self, Ty};
7979
use middle::ty::{Region, ReFree};
8080
use std::cell::{Cell, RefCell};
8181
use std::char::from_u32;
82-
use std::rc::Rc;
8382
use std::string::String;
8483
use syntax::ast;
8584
use syntax::ast_map;
@@ -1680,13 +1679,13 @@ impl<'tcx> Resolvable<'tcx> for Ty<'tcx> {
16801679
}
16811680
}
16821681

1683-
impl<'tcx> Resolvable<'tcx> for Rc<ty::TraitRef<'tcx>> {
1682+
impl<'tcx> Resolvable<'tcx> for ty::TraitRef<'tcx> {
16841683
fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>)
1685-
-> Rc<ty::TraitRef<'tcx>> {
1686-
Rc::new(infcx.resolve_type_vars_if_possible(&**self))
1684+
-> ty::TraitRef<'tcx> {
1685+
infcx.resolve_type_vars_if_possible(self)
16871686
}
16881687
fn contains_error(&self) -> bool {
1689-
ty::trait_ref_contains_error(&**self)
1688+
ty::trait_ref_contains_error(self)
16901689
}
16911690
}
16921691

@@ -1699,7 +1698,7 @@ impl<'tcx> Resolvable<'tcx> for ty::PolyTraitRef<'tcx> {
16991698
}
17001699

17011700
fn contains_error(&self) -> bool {
1702-
ty::trait_ref_contains_error(&*self.0)
1701+
ty::trait_ref_contains_error(&self.0)
17031702
}
17041703
}
17051704

src/librustc/middle/infer/mod.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use middle::ty_relate::{Relate, RelateResult, TypeRelation};
3333
use rustc_data_structures::unify::{self, UnificationTable};
3434
use std::cell::{RefCell};
3535
use std::fmt;
36-
use std::rc::Rc;
3736
use syntax::ast;
3837
use syntax::codemap;
3938
use syntax::codemap::Span;
@@ -155,7 +154,7 @@ impl fmt::Display for TypeOrigin {
155154
#[derive(Clone, Debug)]
156155
pub enum ValuePairs<'tcx> {
157156
Types(ty::expected_found<Ty<'tcx>>),
158-
TraitRefs(ty::expected_found<Rc<ty::TraitRef<'tcx>>>),
157+
TraitRefs(ty::expected_found<ty::TraitRef<'tcx>>),
159158
PolyTraitRefs(ty::expected_found<ty::PolyTraitRef<'tcx>>),
160159
}
161160

@@ -663,8 +662,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
663662
pub fn sub_trait_refs(&self,
664663
a_is_expected: bool,
665664
origin: TypeOrigin,
666-
a: Rc<ty::TraitRef<'tcx>>,
667-
b: Rc<ty::TraitRef<'tcx>>)
665+
a: ty::TraitRef<'tcx>,
666+
b: ty::TraitRef<'tcx>)
668667
-> UnitResult<'tcx>
669668
{
670669
debug!("sub_trait_refs({} <: {})",
@@ -675,7 +674,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
675674
origin: origin,
676675
values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
677676
};
678-
self.sub(a_is_expected, trace).relate(&*a, &*b).map(|_| ())
677+
self.sub(a_is_expected, trace).relate(&a, &b).map(|_| ())
679678
})
680679
}
681680

@@ -873,8 +872,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
873872
format!("({})", tstrs.connect(", "))
874873
}
875874

876-
pub fn trait_ref_to_string(&self, t: &Rc<ty::TraitRef<'tcx>>) -> String {
877-
let t = self.resolve_type_vars_if_possible(&**t);
875+
pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
876+
let t = self.resolve_type_vars_if_possible(t);
878877
t.user_string(self.tcx)
879878
}
880879

0 commit comments

Comments
 (0)