Skip to content

Commit 3a1db2d

Browse files
committed
auto merge of #7886 : msullivan/rust/default-methods, r=pcwalton
This does a bunch of cleanup on the data structures for the trait system. (Unfortunately it doesn't remove `provided_method_sources`. Maybe later.) It also changes how cross crate methods are handled, so that information about them is exported in metadata, instead of having the methods regenerated by every crate that imports an impl. r? @nikomatsakis, maybe?
2 parents ec53efa + 002bfd7 commit 3a1db2d

20 files changed

+383
-615
lines changed

src/librustc/metadata/common.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ pub static tag_mod_child: uint = 0x7e;
179179
pub static tag_misc_info: uint = 0x7f;
180180
pub static tag_misc_info_crate_items: uint = 0x80;
181181

182+
pub static tag_item_method_provided_source: uint = 0x81;
183+
182184
pub struct LinkMeta {
183185
name: @str,
184186
vers: @str,

src/librustc/metadata/csearch.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use metadata::common::*;
1515
use metadata::cstore;
1616
use metadata::decoder;
1717
use metadata;
18-
use middle::{ty, resolve};
18+
use middle::ty;
1919

2020
use std::vec;
2121
use reader = extra::ebml::reader;
@@ -97,10 +97,10 @@ pub fn get_enum_variants(tcx: ty::ctxt, def: ast::def_id)
9797
}
9898

9999
/// Returns information about the given implementation.
100-
pub fn get_impl(cstore: @mut cstore::CStore, impl_def_id: ast::def_id)
101-
-> resolve::Impl {
102-
let cdata = cstore::get_crate_data(cstore, impl_def_id.crate);
103-
decoder::get_impl(cstore.intr, cdata, impl_def_id.node)
100+
pub fn get_impl(tcx: ty::ctxt, impl_def_id: ast::def_id)
101+
-> ty::Impl {
102+
let cdata = cstore::get_crate_data(tcx.cstore, impl_def_id.crate);
103+
decoder::get_impl(tcx.cstore.intr, cdata, impl_def_id.node, tcx)
104104
}
105105

106106
pub fn get_method(tcx: ty::ctxt, def: ast::def_id) -> ty::Method {

src/librustc/metadata/decoder.rs

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

2525
use std::hash::HashUtil;
2626
use std::int;
@@ -174,14 +174,6 @@ fn item_parent_item(d: ebml::Doc) -> Option<ast::def_id> {
174174
None
175175
}
176176

177-
fn translated_parent_item_opt(cnum: ast::crate_num, d: ebml::Doc) ->
178-
Option<ast::def_id> {
179-
let trait_did_opt = item_parent_item(d);
180-
do trait_did_opt.map |trait_did| {
181-
ast::def_id { crate: cnum, node: trait_did.node }
182-
}
183-
}
184-
185177
fn item_reqd_and_translated_parent_item(cnum: ast::crate_num,
186178
d: ebml::Doc) -> ast::def_id {
187179
let trait_did = item_parent_item(d).expect("item without parent");
@@ -193,6 +185,12 @@ fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id {
193185
return translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id));
194186
}
195187

188+
fn get_provided_source(d: ebml::Doc, cdata: cmd) -> Option<ast::def_id> {
189+
do reader::maybe_get_doc(d, tag_item_method_provided_source).map |doc| {
190+
translate_def_id(cdata, reader::with_doc_data(*doc, parse_def_id))
191+
}
192+
}
193+
196194
fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
197195
for reader::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| {
198196
if !f(reexport_doc) {
@@ -323,13 +321,19 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num)
323321
UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)),
324322
Fn => dl_def(ast::def_fn(did, ast::impure_fn)),
325323
ForeignFn => dl_def(ast::def_fn(did, ast::extern_fn)),
326-
UnsafeStaticMethod => {
327-
let trait_did_opt = translated_parent_item_opt(cnum, item);
328-
dl_def(ast::def_static_method(did, trait_did_opt, ast::unsafe_fn))
329-
}
330-
StaticMethod => {
331-
let trait_did_opt = translated_parent_item_opt(cnum, item);
332-
dl_def(ast::def_static_method(did, trait_did_opt, ast::impure_fn))
324+
StaticMethod | UnsafeStaticMethod => {
325+
let purity = if fam == UnsafeStaticMethod { ast::unsafe_fn } else
326+
{ ast::impure_fn };
327+
// def_static_method carries an optional field of its enclosing
328+
// *trait*, but not an inclosing Impl (if this is an inherent
329+
// static method). So we need to detect whether this is in
330+
// a trait or not, which we do through the mildly hacky
331+
// way of checking whether there is a trait_method_sort.
332+
let trait_did_opt = if reader::maybe_get_doc(
333+
item, tag_item_trait_method_sort).is_some() {
334+
Some(item_reqd_and_translated_parent_item(cnum, item))
335+
} else { None };
336+
dl_def(ast::def_static_method(did, trait_did_opt, purity))
333337
}
334338
Type | ForeignType => dl_def(ast::def_ty(did)),
335339
Mod => dl_def(ast::def_mod(did)),
@@ -795,34 +799,29 @@ fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ {
795799
}
796800

797801
fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc,
798-
base_tps: uint) -> ~[@resolve::MethodInfo] {
802+
tcx: ty::ctxt) -> ~[@ty::Method] {
799803
let mut rslt = ~[];
800804
for reader::tagged_docs(item, tag_item_impl_method) |doc| {
801805
let m_did = reader::with_doc_data(doc, parse_def_id);
802-
let mth_item = lookup_item(m_did.node, cdata.data);
803-
let explicit_self = get_explicit_self(mth_item);
804-
rslt.push(@resolve::MethodInfo {
805-
did: translate_def_id(cdata, m_did),
806-
n_tps: item_ty_param_count(mth_item) - base_tps,
807-
ident: item_name(intr, mth_item),
808-
explicit_self: explicit_self});
806+
rslt.push(@get_method(intr, cdata, m_did.node, tcx));
809807
}
808+
810809
rslt
811810
}
812811

813812
/// Returns information about the given implementation.
814-
pub fn get_impl(intr: @ident_interner, cdata: cmd, impl_id: ast::node_id)
815-
-> resolve::Impl {
813+
pub fn get_impl(intr: @ident_interner, cdata: cmd, impl_id: ast::node_id,
814+
tcx: ty::ctxt)
815+
-> ty::Impl {
816816
let data = cdata.data;
817817
let impl_item = lookup_item(impl_id, data);
818-
let base_tps = item_ty_param_count(impl_item);
819-
resolve::Impl {
818+
ty::Impl {
820819
did: ast::def_id {
821820
crate: cdata.cnum,
822821
node: impl_id,
823822
},
824823
ident: item_name(intr, impl_item),
825-
methods: item_impl_methods(intr, cdata, impl_item, base_tps),
824+
methods: item_impl_methods(intr, cdata, impl_item, tcx),
826825
}
827826
}
828827

@@ -842,13 +841,16 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
842841
{
843842
let method_doc = lookup_item(id, cdata.data);
844843
let def_id = item_def_id(method_doc, cdata);
844+
let container_id = item_reqd_and_translated_parent_item(cdata.cnum,
845+
method_doc);
845846
let name = item_name(intr, method_doc);
846847
let type_param_defs = item_ty_param_defs(method_doc, tcx, cdata,
847848
tag_item_method_tps);
848849
let transformed_self_ty = doc_transformed_self_ty(method_doc, tcx, cdata);
849850
let fty = doc_method_fty(method_doc, tcx, cdata);
850851
let vis = item_visibility(method_doc);
851852
let explicit_self = get_explicit_self(method_doc);
853+
let provided_source = get_provided_source(method_doc, cdata);
852854

853855
ty::Method::new(
854856
name,
@@ -860,7 +862,9 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
860862
fty,
861863
explicit_self,
862864
vis,
863-
def_id
865+
def_id,
866+
container_id,
867+
provided_source
864868
)
865869
}
866870

0 commit comments

Comments
 (0)