Export information about used default methods instead of regenerating it. Closes #7862.
This commit is contained in:
parent
8e714fa8d8
commit
002bfd7966
@ -185,6 +185,12 @@ fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id {
|
||||
return translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id));
|
||||
}
|
||||
|
||||
fn get_provided_source(d: ebml::Doc, cdata: cmd) -> Option<ast::def_id> {
|
||||
do reader::maybe_get_doc(d, tag_item_method_provided_source).map |doc| {
|
||||
translate_def_id(cdata, reader::with_doc_data(*doc, parse_def_id))
|
||||
}
|
||||
}
|
||||
|
||||
fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
|
||||
for reader::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| {
|
||||
if !f(reexport_doc) {
|
||||
@ -844,6 +850,7 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
||||
let fty = doc_method_fty(method_doc, tcx, cdata);
|
||||
let vis = item_visibility(method_doc);
|
||||
let explicit_self = get_explicit_self(method_doc);
|
||||
let provided_source = get_provided_source(method_doc, cdata);
|
||||
|
||||
ty::Method::new(
|
||||
name,
|
||||
@ -857,7 +864,7 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
||||
vis,
|
||||
def_id,
|
||||
container_id,
|
||||
None
|
||||
provided_source
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -650,6 +650,16 @@ fn encode_method_sort(ebml_w: &mut writer::Encoder, sort: char) {
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_provided_source(ebml_w: &mut writer::Encoder,
|
||||
source_opt: Option<def_id>) {
|
||||
for source_opt.iter().advance |source| {
|
||||
ebml_w.start_tag(tag_item_method_provided_source);
|
||||
let s = def_to_str(*source);
|
||||
ebml_w.writer.write(s.as_bytes());
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns an index of items in this class */
|
||||
fn encode_info_for_struct(ecx: &EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
@ -726,6 +736,7 @@ fn encode_method_ty_fields(ecx: &EncodeContext,
|
||||
}
|
||||
_ => encode_family(ebml_w, purity_fn_family(purity))
|
||||
}
|
||||
encode_provided_source(ebml_w, method_ty.provided_source);
|
||||
}
|
||||
|
||||
fn encode_info_for_method(ecx: &EncodeContext,
|
||||
@ -987,7 +998,6 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||
_ => {}
|
||||
}
|
||||
for imp.methods.iter().advance |method| {
|
||||
if method.provided_source.is_some() { loop; }
|
||||
ebml_w.start_tag(tag_item_impl_method);
|
||||
let s = def_to_str(method.def_id);
|
||||
ebml_w.writer.write(s.as_bytes());
|
||||
@ -1005,16 +1015,24 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||
let mut impl_path = vec::append(~[], path);
|
||||
impl_path.push(ast_map::path_name(item.ident));
|
||||
|
||||
for ast_methods.iter().advance |ast_method| {
|
||||
let m = ty::method(ecx.tcx, local_def(ast_method.id));
|
||||
// Iterate down the methods, emitting them. We rely on the
|
||||
// assumption that all of the actually implemented methods
|
||||
// appear first in the impl structure, in the same order they do
|
||||
// in the ast. This is a little sketchy.
|
||||
let num_implemented_methods = ast_methods.len();
|
||||
for imp.methods.iter().enumerate().advance |(i, m)| {
|
||||
let ast_method = if i < num_implemented_methods {
|
||||
Some(ast_methods[i])
|
||||
} else { None };
|
||||
|
||||
index.push(entry {val: m.def_id.node, pos: ebml_w.writer.tell()});
|
||||
encode_info_for_method(ecx,
|
||||
ebml_w,
|
||||
m,
|
||||
*m,
|
||||
impl_path,
|
||||
false,
|
||||
item.id,
|
||||
Some(*ast_method));
|
||||
ast_method)
|
||||
}
|
||||
}
|
||||
item_trait(_, ref super_traits, ref ms) => {
|
||||
|
@ -664,7 +664,7 @@ impl CoherenceChecker {
|
||||
impls_seen: &mut HashSet<def_id>,
|
||||
impl_def_id: def_id) {
|
||||
let tcx = self.crate_context.tcx;
|
||||
let implementation = csearch::get_impl(tcx, impl_def_id);
|
||||
let implementation = @csearch::get_impl(tcx, impl_def_id);
|
||||
|
||||
debug!("coherence: adding impl from external crate: %s",
|
||||
ty::item_path_str(tcx, implementation.did));
|
||||
@ -697,21 +697,16 @@ impl CoherenceChecker {
|
||||
}
|
||||
|
||||
// Record all the trait methods.
|
||||
let mut implementation = @implementation;
|
||||
for associated_traits.iter().advance |trait_ref| {
|
||||
// XXX(sully): We could probably avoid this copy if there are no
|
||||
// default methods.
|
||||
let mut methods = implementation.methods.clone();
|
||||
self.instantiate_default_methods(implementation.did,
|
||||
*trait_ref,
|
||||
&mut methods);
|
||||
self.add_trait_impl(trait_ref.def_id, implementation);
|
||||
}
|
||||
|
||||
implementation = @Impl {
|
||||
methods: methods,
|
||||
..*implementation
|
||||
};
|
||||
|
||||
self.add_trait_impl(trait_ref.def_id, implementation);
|
||||
// For any methods that use a default implementation, add them to
|
||||
// the map. This is a bit unfortunate.
|
||||
for implementation.methods.iter().advance |method| {
|
||||
for method.provided_source.iter().advance |source| {
|
||||
tcx.provided_method_sources.insert(method.def_id, *source);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the implementation to the mapping from implementation to base
|
||||
|
17
src/test/auxiliary/trait_default_method_xc_aux_2.rs
Normal file
17
src/test/auxiliary/trait_default_method_xc_aux_2.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// aux-build:trait_default_method_xc_aux.rs
|
||||
|
||||
extern mod aux(name = "trait_default_method_xc_aux");
|
||||
use aux::A;
|
||||
|
||||
pub struct a_struct { x: int }
|
||||
|
||||
impl A for a_struct {
|
||||
fn f(&self) -> int { 10 }
|
||||
}
|
||||
|
||||
// This function will need to get inlined, and badness may result.
|
||||
pub fn welp<A>(x: A) -> A {
|
||||
let a = a_struct { x: 0 };
|
||||
a.g();
|
||||
x
|
||||
}
|
25
src/test/run-pass/trait-default-method-xc-2.rs
Normal file
25
src/test/run-pass/trait-default-method-xc-2.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// xfail-fast
|
||||
// aux-build:trait_default_method_xc_aux.rs
|
||||
// aux-build:trait_default_method_xc_aux_2.rs
|
||||
|
||||
|
||||
extern mod aux(name = "trait_default_method_xc_aux");
|
||||
extern mod aux2(name = "trait_default_method_xc_aux_2");
|
||||
use aux::A;
|
||||
use aux2::{a_struct, welp};
|
||||
|
||||
|
||||
fn main () {
|
||||
|
||||
let a = a_struct { x: 0 };
|
||||
let b = a_struct { x: 1 };
|
||||
|
||||
assert_eq!(0i.g(), 10);
|
||||
assert_eq!(a.g(), 10);
|
||||
assert_eq!(a.h(), 11);
|
||||
assert_eq!(b.g(), 10);
|
||||
assert_eq!(b.h(), 11);
|
||||
assert_eq!(A::lurr(&a, &b), 21);
|
||||
|
||||
welp(&0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user