Skip to content

Commit bc9ae36

Browse files
committed
Separate supertrait collection from processing a TraitDef. This allows
us to construct trait-references and do other things without forcing a full evaluation of the supertraits. One downside of this scheme is that we must invoke `ensure_super_predicates` before using any construct that might require knowing about the super-predicates.
1 parent 4ee002a commit bc9ae36

23 files changed

+487
-417
lines changed

src/librustc/metadata/common.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ pub const tag_mod_impl: uint = 0x38;
8484
pub const tag_item_trait_item: uint = 0x39;
8585

8686
pub const tag_item_trait_ref: uint = 0x3a;
87-
pub const tag_item_super_trait_ref: uint = 0x3b;
8887

8988
// discriminator value for variants
9089
pub const tag_disr_val: uint = 0x3c;
@@ -221,8 +220,6 @@ pub const tag_struct_field_id: uint = 0x8b;
221220

222221
pub const tag_attribute_is_sugared_doc: uint = 0x8c;
223222

224-
pub const tag_trait_def_bounds: uint = 0x8d;
225-
226223
pub const tag_items_data_region: uint = 0x8e;
227224

228225
pub const tag_region_param_def: uint = 0x8f;
@@ -255,3 +252,5 @@ pub const tag_paren_sugar: uint = 0xa0;
255252

256253
pub const tag_codemap: uint = 0xa1;
257254
pub const tag_codemap_filemap: uint = 0xa2;
255+
256+
pub const tag_item_super_predicates: uint = 0xa3;

src/librustc/metadata/csearch.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,6 @@ pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
175175
decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx)
176176
}
177177

178-
pub fn get_supertraits<'tcx>(tcx: &ty::ctxt<'tcx>,
179-
def: ast::DefId)
180-
-> Vec<Rc<ty::TraitRef<'tcx>>> {
181-
let cstore = &tcx.sess.cstore;
182-
let cdata = cstore.get_crate_data(def.krate);
183-
decoder::get_supertraits(&*cdata, def.node, tcx)
184-
}
185-
186178
pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: ast::DefId)
187179
-> Option<ast::Name> {
188180
let cdata = cstore.get_crate_data(def.krate);
@@ -238,6 +230,14 @@ pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
238230
decoder::get_predicates(&*cdata, def.node, tcx)
239231
}
240232

233+
pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
234+
-> ty::GenericPredicates<'tcx>
235+
{
236+
let cstore = &tcx.sess.cstore;
237+
let cdata = cstore.get_crate_data(def.krate);
238+
decoder::get_super_predicates(&*cdata, def.node, tcx)
239+
}
240+
241241
pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
242242
def: ast::DefId) -> ty::TypeScheme<'tcx> {
243243
let cstore = &tcx.sess.cstore;

src/librustc/metadata/decoder.rs

+11-35
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@ use metadata::csearch::MethodInfo;
2222
use metadata::csearch;
2323
use metadata::cstore;
2424
use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
25-
parse_type_param_def_data, parse_bounds_data,
26-
parse_bare_fn_ty_data, parse_trait_ref_data,
27-
parse_predicate_data};
25+
parse_type_param_def_data, parse_bare_fn_ty_data,
26+
parse_trait_ref_data, parse_predicate_data};
2827
use middle::def;
2928
use middle::lang_items;
3029
use middle::subst;
@@ -260,18 +259,6 @@ fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
260259
doc_trait_ref(tp, tcx, cdata)
261260
}
262261

263-
fn doc_bounds<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
264-
-> ty::ParamBounds<'tcx> {
265-
parse_bounds_data(doc.data, cdata.cnum, doc.start, tcx,
266-
|_, did| translate_def_id(cdata, did))
267-
}
268-
269-
fn trait_def_bounds<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
270-
-> ty::ParamBounds<'tcx> {
271-
let d = reader::get_doc(doc, tag_trait_def_bounds);
272-
doc_bounds(d, tcx, cdata)
273-
}
274-
275262
fn enum_variant_ids(item: rbml::Doc, cdata: Cmd) -> Vec<ast::DefId> {
276263
let mut ids: Vec<ast::DefId> = Vec::new();
277264
let v = tag_items_data_item_variant;
@@ -406,7 +393,6 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
406393
{
407394
let item_doc = lookup_item(item_id, cdata.data());
408395
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
409-
let bounds = trait_def_bounds(item_doc, tcx, cdata);
410396
let unsafety = parse_unsafety(item_doc);
411397
let associated_type_names = parse_associated_type_names(item_doc);
412398
let paren_sugar = parse_paren_sugar(item_doc);
@@ -415,7 +401,6 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
415401
paren_sugar: paren_sugar,
416402
unsafety: unsafety,
417403
generics: generics,
418-
bounds: bounds,
419404
trait_ref: item_trait_ref(item_doc, tcx, cdata),
420405
associated_type_names: associated_type_names,
421406
}
@@ -430,6 +415,15 @@ pub fn get_predicates<'tcx>(cdata: Cmd,
430415
doc_predicates(item_doc, tcx, cdata, tag_item_generics)
431416
}
432417

