Skip to content

Commit 39b463f

Browse files
committed
Auto merge of #22182 - nikomatsakis:cycles-in-collect, r=nikomatsakis
This resolves a number of bugs that trigger stack overflows or other cyclic errors. r? @nick29581 (it is based on work that you started) f? @jroesch (also based on your branch)
2 parents cca1cf6 + a25ed22 commit 39b463f

32 files changed

+1073
-626
lines changed

src/librustc/metadata/csearch.rs

+8
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,14 @@ pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) -> ty::TraitDe
233233
decoder::get_trait_def(&*cdata, def.node, tcx)
234234
}
235235

236+
pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
237+
-> ty::GenericPredicates<'tcx>
238+
{
239+
let cstore = &tcx.sess.cstore;
240+
let cdata = cstore.get_crate_data(def.krate);
241+
decoder::get_predicates(&*cdata, def.node, tcx)
242+
}
243+
236244
pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
237245
def: ast::DefId) -> ty::TypeScheme<'tcx> {
238246
let cstore = &tcx.sess.cstore;

src/librustc/metadata/decoder.rs

+29-11
Original file line numberDiff line numberDiff line change
@@ -417,16 +417,22 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
417417
}
418418
}
419419

420-
pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
421-
-> ty::TypeScheme<'tcx> {
422-
423-
let item = lookup_item(id, cdata.data());
420+
pub fn get_predicates<'tcx>(cdata: Cmd,
421+
item_id: ast::NodeId,
422+
tcx: &ty::ctxt<'tcx>)
423+
-> ty::GenericPredicates<'tcx>
424+
{
425+
let item_doc = lookup_item(item_id, cdata.data());
426+
doc_predicates(item_doc, tcx, cdata, tag_item_generics)
427+
}
424428

