Skip to content

Commit d28f734

Browse files
committed
Refactor so that references to traits are not represented using a type with a
bare function store (which is not in fact a kind of value) but rather ty::TraitRef. Removes many uses of fail!() and other telltale signs of type-semantic mismatch. cc #4183 (not a fix, but related)
1 parent 3333b0f commit d28f734

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1071
-862
lines changed

src/libcore/option.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ use ops::Add;
4646
use kinds::Copy;
4747
use util;
4848
use num::Zero;
49-
use iter::{BaseIter, MutableIter};
49+
use iter::{BaseIter, MutableIter, ExtendedIter};
50+
use iter;
5051

5152
#[cfg(test)] use ptr;
5253
#[cfg(test)] use str;
@@ -118,6 +119,31 @@ impl<T> MutableIter<T> for Option<T> {
118119
}
119120
}
120121

122+
impl<A> ExtendedIter<A> for Option<A> {
123+
pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) {
124+
iter::eachi(self, blk)
125+
}
126+
pub fn all(&self, blk: &fn(&A) -> bool) -> bool {
127+
iter::all(self, blk)
128+
}
129+
pub fn any(&self, blk: &fn(&A) -> bool) -> bool {
130+
iter::any(self, blk)
131+
}
132+
pub fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B {
133+
iter::foldl(self, b0, blk)
134+
}
135+
pub fn position(&self, f: &fn(&A) -> bool) -> Option<uint> {
136+
iter::position(self, f)
137+
}
138+
fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B] {
139+
iter::map_to_vec(self, op)
140+
}
141+
fn flat_map_to_vec<B,IB:BaseIter<B>>(&self, op: &fn(&A) -> IB)
142+
-> ~[B] {
143+
iter::flat_map_to_vec(self, op)
144+
}
145+
}
146+
121147
pub impl<T> Option<T> {
122148
/// Returns true if the option equals `none`
123149
fn is_none(&const self) -> bool {

src/libcore/reflect.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,9 +443,9 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
443443
}
444444

445445
fn visit_trait(&self) -> bool {
446-
self.align_to::<TyVisitor>();
446+
self.align_to::<@TyVisitor>();
447447
if ! self.inner.visit_trait() { return false; }
448-
self.bump_past::<TyVisitor>();
448+
self.bump_past::<@TyVisitor>();
449449
true
450450
}
451451

src/libcore/run.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program {
298298
@ProgRes(repr) as @Program
299299
}
300300

301-
fn read_all(rd: io::Reader) -> ~str {
301+
fn read_all(rd: @io::Reader) -> ~str {
302302
let buf = io::with_bytes_writer(|wr| {
303303
let mut bytes = [0, ..4096];
304304
while !rd.eof() {

src/librustc/metadata/common.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ pub static tag_crate_dep_vers: uint = 0x2cu;
7474
pub static tag_mod_impl: uint = 0x30u;
7575

7676
pub static tag_item_trait_method: uint = 0x31u;
77-
pub static tag_impl_trait: uint = 0x32u;
77+
78+
pub static tag_item_trait_ref: uint = 0x32u;
79+
pub static tag_item_super_trait_ref: uint = 0x33u;
7880

7981
// discriminator value for variants
8082
pub static tag_disr_val: uint = 0x34u;

src/librustc/metadata/csearch.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ pub fn get_provided_trait_methods(tcx: ty::ctxt,
139139
decoder::get_provided_trait_methods(cstore.intr, cdata, def.node, tcx)
140140
}
141141

142-
pub fn get_supertraits(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::t] {
142+
pub fn get_supertraits(tcx: ty::ctxt, def: ast::def_id) -> ~[@ty::TraitRef] {
143143
let cstore = tcx.cstore;
144144
let cdata = cstore::get_crate_data(cstore, def.crate);
145145
decoder::get_supertraits(cdata, def.node, tcx)
@@ -180,6 +180,12 @@ pub fn get_type(tcx: ty::ctxt,
180180
decoder::get_type(cdata, def.node, tcx)
181181
}
182182

183+
pub fn get_trait_def(tcx: ty::ctxt, def: ast::def_id) -> ty::TraitDef {
184+
let cstore = tcx.cstore;
185+
let cdata = cstore::get_crate_data(cstore, def.crate);
186+
decoder::get_trait_def(cdata, def.node, tcx)
187+
}
188+
183189
pub fn get_region_param(cstore: @mut metadata::cstore::CStore,
184190
def: ast::def_id) -> Option<ty::region_variance> {
185191
let cdata = cstore::get_crate_data(cstore, def.crate);
@@ -204,16 +210,17 @@ pub fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
204210
debug!("got field data %?", the_field);
205211
let ty = decoder::item_type(def, the_field, tcx, cdata);
206212
ty::ty_param_bounds_and_ty {
207-
bounds: @~[],
208-
region_param: None,
213+
generics: ty::Generics {bounds: @~[],
214+
region_param: None},
209215
ty: ty
210216
}
211217
}
212218

213219
// Given a def_id for an impl or class, return the traits it implements,
214220
// or the empty vector if it's not for an impl or for a class that implements
215221
// traits
216-
pub fn get_impl_traits(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::t] {
222+
pub fn get_impl_traits(tcx: ty::ctxt,
223+
def: ast::def_id) -> ~[@ty::TraitRef] {
217224
let cstore = tcx.cstore;
218225
let cdata = cstore::get_crate_data(cstore, def.crate);
219226
decoder::get_impl_traits(cdata, def.node, tcx)

src/librustc/metadata/decoder.rs

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use metadata::csearch;
2020
use metadata::cstore;
2121
use metadata::decoder;
2222
use metadata::tydecode::{parse_ty_data, parse_def_id, parse_bounds_data,
23-
parse_bare_fn_ty_data};
23+
parse_bare_fn_ty_data, parse_trait_ref_data};
2424
use middle::{ty, resolve};
2525

2626
use core::hash::HashUtil;
@@ -256,12 +256,14 @@ pub fn item_type(item_id: ast::def_id, item: ebml::Doc,
256256
}
257257
}
258258
259-
fn item_impl_traits(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ~[ty::t] {
260-
let mut results = ~[];
261-
for reader::tagged_docs(item, tag_impl_trait) |ity| {
262-
results.push(doc_type(ity, tcx, cdata));
263-
};
264-
results
259+
fn doc_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef {
260+
parse_trait_ref_data(doc.data, cdata.cnum, doc.start, tcx,
261+
|_, did| translate_def_id(cdata, did))
262+
}
263+
264+
fn item_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef {
265+
let tp = reader::get_doc(doc, tag_item_trait_ref);
266+
doc_trait_ref(tp, tcx, cdata)
265267
}
266268
267269
fn item_ty_param_bounds(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd,
@@ -371,6 +373,21 @@ pub fn lookup_def(cnum: ast::crate_num, data: @~[u8], did_: ast::def_id) ->
371373
return def_like_to_def(item_to_def_like(item, did, cnum));
372374
}
373375
376+
pub fn get_trait_def(cdata: cmd,
377+
item_id: ast::node_id,
378+
tcx: ty::ctxt) -> ty::TraitDef
379+
{
380+
let item_doc = lookup_item(item_id, cdata.data);
381+
let tp_bounds = item_ty_param_bounds(item_doc, tcx, cdata,
382+
tag_items_data_item_ty_param_bounds);
383+
let rp = item_ty_region_param(item_doc);
384+
ty::TraitDef {
385+
generics: ty::Generics {bounds: tp_bounds,
386+
region_param: rp},
387+
trait_ref: @item_trait_ref(item_doc, tcx, cdata)
388+
}
389+
}
390+
374391
pub fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
375392
-> ty::ty_param_bounds_and_ty {
376393
@@ -382,8 +399,8 @@ pub fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
382399
} else { @~[] };
383400
let rp = item_ty_region_param(item);
384401
ty::ty_param_bounds_and_ty {
385-
bounds: tp_bounds,
386-
region_param: rp,
402+
generics: ty::Generics {bounds: tp_bounds,
403+
region_param: rp},
387404
ty: t
388405
}
389406
}
@@ -399,9 +416,19 @@ pub fn get_type_param_count(data: @~[u8], id: ast::node_id) -> uint {
399416
item_ty_param_count(lookup_item(id, data))
400417
}
401418
402-
pub fn get_impl_traits(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
403-
-> ~[ty::t] {
404-
item_impl_traits(lookup_item(id, cdata.data), tcx, cdata)
419+
pub fn get_impl_traits(cdata: cmd,
420+
id: ast::node_id,
421+
tcx: ty::ctxt) -> ~[@ty::TraitRef]
422+
{
423+
let item_doc = lookup_item(id, cdata.data);
424+
let mut results = ~[];
425+
for reader::tagged_docs(item_doc, tag_item_trait_ref) |tp| {
426+
let trait_ref =
427+
@parse_trait_ref_data(tp.data, cdata.cnum, tp.start, tcx,
428+
|_, did| translate_def_id(cdata, did));
429+
results.push(trait_ref);
430+
};
431+
results
405432
}
406433
407434
pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
@@ -735,7 +762,10 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
735762
let self_ty = get_self_ty(method_doc);
736763
ty::method {
737764
ident: name,
738-
tps: bounds,
765+
generics: ty::Generics {
766+
bounds: bounds,
767+
region_param: None
768+
},
739769
transformed_self_ty: transformed_self_ty,
740770
fty: fty,
741771
self_ty: self_ty,
@@ -784,7 +814,10 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
784814
let self_ty = get_self_ty(mth);
785815
let ty_method = ty::method {
786816
ident: name,
787-
tps: bounds,
817+
generics: ty::Generics {
818+
bounds: bounds,
819+
region_param: None
820+
},
788821
transformed_self_ty: transformed_self_ty,
789822
fty: fty,
790823
self_ty: self_ty,
@@ -804,11 +837,11 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
804837

805838
/// Returns the supertraits of the given trait.
806839
pub fn get_supertraits(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
807-
-> ~[ty::t] {
840+
-> ~[@ty::TraitRef] {
808841
let mut results = ~[];
809842
let item_doc = lookup_item(id, cdata.data);
810-
for reader::tagged_docs(item_doc, tag_impl_trait) |trait_doc| {
811-
results.push(doc_type(trait_doc, tcx, cdata));
843+
for reader::tagged_docs(item_doc, tag_item_super_trait_ref) |trait_doc| {
844+
results.push(@doc_trait_ref(trait_doc, tcx, cdata));
812845
}
813846
return results;
814847
}
@@ -837,8 +870,8 @@ pub fn get_static_methods_if_impl(intr: @ident_interner,
837870
return None;
838871
}
839872

840-
// If this impl has a trait ref, don't consider it.
841-
for reader::tagged_docs(item, tag_impl_trait) |_doc| {
873+
// If this impl implements a trait, don't consider it.
874+
for reader::tagged_docs(item, tag_item_trait_ref) |_doc| {
842875
return None;
843876
}
844877

src/librustc/metadata/encoder.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,23 @@ fn add_to_index(ecx: @EncodeContext, ebml_w: writer::Encoder, path: &[ident],
153153
});
154154
}
155155

156-
fn encode_trait_ref(ebml_w: writer::Encoder, ecx: @EncodeContext,
157-
t: @trait_ref) {
158-
ebml_w.start_tag(tag_impl_trait);
159-
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id));
156+
fn encode_trait_ref(ebml_w: writer::Encoder,
157+
ecx: @EncodeContext,
158+
trait_ref: &ty::TraitRef,
159+
tag: uint)
160+
{
161+
let ty_str_ctxt = @tyencode::ctxt {
162+
diag: ecx.diag,
163+
ds: def_to_str,
164+
tcx: ecx.tcx,
165+
reachable: |a| reachable(ecx, a),
166+
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
167+
168+
ebml_w.start_tag(tag);
169+
tyencode::enc_trait_ref(ebml_w.writer, ty_str_ctxt, trait_ref);
160170
ebml_w.end_tag();
161171
}
162172

163-
164173
// Item info table encoding
165174
fn encode_family(ebml_w: writer::Encoder, c: char) {
166175
ebml_w.start_tag(tag_items_data_item_family);
@@ -579,7 +588,7 @@ fn encode_method_ty_fields(ecx: @EncodeContext,
579588
{
580589
encode_def_id(ebml_w, method_ty.def_id);
581590
encode_name(ecx, ebml_w, method_ty.ident);
582-
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.tps,
591+
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.generics.bounds,
583592
tag_item_method_tps);
584593
encode_transformed_self_ty(ecx, ebml_w, method_ty.transformed_self_ty);
585594
encode_method_fty(ecx, ebml_w, &method_ty.fty);
@@ -872,8 +881,9 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
872881
ebml_w.writer.write(str::to_bytes(def_to_str(method_def_id)));
873882
ebml_w.end_tag();
874883
}
875-
for opt_trait.each |associated_trait| {
876-
encode_trait_ref(ebml_w, ecx, *associated_trait);
884+
for opt_trait.each |ast_trait_ref| {
885+
let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
886+
encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_trait_ref);
877887
}
878888
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
879889
ebml_w.end_tag();
@@ -894,14 +904,15 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
894904
&m.generics);
895905
}
896906
}
897-
item_trait(ref generics, ref traits, ref ms) => {
907+
item_trait(ref generics, ref super_traits, ref ms) => {
898908
add_to_index();
899909
ebml_w.start_tag(tag_items_data_item);
900910
encode_def_id(ebml_w, local_def(item.id));
901911
encode_family(ebml_w, 'I');
902912
encode_region_param(ecx, ebml_w, item);
903913
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
904-
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
914+
let trait_def = ty::lookup_trait_def(tcx, local_def(item.id));
915+
encode_trait_ref(ebml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
905916
encode_name(ecx, ebml_w, item.ident);
906917
encode_attributes(ebml_w, item.attrs);
907918
for ty::trait_method_def_ids(tcx, local_def(item.id)).each |&method_def_id| {
@@ -910,8 +921,9 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
910921
ebml_w.end_tag();
911922
}
912923
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
913-
for traits.each |associated_trait| {
914-
encode_trait_ref(ebml_w, ecx, *associated_trait);
924+
for super_traits.each |ast_trait_ref| {
925+
let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
926+
encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref);
915927
}
916928
ebml_w.end_tag();
917929
@@ -940,7 +952,7 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
940952
method_ty.fty.purity));
941953
942954
let tpt = ty::lookup_item_type(tcx, method_def_id);
943-
encode_ty_type_param_bounds(ebml_w, ecx, tpt.bounds,
955+
encode_ty_type_param_bounds(ebml_w, ecx, tpt.generics.bounds,
944956
tag_items_data_item_ty_param_bounds);
945957
encode_type(ecx, ebml_w, tpt.ty);
946958
}

src/librustc/metadata/tydecode.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ pub fn parse_bare_fn_ty_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::c
125125
parse_bare_fn_ty(st, conv)
126126
}
127127

128+
pub fn parse_trait_ref_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt,
129+
conv: conv_did) -> ty::TraitRef {
130+
let st = parse_state_from_data(data, crate_num, pos, tcx);
131+
parse_trait_ref(st, conv)
132+
}
133+
128134
pub fn parse_arg_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt,
129135
conv: conv_did) -> ty::arg {
130136
let st = parse_state_from_data(data, crate_num, pos, tcx);
@@ -183,7 +189,6 @@ fn parse_trait_store(st: @mut PState) -> ty::TraitStore {
183189
'~' => ty::UniqTraitStore,
184190
'@' => ty::BoxTraitStore,
185191
'&' => ty::RegionTraitStore(parse_region(st)),
186-
'.' => ty::BareTraitStore,
187192
c => st.tcx.sess.bug(fmt!("parse_trait_store(): bad input '%c'", c))
188193
}
189194
}
@@ -265,6 +270,12 @@ fn parse_str(st: @mut PState, term: char) -> ~str {
265270
return result;
266271
}
267272
273+
fn parse_trait_ref(st: @mut PState, conv: conv_did) -> ty::TraitRef {
274+
let def = parse_def(st, NominalType, conv);
275+
let substs = parse_substs(st, conv);
276+
ty::TraitRef {def_id: def, substs: substs}
277+
}
278+
268279
fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t {
269280
match next(st) {
270281
'n' => return ty::mk_nil(st.tcx),
@@ -551,7 +562,7 @@ fn parse_bounds(st: @mut PState, conv: conv_did) -> @~[ty::param_bound] {
551562
'C' => ty::bound_copy,
552563
'K' => ty::bound_const,
553564
'O' => ty::bound_durable,
554-
'I' => ty::bound_trait(parse_ty(st, conv)),
565+
'I' => ty::bound_trait(@parse_trait_ref(st, conv)),
555566
'.' => break,
556567
_ => fail!(~"parse_bounds: bad bounds")
557568
});

0 commit comments

Comments
 (0)