418+
pub fn get_super_predicates<'tcx>(cdata: Cmd,
419+
item_id: ast::NodeId,
420+
tcx: &ty::ctxt<'tcx>)
421+
-> ty::GenericPredicates<'tcx>
422+
{
423+
let item_doc = lookup_item(item_id, cdata.data());
424+
doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates)
425+
}
426+
433427
pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
434428
-> ty::TypeScheme<'tcx>
435429
{
@@ -971,24 +965,6 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
971965
return result;
972966
}
973967

974-
/// Returns the supertraits of the given trait.
975-
pub fn get_supertraits<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
976-
-> Vec<Rc<ty::TraitRef<'tcx>>> {
977-
let mut results = Vec::new();
978-
let item_doc = lookup_item(id, cdata.data());
979-
reader::tagged_docs(item_doc, tag_item_super_trait_ref, |trait_doc| {
980-
// NB. Only reads the ones that *aren't* builtin-bounds. See also
981-
// get_trait_def() for collecting the builtin bounds.
982-
// FIXME(#8559): The builtin bounds shouldn't be encoded in the first place.
983-
let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
984-
if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() {
985-
results.push(trait_ref);
986-
}
987-
true
988-
});
989-
return results;
990-
}
991-
992968
pub fn get_type_name_if_impl(cdata: Cmd,
993969
node_id: ast::NodeId) -> Option<ast::Name> {
994970
let item = lookup_item(node_id, cdata.data());

src/librustc/metadata/encoder.rs

+27-17
Original file line numberDiff line numberDiff line change
@@ -206,21 +206,6 @@ pub fn write_region(ecx: &EncodeContext,
206206
tyencode::enc_region(rbml_w, ty_str_ctxt, r);
207207
}
208208

209-
fn encode_bounds<'a, 'tcx>(rbml_w: &mut Encoder,
210-
ecx: &EncodeContext<'a, 'tcx>,
211-
bounds: &ty::ParamBounds<'tcx>,
212-
tag: uint) {
213-
rbml_w.start_tag(tag);
214-
215-
let ty_str_ctxt = &tyencode::ctxt { diag: ecx.diag,
216-
ds: def_to_string,
217-
tcx: ecx.tcx,
218-
abbrevs: &ecx.type_abbrevs };
219-
tyencode::enc_bounds(rbml_w, ty_str_ctxt, bounds);
220-
221-
rbml_w.end_tag();
222-
}
223-
224209
fn encode_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
225210
rbml_w: &mut Encoder,
226211
typ: Ty<'tcx>) {
@@ -728,6 +713,7 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
728713
tcx: ecx.tcx,
729714
abbrevs: &ecx.type_abbrevs
730715
};
716+
731717
for param in generics.types.iter() {
732718
rbml_w.start_tag(tag_type_param_def);
733719
tyencode::enc_type_param_def(rbml_w, ty_str_ctxt, param);
@@ -758,6 +744,22 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
758744
rbml_w.end_tag();
759745
}
760746

747+
encode_predicates_in_current_doc(rbml_w, ecx, predicates);
748+
749+
rbml_w.end_tag();
750+
}
751+
752+
fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder,
753+
ecx: &EncodeContext<'a,'tcx>,
754+
predicates: &ty::GenericPredicates<'tcx>)
755+
{
756+
let ty_str_ctxt = &tyencode::ctxt {
757+
diag: ecx.diag,
758+
ds: def_to_string,
759+
tcx: ecx.tcx,
760+
abbrevs: &ecx.type_abbrevs
761+
};
762+
761763
for (space, _, predicate) in predicates.predicates.iter_enumerated() {
762764
rbml_w.start_tag(tag_predicate);
763765

@@ -769,7 +771,15 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
769771

770772
rbml_w.end_tag();
771773
}
774+
}
772775