425-
let t = item_type(ast::DefId { krate: cdata.cnum, node: id }, item, tcx,
429+
pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
430+
-> ty::TypeScheme<'tcx>
431+
{
432+
let item_doc = lookup_item(id, cdata.data());
433+
let t = item_type(ast::DefId { krate: cdata.cnum, node: id }, item_doc, tcx,
426434
cdata);
427-
428-
let generics = doc_generics(item, tcx, cdata, tag_item_generics);
429-
435+
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
430436
ty::TypeScheme {
431437
generics: generics,
432438
ty: t
@@ -882,14 +888,15 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
882888

883889
match item_sort(method_doc) {
884890
'r' | 'p' => {
885-
let generics = doc_generics(method_doc, tcx, cdata,
886-
tag_method_ty_generics);
891+
let generics = doc_generics(method_doc, tcx, cdata, tag_method_ty_generics);
892+
let predicates = doc_predicates(method_doc, tcx, cdata, tag_method_ty_generics);
887893
let fty = doc_method_fty(method_doc, tcx, cdata);
888894
let explicit_self = get_explicit_self(method_doc);
889895
let provided_source = get_provided_source(method_doc, cdata);
890896

891897
ty::MethodTraitItem(Rc::new(ty::Method::new(name,
892898
generics,
899+
predicates,
893900
fty,
894901
explicit_self,
895902
vis,
@@ -1520,6 +1527,17 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
15201527
true
15211528
});
15221529

1530+
ty::Generics { types: types, regions: regions }
1531+
}
1532+
1533+
fn doc_predicates<'tcx>(base_doc: rbml::Doc,
1534+
tcx: &ty::ctxt<'tcx>,
1535+
cdata: Cmd,
1536+
tag: uint)
1537+
-> ty::GenericPredicates<'tcx>
1538+
{
1539+
let doc = reader::get_doc(base_doc, tag);
1540+
15231541
let mut predicates = subst::VecPerParamSpace::empty();
15241542
reader::tagged_docs(doc, tag_predicate, |predicate_doc| {
15251543
let space_doc = reader::get_doc(predicate_doc, tag_predicate_space);
@@ -1533,7 +1551,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
15331551
true
15341552
});
15351553

1536-
ty::Generics { types: types, regions: regions, predicates: predicates }
1554+
ty::GenericPredicates { predicates: predicates }
15371555
}
15381556

15391557
pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {

src/librustc/metadata/encoder.rs

+36-33
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,21 @@ fn encode_item_variances(rbml_w: &mut Encoder,
139139
rbml_w.end_tag();
140140
}
141141

142+
fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder,
143+
ecx: &EncodeContext<'a, 'tcx>,
144+
id: ast::NodeId) {
145+
encode_bounds_and_type(rbml_w,
146+
ecx,
147+
&ty::lookup_item_type(ecx.tcx, local_def(id)),
148+
&ty::lookup_predicates(ecx.tcx, local_def(id)));
149+
}
150+
142151
fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder,
143152
ecx: &EncodeContext<'a, 'tcx>,
144-
pty: &ty::TypeScheme<'tcx>) {
145-
encode_generics(rbml_w, ecx, &pty.generics, tag_item_generics);
146-
encode_type(ecx, rbml_w, pty.ty);
153+
scheme: &ty::TypeScheme<'tcx>,
154+
predicates: &ty::GenericPredicates<'tcx>) {
155+
encode_generics(rbml_w, ecx, &scheme.generics, &predicates, tag_item_generics);
156+
encode_type(ecx, rbml_w, scheme.ty);
147157
}
148158

149159
fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) {
@@ -353,8 +363,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
353363
encode_disr_val(ecx, rbml_w, (*vi)[i].disr_val);
354364
disr_val = (*vi)[i].disr_val;
355365
}
356-
encode_bounds_and_type(rbml_w, ecx,
357-
&lookup_item_type(ecx.tcx, def_id));
366+
encode_bounds_and_type_for_item(rbml_w, ecx, def_id.local_id());
358367

359368
ecx.tcx.map.with_path(variant.node.id, |path| encode_path(rbml_w, path));
360369
rbml_w.end_tag();
@@ -698,8 +707,7 @@ fn encode_info_for_struct(ecx: &EncodeContext,
698707
token::get_name(nm), id);
699708
encode_struct_field_family(rbml_w, field.vis);
700709
encode_name(rbml_w, nm);
701-
encode_bounds_and_type(rbml_w, ecx,
702-
&lookup_item_type(ecx.tcx, local_def(id)));
710+
encode_bounds_and_type_for_item(rbml_w, ecx, id);
703711
encode_def_id(rbml_w, local_def(id));
704712

705713
let stab = stability::lookup(ecx.tcx, field.id);
@@ -724,8 +732,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
724732
rbml_w.start_tag(tag_items_data_item);
725733
encode_def_id(rbml_w, local_def(ctor_id));
726734
encode_family(rbml_w, 'o');
727-
encode_bounds_and_type(rbml_w, ecx,
728-
&lookup_item_type(ecx.tcx, local_def(ctor_id)));
735+
encode_bounds_and_type_for_item(rbml_w, ecx, ctor_id);
729736
encode_name(rbml_w, name.name);
730737
ecx.tcx.map.with_path(ctor_id, |path| encode_path(rbml_w, path));
731738
encode_parent_item(rbml_w, local_def(struct_id));
@@ -749,6 +756,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
749756
fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
750757
ecx: &EncodeContext<'a, 'tcx>,
751758
generics: &ty::Generics<'tcx>,
759+
predicates: &ty::GenericPredicates<'tcx>,
752760
tag: uint)
753761
{
754762
rbml_w.start_tag(tag);
@@ -790,7 +798,7 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
790798
rbml_w.end_tag();
791799
}
792800

793-
for (space, _, predicate) in generics.predicates.iter_enumerated() {
801+
for (space, _, predicate) in predicates.predicates.iter_enumerated() {
794802
rbml_w.start_tag(tag_predicate);
795803

796804
rbml_w.wr_tagged_u8(tag_predicate_space, space as u8);
@@ -810,7 +818,7 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
810818
method_ty: &ty::Method<'tcx>) {
811819
encode_def_id(rbml_w, method_ty.def_id);
812820
encode_name(rbml_w, method_ty.name);
813-
encode_generics(rbml_w, ecx, &method_ty.generics,
821+
encode_generics(rbml_w, ecx, &method_ty.generics, &method_ty.predicates,
814822
tag_method_ty_generics);
815823
encode_method_fty(ecx, rbml_w, &method_ty.fty);
816824
encode_visibility(rbml_w, method_ty.vis);
@@ -844,15 +852,15 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
844852
encode_stability(rbml_w, stab);
845853

846854
// The type for methods gets encoded twice, which is unfortunate.
847-
let pty = lookup_item_type(ecx.tcx, m.def_id);
848-
encode_bounds_and_type(rbml_w, ecx, &pty);
855+
encode_bounds_and_type_for_item(rbml_w, ecx, m.def_id.local_id());
849856

850857
let elem = ast_map::PathName(m.name);
851858
encode_path(rbml_w, impl_path.chain(Some(elem).into_iter()));
852859
match ast_item_opt {
853860
Some(&ast::MethodImplItem(ref ast_method)) => {
854861
encode_attributes(rbml_w, &ast_method.attrs[]);
855-
let any_types = !pty.generics.types.is_empty();
862+
let scheme = ty::lookup_item_type(ecx.tcx, m.def_id);
863+
let any_types = !scheme.generics.types.is_empty();
856864
if any_types || is_default_impl || should_inline(&ast_method.attrs[]) {
857865
encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id),
858866
ast_item_opt.unwrap()));
@@ -887,8 +895,7 @@ fn encode_info_for_associated_type(ecx: &EncodeContext,
887895
encode_parent_item(rbml_w, local_def(parent_id));
888896
encode_item_sort(rbml_w, 't');
889897

890-
let type_scheme = ty::lookup_item_type(ecx.tcx, associated_type.def_id);
891-
encode_bounds_and_type(rbml_w, ecx, &type_scheme);
898+
encode_bounds_and_type_for_item(rbml_w, ecx, associated_type.def_id.local_id());
892899

893900
let stab = stability::lookup(ecx.tcx, associated_type.def_id);
894901
encode_stability(rbml_w, stab);
@@ -1027,7 +1034,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
10271034
} else {
10281035
encode_family(rbml_w, 'c');
10291036
}
1030-
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
1037+
encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
10311038
encode_symbol(ecx, rbml_w, item.id);
10321039
encode_name(rbml_w, item.ident.name);
10331040
encode_path(rbml_w, path);
@@ -1041,7 +1048,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
10411048
rbml_w.start_tag(tag_items_data_item);
10421049
encode_def_id(rbml_w, def_id);
10431050
encode_family(rbml_w, 'C');
1044-
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
1051+
encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
10451052
encode_name(rbml_w, item.ident.name);
10461053
encode_path(rbml_w, path);
10471054
encode_attributes(rbml_w, &item.attrs);
@@ -1056,7 +1063,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
10561063
encode_def_id(rbml_w, def_id);
10571064
encode_family(rbml_w, FN_FAMILY);
10581065
let tps_len = generics.ty_params.len();
1059-
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
1066+
encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
10601067
encode_name(rbml_w, item.ident.name);
10611068
encode_path(rbml_w, path);
10621069
encode_attributes(rbml_w, &item.attrs[]);
@@ -1105,7 +1112,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
11051112
rbml_w.start_tag(tag_items_data_item);
11061113
encode_def_id(rbml_w, def_id);
11071114
encode_family(rbml_w, 'y');
1108-
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
1115+
encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
11091116
encode_name(rbml_w, item.ident.name);
11101117
encode_path(rbml_w, path);
11111118
encode_visibility(rbml_w, vis);
@@ -1119,7 +1126,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
11191126
encode_def_id(rbml_w, def_id);
11201127
encode_family(rbml_w, 't');
11211128
encode_item_variances(rbml_w, ecx, item.id);
1122-
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
1129+
encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
11231130
encode_name(rbml_w, item.ident.name);
11241131
encode_attributes(rbml_w, &item.attrs[]);
11251132
encode_repr_attrs(rbml_w, ecx, &item.attrs[]);
@@ -1161,7 +1168,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
11611168
rbml_w.start_tag(tag_items_data_item);
11621169
encode_def_id(rbml_w, def_id);
11631170
encode_family(rbml_w, 'S');
1164-
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
1171+
encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
11651172

11661173
encode_item_variances(rbml_w, ecx, item.id);
11671174
encode_name(rbml_w, item.ident.name);
@@ -1204,7 +1211,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
12041211
rbml_w.start_tag(tag_items_data_item);
12051212
encode_def_id(rbml_w, def_id);
12061213
encode_family(rbml_w, 'i');
1207-
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
1214+
encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
12081215
encode_name(rbml_w, item.ident.name);
12091216
encode_attributes(rbml_w, &item.attrs[]);
12101217
encode_unsafety(rbml_w, unsafety);
@@ -1305,10 +1312,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
13051312
encode_family(rbml_w, 'I');
13061313
encode_item_variances(rbml_w, ecx, item.id);
13071314
let trait_def = ty::lookup_trait_def(tcx, def_id);
1315+
let trait_predicates = ty::lookup_predicates(tcx, def_id);
13081316
encode_unsafety(rbml_w, trait_def.unsafety);
13091317
encode_paren_sugar(rbml_w, trait_def.paren_sugar);
13101318
encode_associated_type_names(rbml_w, &trait_def.associated_type_names);
1311-
encode_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics);
1319+
encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates, tag_item_generics);
13121320
encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
13131321
encode_name(rbml_w, item.ident.name);
13141322
encode_attributes(rbml_w, &item.attrs[]);
@@ -1384,9 +1392,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
13841392
METHOD_FAMILY);
13851393
}
13861394
}
1387-
let pty = ty::lookup_item_type(tcx,
1388-
method_def_id);
1389-
encode_bounds_and_type(rbml_w, ecx, &pty);
1395+
encode_bounds_and_type_for_item(rbml_w, ecx, method_def_id.local_id());
13901396

