Skip to content

Commit a159f85

Browse files
committed
Properly translate calls to default methods in a number of cases. Closes #4350.
1 parent 135ba94 commit a159f85

File tree

2 files changed

+23
-50
lines changed

2 files changed

+23
-50
lines changed

src/librustc/middle/trans/meth.rs

Lines changed: 22 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,9 @@ pub fn trans_method_callee(bcx: block,
207207
let method_name =
208208
ty::trait_method(tcx, trait_id, method_index).ident;
209209
let method_id =
210-
method_with_name(bcx.ccx(), impl_def_id, method_name);
210+
method_with_name_or_default(bcx.ccx(),
211+
impl_def_id,
212+
method_name);
211213
origin = typeck::method_static(method_id);
212214
}
213215
typeck::method_super(trait_id, method_index) => {
@@ -229,9 +231,10 @@ pub fn trans_method_callee(bcx: block,
229231
ty::method(tcx, supertrait_method_def_ids[method_index]).ident;
230232
// Now that we know the impl ID, we can look up the method
231233
// ID from its name
232-
origin = typeck::method_static(method_with_name(bcx.ccx(),
233-
impl_id,
234-
method_name));
234+
origin = typeck::method_static(
235+
method_with_name_or_default(bcx.ccx(),
236+
impl_id,
237+
method_name));
235238
}
236239
typeck::method_static(*) | typeck::method_param(*) |
237240
typeck::method_trait(*) => {}
@@ -345,7 +348,9 @@ pub fn trans_static_method_callee(bcx: block,
345348
typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
346349
assert!(rcvr_substs.all(|t| !ty::type_needs_infer(*t)));
347350

348-
let mth_id = method_with_name(bcx.ccx(), impl_did, mname);
351+
let mth_id = method_with_name_or_default(bcx.ccx(),
352+
impl_did,
353+
mname);
349354
let callee_substs = combine_impl_and_methods_tps(
350355
bcx, mth_id, impl_did, callee_id, *rcvr_substs);
351356
let callee_origins = combine_impl_and_methods_origins(
@@ -374,23 +379,6 @@ pub fn method_from_methods(ms: &[@ast::method], name: ast::ident)
374379
ms.find(|m| m.ident == name).map(|m| ast_util::local_def(m.id))
375380
}
376381

377-
pub fn method_with_name(ccx: @CrateContext, impl_id: ast::def_id,
378-
name: ast::ident) -> ast::def_id {
379-
if impl_id.crate == ast::local_crate {
380-
match ccx.tcx.items.get_copy(&impl_id.node) {
381-
ast_map::node_item(@ast::item {
382-
node: ast::item_impl(_, _, _, ref ms),
383-
_
384-
}, _) => {
385-
method_from_methods(*ms, name).get()
386-
}
387-
_ => fail!("method_with_name")
388-
}
389-
} else {
390-
csearch::get_impl_method(ccx.sess.cstore, impl_id, name)
391-
}
392-
}
393-
394382
pub fn method_with_name_or_default(ccx: @CrateContext,
395383
impl_id: ast::def_id,
396384
name: ast::ident) -> ast::def_id {
@@ -770,17 +758,17 @@ pub fn vtable_id(ccx: @CrateContext,
770758

771759
/// Creates a returns a dynamic vtable for the given type and vtable origin.
772760
/// This is used only for objects.
773-
pub fn get_vtable(ccx: @CrateContext,
761+
pub fn get_vtable(bcx: block,
774762
self_ty: ty::t,
775763
origin: typeck::vtable_origin)
776764
-> ValueRef {
777-
let hash_id = vtable_id(ccx, &origin);
778-
match ccx.vtables.find(&hash_id) {
765+
let hash_id = vtable_id(bcx.ccx(), &origin);
766+
match bcx.ccx().vtables.find(&hash_id) {
779767
Some(&val) => val,
780768
None => {
781769
match origin {
782770
typeck::vtable_static(id, substs, sub_vtables) => {
783-
make_impl_vtable(ccx, id, self_ty, substs, sub_vtables)
771+
make_impl_vtable(bcx, id, self_ty, substs, sub_vtables)
784772
}
785773
_ => fail!("get_vtable: expected a static origin"),
786774
}
@@ -814,12 +802,13 @@ pub fn make_vtable(ccx: @CrateContext,
814802
}
815803

816804
/// Generates a dynamic vtable for objects.
817-
pub fn make_impl_vtable(ccx: @CrateContext,
805+
pub fn make_impl_vtable(bcx: block,
818806
impl_id: ast::def_id,
819807
self_ty: ty::t,
820808
substs: ~[ty::t],
821809
vtables: typeck::vtable_res)
822810
-> ValueRef {
811+
let ccx = bcx.ccx();
823812
let _icx = ccx.insn_ctxt("impl::make_impl_vtable");
824813
let tcx = ccx.tcx;
825814

@@ -829,9 +818,6 @@ pub fn make_impl_vtable(ccx: @CrateContext,
829818
make a vtable for a type impl!")
830819
};
831820

832-
let has_tps =
833-
!ty::lookup_item_type(ccx.tcx, impl_id).generics.type_param_defs.is_empty();
834-
835821
let trait_method_def_ids = ty::trait_method_def_ids(tcx, trt_id);
836822
let methods = do trait_method_def_ids.map |method_def_id| {
837823
let im = ty::method(tcx, *method_def_id);
@@ -846,22 +832,11 @@ pub fn make_impl_vtable(ccx: @CrateContext,
846832
} else {
847833
debug!("(making impl vtable) adding method to vtable: %s",
848834
*tcx.sess.str_of(im.ident));
849-
let mut m_id = method_with_name(ccx, impl_id, im.ident);
850-
if has_tps {
851-
// If the method is in another crate, need to make an inlined
852-
// copy first
853-
if m_id.crate != ast::local_crate {
854-
// XXX: Set impl ID here?
855-
m_id = inline::maybe_instantiate_inline(ccx, m_id, true);
856-
}
857-
let (val, _) = monomorphize::monomorphic_fn(ccx, m_id, substs,
858-
Some(vtables), None, None);
859-
val
860-
} else if m_id.crate == ast::local_crate {
861-
get_item_val(ccx, m_id.node)
862-
} else {
863-
trans_external_path(ccx, m_id, fty)
864-
}
835+
let m_id = method_with_name_or_default(ccx, impl_id, im.ident);
836+
837+
trans_fn_ref_with_vtables(bcx, m_id, 0,
838+
substs, Some(vtables)).llfn
839+
865840
}
866841
};
867842

@@ -903,7 +878,7 @@ pub fn trans_trait_cast(bcx: block,
903878
// Store the vtable into the pair or triple.
904879
let orig = /*bad*/copy ccx.maps.vtable_map.get(&id)[0];
905880
let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, orig);
906-
let vtable = get_vtable(bcx.ccx(), v_ty, orig);
881+
let vtable = get_vtable(bcx, v_ty, orig);
907882
Store(bcx, vtable, PointerCast(bcx,
908883
GEPi(bcx, lldest, [0u, abi::trt_field_vtable]),
909884
T_ptr(val_ty(vtable))));

src/test/run-pass/traits-default-method-self.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//xfail-test
12-
13-
// Currently failing with an ICE in trans. (FIXME: #4350)
11+
#[allow(default_methods)];
1412

1513
trait Cat {
1614
fn meow(&self) -> bool;

0 commit comments

Comments
 (0)