776+
fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
777+
ecx: &EncodeContext<'a,'tcx>,
778+
predicates: &ty::GenericPredicates<'tcx>,
779+
tag: uint)
780+
{
781+
rbml_w.start_tag(tag);
782+
encode_predicates_in_current_doc(rbml_w, ecx, predicates);
773783
rbml_w.end_tag();
774784
}
775785

@@ -1280,6 +1290,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
12801290
encode_paren_sugar(rbml_w, trait_def.paren_sugar);
12811291
encode_associated_type_names(rbml_w, &trait_def.associated_type_names);
12821292
encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates, tag_item_generics);
1293+
encode_predicates(rbml_w, ecx, &ty::lookup_super_predicates(tcx, def_id),
1294+
tag_item_super_predicates);
12831295
encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
12841296
encode_name(rbml_w, item.ident.name);
12851297
encode_attributes(rbml_w, &item.attrs);
@@ -1304,8 +1316,6 @@ fn encode_info_for_item(ecx: &EncodeContext,
13041316
}
13051317
encode_path(rbml_w, path.clone());
13061318

1307-
encode_bounds(rbml_w, ecx, &trait_def.bounds, tag_trait_def_bounds);
1308-
13091319
// Encode the implementations of this trait.
13101320
encode_extension_implementations(ecx, rbml_w, def_id);
13111321

src/librustc/middle/traits/object_safety.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use super::elaborate_predicates;
2222

2323
use middle::subst::{self, SelfSpace, TypeSpace};
2424
use middle::traits;
25-
use middle::ty::{self, Ty};
25+
use middle::ty::{self, ToPolyTraitRef, Ty};
2626
use std::rc::Rc;
2727
use syntax::ast;
2828
use util::ppaux::Repr;
@@ -128,9 +128,12 @@ fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>,
128128
{
129129
let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
130130
let trait_ref = trait_def.trait_ref.clone();
131-
let predicates = ty::predicates_for_trait_ref(tcx, &ty::Binder(trait_ref));
131+
let trait_ref = trait_ref.to_poly_trait_ref();
132+
let predicates = ty::lookup_super_predicates(tcx, trait_def_id);
132133
predicates
134+
.predicates
133135
.into_iter()
136+
.map(|predicate| predicate.subst_supertrait(tcx, &trait_ref))
134137
.any(|predicate| {
135138
match predicate {
136139
ty::Predicate::Trait(ref data) => {

src/librustc/middle/traits/select.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1455,9 +1455,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14551455
let principal =
14561456
data.principal_trait_ref_with_self_ty(self.tcx(),
14571457
self.tcx().types.err);
1458+
let desired_def_id = obligation.predicate.def_id();
14581459
for tr in util::supertraits(self.tcx(), principal) {
1459-
let td = ty::lookup_trait_def(self.tcx(), tr.def_id());
1460-
if td.bounds.builtin_bounds.contains(&bound) {
1460+
if tr.def_id() == desired_def_id {
14611461
return Ok(If(Vec::new()))
14621462
}
14631463
}

src/librustc/middle/traits/util.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,17 @@ impl<'cx, 'tcx> Elaborator<'cx, 'tcx> {
117117
fn push(&mut self, predicate: &ty::Predicate<'tcx>) {
118118
match *predicate {
119119
ty::Predicate::Trait(ref data) => {
120-
let mut predicates =
121-
ty::predicates_for_trait_ref(self.tcx,
122-
&data.to_poly_trait_ref());
120+
// Predicates declared on the trait.
121+
let predicates = ty::lookup_super_predicates(self.tcx, data.def_id());
122+
123+
let mut predicates: Vec<_> =
124+
predicates.predicates
125+
.iter()
126+
.map(|p| p.subst_supertrait(self.tcx, &data.to_poly_trait_ref()))
127+
.collect();
128+
129+
debug!("super_predicates: data={} predicates={}",
130+
data.repr(self.tcx), predicates.repr(self.tcx));
123131

124132
// Only keep those bounds that we haven't already
125133
// seen. This is necessary to prevent infinite

0 commit comments

Comments
 (0)