13911397
is_nonstatic_method = method_ty.explicit_self !=
13921398
ty::StaticExplicitSelfCategory;
@@ -1415,8 +1421,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
14151421
if is_nonstatic_method {
14161422
// FIXME: I feel like there is something funny
14171423
// going on.
1418-
let pty = ty::lookup_item_type(tcx, item_def_id.def_id());
1419-
encode_bounds_and_type(rbml_w, ecx, &pty);
1424+
encode_bounds_and_type_for_item(rbml_w, ecx, item_def_id.def_id().local_id());
14201425
}
14211426
};
14221427
match trait_item {
@@ -1468,8 +1473,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
14681473
match nitem.node {
14691474
ast::ForeignItemFn(ref fndecl, _) => {
14701475
encode_family(rbml_w, FN_FAMILY);
1471-
encode_bounds_and_type(rbml_w, ecx,
1472-
&lookup_item_type(ecx.tcx,local_def(nitem.id)));
1476+
encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id);
14731477
encode_name(rbml_w, nitem.ident.name);
14741478
if abi == abi::RustIntrinsic {
14751479
encode_inlined_item(ecx, rbml_w, IIForeignRef(nitem));
@@ -1486,8 +1490,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
14861490
} else {
14871491
encode_family(rbml_w, 'c');
14881492
}
1489-
encode_bounds_and_type(rbml_w, ecx,
1490-
&lookup_item_type(ecx.tcx,local_def(nitem.id)));
1493+
encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id);
14911494
encode_attributes(rbml_w, &*nitem.attrs);
14921495
let stab = stability::lookup(ecx.tcx, ast_util::local_def(nitem.id));
14931496
encode_stability(rbml_w, stab);

src/librustc/middle/astencode.rs

+1-12
Original file line numberDiff line numberDiff line change
@@ -951,11 +951,6 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
951951
Ok(encode_vec_per_param_space(
952952
this, &type_scheme.generics.regions,
953953
|this, def| def.encode(this).unwrap()))
954-
});
955-
this.emit_struct_field("predicates", 2, |this| {
956-
Ok(encode_vec_per_param_space(
957-
this, &type_scheme.generics.predicates,
958-
|this, def| this.emit_predicate(ecx, def)))
959954
})
960955
})
961956
});
@@ -1574,7 +1569,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
15741569

