Skip to content

Commit

Permalink
Refactor so that references to traits are not represented using a typ…
Browse files Browse the repository at this point in the history
…e 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 rust-lang#4183 (not a fix, but related)
  • Loading branch information
nikomatsakis committed Apr 5, 2013
1 parent 3333b0f commit d28f734
Show file tree
Hide file tree
Showing 46 changed files with 1,071 additions and 862 deletions.
28 changes: 27 additions & 1 deletion src/libcore/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ use ops::Add;
use kinds::Copy;
use util;
use num::Zero;
use iter::{BaseIter, MutableIter};
use iter::{BaseIter, MutableIter, ExtendedIter};
use iter;

#[cfg(test)] use ptr;
#[cfg(test)] use str;
Expand Down Expand Up @@ -118,6 +119,31 @@ impl<T> MutableIter<T> for Option<T> {
}
}

impl<A> ExtendedIter<A> for Option<A> {
pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) {
iter::eachi(self, blk)
}
pub fn all(&self, blk: &fn(&A) -> bool) -> bool {
iter::all(self, blk)
}
pub fn any(&self, blk: &fn(&A) -> bool) -> bool {
iter::any(self, blk)
}
pub fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B {
iter::foldl(self, b0, blk)
}
pub fn position(&self, f: &fn(&A) -> bool) -> Option<uint> {
iter::position(self, f)
}
fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B] {
iter::map_to_vec(self, op)
}
fn flat_map_to_vec<B,IB:BaseIter<B>>(&self, op: &fn(&A) -> IB)
-> ~[B] {
iter::flat_map_to_vec(self, op)
}
}