15751570
fn read_type_scheme<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
15761571
-> ty::TypeScheme<'tcx> {
1577-
self.read_struct("TypeScheme", 2, |this| {
1572+
self.read_struct("TypeScheme", 3, |this| {
15781573
Ok(ty::TypeScheme {
15791574
generics: this.read_struct_field("generics", 0, |this| {
15801575
this.read_struct("Generics", 2, |this| {
@@ -1590,12 +1585,6 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
15901585
Ok(this.read_vec_per_param_space(
15911586
|this| Decodable::decode(this).unwrap()))
15921587
}).unwrap(),
1593-
1594-
predicates:
1595-
this.read_struct_field("predicates", 2, |this| {
1596-
Ok(this.read_vec_per_param_space(
1597-
|this| this.read_predicate(dcx)))
1598-
}).unwrap(),
15991588
})
16001589
})
16011590
}).unwrap(),

src/librustc/middle/subst.rs

+18
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use middle::ty_fold::{self, TypeFoldable, TypeFolder};
1818
use util::ppaux::Repr;
1919

2020
use std::fmt;
21+
use std::iter::IntoIterator;
2122
use std::slice::Iter;
2223
use std::vec::{Vec, IntoIter};
2324
use syntax::codemap::{Span, DUMMY_SP};
@@ -529,6 +530,23 @@ impl<'a,T> Iterator for EnumeratedItems<'a,T> {
529530
}
530531
}
531532

533+
impl<T> IntoIterator for VecPerParamSpace<T> {
534+
type IntoIter = IntoIter<T>;
535+
536+
fn into_iter(self) -> IntoIter<T> {
537+
self.into_vec().into_iter()
538+
}
539+
}
540+
541+
impl<'a,T> IntoIterator for &'a VecPerParamSpace<T> {
542+
type IntoIter = Iter<'a, T>;
543+
544+
fn into_iter(self) -> Iter<'a, T> {
545+
self.as_slice().into_iter()
546+
}
547+
}
548+
549+
532550
///////////////////////////////////////////////////////////////////////////
533551
// Public trait `Subst`
534552
//

src/librustc/middle/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ pub fn overlapping_impls(infcx: &InferCtxt,
283283
/// Creates predicate obligations from the generic bounds.
284284
pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
285285
cause: ObligationCause<'tcx>,
286-
generic_bounds: &ty::GenericBounds<'tcx>)
286+
generic_bounds: &ty::InstantiatedPredicates<'tcx>)
287287
-> PredicateObligations<'tcx>
288288
{
289289
util::predicates_for_generics(tcx, cause, 0, generic_bounds)

0 commit comments

Comments
 (0)