pub impl<T> Option<T> {
/// Returns true if the option equals `none`
fn is_none(&const self) -> bool {
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,9 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
}

fn visit_trait(&self) -> bool {
self.align_to::<TyVisitor>();
self.align_to::<@TyVisitor>();
if ! self.inner.visit_trait() { return false; }
self.bump_past::<TyVisitor>();
self.bump_past::<@TyVisitor>();
true
}

Expand Down
2 changes: 1 addition & 1 deletion src/libcore/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program {
@ProgRes(repr) as @Program
}

fn read_all(rd: io::Reader) -> ~str {
fn read_all(rd: @io::Reader) -> ~str {
let buf = io::with_bytes_writer(|wr| {
let mut bytes = [0, ..4096];
while !rd.eof() {
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ pub static tag_crate_dep_vers: uint = 0x2cu;
pub static tag_mod_impl: uint = 0x30u;

pub static tag_item_trait_method: uint = 0x31u;
pub static tag_impl_trait: uint = 0x32u;

pub static tag_item_trait_ref: uint = 0x32u;
pub static tag_item_super_trait_ref: uint = 0x33u;

// discriminator value for variants
pub static tag_disr_val: uint = 0x34u;
Expand Down
15 changes: 11 additions & 4 deletions src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ pub fn get_provided_trait_methods(tcx: ty::ctxt,
decoder::get_provided_trait_methods(cstore.intr, cdata, def.node, tcx)
}

pub fn get_supertraits(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::t] {
pub fn get_supertraits(tcx: ty::ctxt, def: ast::def_id) -> ~[@ty::TraitRef] {
let cstore = tcx.cstore;
let cdata = cstore::get_crate_data(cstore, def.crate);
decoder::get_supertraits(cdata, def.node, tcx)
Expand Down Expand Up @@ -180,6 +180,12 @@ pub fn get_type(tcx: ty::ctxt,
decoder::get_type(cdata, def.node, tcx)
}

pub fn get_trait_def(tcx: ty::ctxt, def: ast::def_id) -> ty::TraitDef {
let cstore = tcx.cstore;
let cdata = cstore::get_crate_data(cstore, def.crate);
decoder::get_trait_def(cdata, def.node, tcx)
}

pub fn get_region_param(cstore: @mut metadata::cstore::CStore,
def: ast::def_id) -> Option<ty::region_variance> {
let cdata = cstore::get_crate_data(cstore, def.crate);
Expand All @@ -204,16 +210,17 @@ pub fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
debug!("got field data %?", the_field);
let ty = decoder::item_type(def, the_field, tcx, cdata);
ty::ty_param_bounds_and_ty {
bounds: @~[],
region_param: None,
generics: ty::Generics {bounds: @~[],
region_param: None},
ty: ty
}
}

// Given a def_id for an impl or class, return the traits it implements,
// or the empty vector if it's not for an impl or for a class that implements
// traits
pub fn get_impl_traits(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::t] {
pub fn get_impl_traits(tcx: ty::ctxt,
def: ast::def_id) -> ~[@ty::TraitRef] {
let cstore = tcx.cstore;
let cdata = cstore::get_crate_data(cstore, def.crate);
decoder::get_impl_traits(cdata, def.node, tcx)
Expand Down
71 changes: 52 additions & 19 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use metadata::csearch;
use metadata::cstore;
use metadata::decoder;
use metadata::tydecode::{parse_ty_data, parse_def_id, parse_bounds_data,
parse_bare_fn_ty_data};
parse_bare_fn_ty_data, parse_trait_ref_data};
use middle::{ty, resolve};

use core::hash::HashUtil;
Expand Down Expand Up @@ -256,12 +256,14 @@ pub fn item_type(item_id: ast::def_id, item: ebml::Doc,
}
}
fn item_impl_traits(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ~[ty::t] {
let mut results = ~[];
for reader::tagged_docs(item, tag_impl_trait) |ity| {
results.push(doc_type(ity, tcx, cdata));
};
results
fn doc_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef {
parse_trait_ref_data(doc.data, cdata.cnum, doc.start, tcx,
|_, did| translate_def_id(cdata, did))
}
fn item_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef {
let tp = reader::get_doc(doc, tag_item_trait_ref);
doc_trait_ref(tp, tcx, cdata)
}
fn item_ty_param_bounds(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd,
Expand Down Expand Up @@ -371,6 +373,21 @@ pub fn lookup_def(cnum: ast::crate_num, data: @~[u8], did_: ast::def_id) ->
return def_like_to_def(item_to_def_like(item, did, cnum));
}
pub fn get_trait_def(cdata: cmd,
item_id: ast::node_id,
tcx: ty::ctxt) -> ty::TraitDef
{
let item_doc = lookup_item(item_id, cdata.data);
let tp_bounds = item_ty_param_bounds(item_doc, tcx, cdata,
tag_items_data_item_ty_param_bounds);
let rp = item_ty_region_param(item_doc);
ty::TraitDef {
generics: ty::Generics {bounds: tp_bounds,
region_param: rp},
trait_ref: @item_trait_ref(item_doc, tcx, cdata)
}
}
pub fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
-> ty::ty_param_bounds_and_ty {
Expand All @@ -382,8 +399,8 @@ pub fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
} else { @~[] };
let rp = item_ty_region_param(item);
ty::ty_param_bounds_and_ty {
bounds: tp_bounds,
region_param: rp,
generics: ty::Generics {bounds: tp_bounds,
region_param: rp},
ty: t
}
}
Expand All @@ -399,9 +416,19 @@ pub fn get_type_param_count(data: @~[u8], id: ast::node_id) -> uint {
item_ty_param_count(lookup_item(id, data))
}
pub fn get_impl_traits(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
-> ~[ty::t] {
item_impl_traits(lookup_item(id, cdata.data), tcx, cdata)
pub fn get_impl_traits(cdata: cmd,
id: ast::node_id,
tcx: ty::ctxt) -> ~[@ty::TraitRef]
{
let item_doc = lookup_item(id, cdata.data);
let mut results = ~[];
for reader::tagged_docs(item_doc, tag_item_trait_ref) |tp| {
let trait_ref =
@parse_trait_ref_data(tp.data, cdata.cnum, tp.start, tcx,
|_, did| translate_def_id(cdata, did));
results.push(trait_ref);
};
results
}
pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
Expand Down Expand Up @@ -735,7 +762,10 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
let self_ty = get_self_ty(method_doc);
ty::method {
ident: name,
tps: bounds,
generics: ty::Generics {
bounds: bounds,
region_param: None
},
transformed_self_ty: transformed_self_ty,
fty: fty,
self_ty: self_ty,
Expand Down Expand Up @@ -784,7 +814,10 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
let self_ty = get_self_ty(mth);
let ty_method = ty::method {
ident: name,
tps: bounds,
generics: ty::Generics {
bounds: bounds,
region_param: None
},
transformed_self_ty: transformed_self_ty,
fty: fty,
self_ty: self_ty,
Expand All @@ -804,11 +837,11 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,

/// Returns the supertraits of the given trait.
pub fn get_supertraits(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
-> ~[ty::t] {
-> ~[@ty::TraitRef] {
let mut results = ~[];
let item_doc = lookup_item(id, cdata.data);
for reader::tagged_docs(item_doc, tag_impl_trait) |trait_doc| {
results.push(doc_type(trait_doc, tcx, cdata));
for reader::tagged_docs(item_doc, tag_item_super_trait_ref) |trait_doc| {
results.push(@doc_trait_ref(trait_doc, tcx, cdata));
}
return results;
}
Expand Down Expand Up @@ -837,8 +870,8 @@ pub fn get_static_methods_if_impl(intr: @ident_interner,
return None;
}

// If this impl has a trait ref, don't consider it.
for reader::tagged_docs(item, tag_impl_trait) |_doc| {
// If this impl implements a trait, don't consider it.
for reader::tagged_docs(item, tag_item_trait_ref) |_doc| {
return None;
}

Expand Down
38 changes: 25 additions & 13 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,23 @@ fn add_to_index(ecx: @EncodeContext, ebml_w: writer::Encoder, path: &[ident],
});
}

fn encode_trait_ref(ebml_w: writer::Encoder, ecx: @EncodeContext,
t: @trait_ref) {
ebml_w.start_tag(tag_impl_trait);
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id));
fn encode_trait_ref(ebml_w: writer::Encoder,
ecx: @EncodeContext,
trait_ref: &ty::TraitRef,
tag: uint)
{
let ty_str_ctxt = @tyencode::ctxt {
diag: ecx.diag,
ds: def_to_str,
tcx: ecx.tcx,
reachable: |a| reachable(ecx, a),
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};

ebml_w.start_tag(tag);
tyencode::enc_trait_ref(ebml_w.writer, ty_str_ctxt, trait_ref);
ebml_w.end_tag();
}


// Item info table encoding
fn encode_family(ebml_w: writer::Encoder, c: char) {
ebml_w.start_tag(tag_items_data_item_family);
Expand Down Expand Up @@ -579,7 +588,7 @@ fn encode_method_ty_fields(ecx: @EncodeContext,
{
encode_def_id(ebml_w, method_ty.def_id);
encode_name(ecx, ebml_w, method_ty.ident);
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.tps,
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.generics.bounds,
tag_item_method_tps);
encode_transformed_self_ty(ecx, ebml_w, method_ty.transformed_self_ty);
encode_method_fty(ecx, ebml_w, &method_ty.fty);
Expand Down Expand Up @@ -872,8 +881,9 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
ebml_w.writer.write(str::to_bytes(def_to_str(method_def_id)));
ebml_w.end_tag();
}
for opt_trait.each |associated_trait| {
encode_trait_ref(ebml_w, ecx, *associated_trait);
for opt_trait.each |ast_trait_ref| {
let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_trait_ref);
}
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
ebml_w.end_tag();
Expand All @@ -894,14 +904,15 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
&m.generics);
}
}
item_trait(ref generics, ref traits, ref ms) => {
item_trait(ref generics, ref super_traits, ref ms) => {
add_to_index();
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 'I');
encode_region_param(ecx, ebml_w, item);
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
let trait_def = ty::lookup_trait_def(tcx, local_def(item.id));
encode_trait_ref(ebml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
encode_name(ecx, ebml_w, item.ident);
encode_attributes(ebml_w, item.attrs);
for ty::trait_method_def_ids(tcx, local_def(item.id)).each |&method_def_id| {
Expand All @@ -910,8 +921,9 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
ebml_w.end_tag();
}
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
for traits.each |associated_trait| {
encode_trait_ref(ebml_w, ecx, *associated_trait);
for super_traits.each |ast_trait_ref| {
let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref);
}
ebml_w.end_tag();
Expand Down Expand Up @@ -940,7 +952,7 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
method_ty.fty.purity));
let tpt = ty::lookup_item_type(tcx, method_def_id);
encode_ty_type_param_bounds(ebml_w, ecx, tpt.bounds,
encode_ty_type_param_bounds(ebml_w, ecx, tpt.generics.bounds,
tag_items_data_item_ty_param_bounds);
encode_type(ecx, ebml_w, tpt.ty);
}
Expand Down
15 changes: 13 additions & 2 deletions src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ pub fn parse_bare_fn_ty_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::c
parse_bare_fn_ty(st, conv)
}

pub fn parse_trait_ref_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt,
conv: conv_did) -> ty::TraitRef {
let st = parse_state_from_data(data, crate_num, pos, tcx);
parse_trait_ref(st, conv)
}

pub fn parse_arg_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt,
conv: conv_did) -> ty::arg {
let st = parse_state_from_data(data, crate_num, pos, tcx);
Expand Down Expand Up @@ -183,7 +189,6 @@ fn parse_trait_store(st: @mut PState) -> ty::TraitStore {
'~' => ty::UniqTraitStore,
'@' => ty::BoxTraitStore,
'&' => ty::RegionTraitStore(parse_region(st)),
'.' => ty::BareTraitStore,
c => st.tcx.sess.bug(fmt!("parse_trait_store(): bad input '%c'", c))
}
}
Expand Down Expand Up @@ -265,6 +270,12 @@ fn parse_str(st: @mut PState, term: char) -> ~str {
return result;
}
fn parse_trait_ref(st: @mut PState, conv: conv_did) -> ty::TraitRef {
let def = parse_def(st, NominalType, conv);
let substs = parse_substs(st, conv);
ty::TraitRef {def_id: def, substs: substs}
}
fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t {
match next(st) {
'n' => return ty::mk_nil(st.tcx),
Expand Down Expand Up @@ -551,7 +562,7 @@ fn parse_bounds(st: @mut PState, conv: conv_did) -> @~[ty::param_bound] {
'C' => ty::bound_copy,
'K' => ty::bound_const,
'O' => ty::bound_durable,
'I' => ty::bound_trait(parse_ty(st, conv)),
'I' => ty::bound_trait(@parse_trait_ref(st, conv)),
'.' => break,
_ => fail!(~"parse_bounds: bad bounds")
});
Expand Down
Loading

0 comments on commit d28f734

Please sign in to comment.