Skip to content

Commit 3243144

Browse files
committed
Fix a bug that was interfering with method overriding. Issue #543.
Previously, we were creating both a normal vtable entry and a forwarding function for overriding methods, when they should have just gotten a vtable entry. This patch fixes that.
1 parent 301f6aa commit 3243144

File tree

2 files changed

+38
-35
lines changed

2 files changed

+38
-35
lines changed

src/comp/middle/trans.rs

+36-23
Original file line numberDiff line numberDiff line change
@@ -8152,34 +8152,47 @@ fn create_vtbl(@local_ctxt cx, &span sp, TypeRef llself_ty, ty::t self_ty,
81528152
}
81538153
}
81548154

8155-
// Now, filter out any methods that are being replaced.
8156-
fn filtering_fn(&vtbl_mthd m, vec[vtbl_mthd] addtl_meths) ->
8157-
option::t[vtbl_mthd] {
8158-
8159-
let option::t[vtbl_mthd] rslt;
8160-
if (std::vec::member[vtbl_mthd](m, addtl_meths)) {
8161-
rslt = none;
8162-
} else {
8163-
rslt = some(m);
8155+
// Now, filter out any methods that we don't need forwarding slots
8156+
// for, because they're being replaced.
8157+
fn filtering_fn(@local_ctxt cx, &vtbl_mthd m,
8158+
(@ast::method)[] addtl_meths)
8159+
-> option::t[vtbl_mthd] {
8160+
8161+
alt (m) {
8162+
case (fwding_mthd(?fm)) {
8163+
// Since fm is a fwding_mthd, and we're checking to
8164+
// see if it's in addtl_meths (which only contains
8165+
// normal_mthds), we can't just check if fm is a
8166+
// member of addtl_meths. Instead, we have to go
8167+
// through addtl_meths and see if there's some method
8168+
// in it that has the same name as fm.
8169+
8170+
// FIXME (part of #543): We're only checking names
8171+
// here. If a method is replacing another, it also
8172+
// needs to have the same type, but this should
8173+
// probably be enforced in typechecking.
8174+
for (@ast::method am in addtl_meths) {
8175+
if (str::eq(am.node.ident, fm.ident)) {
8176+
ret none;
8177+
}
8178+
}
8179+
ret some(fwding_mthd(fm));
8180+
}
8181+
case (normal_mthd(_)) {
8182+
// Should never happen.
8183+
cx.ccx.sess.bug("create_vtbl(): shouldn't be any"
8184+
+ " normal_mthds in meths here");
8185+
}
81648186
}
8165-
ret rslt;
81668187
}
8167-
8168-
// NB: addtl_meths is just like ob.methods except that it's of
8169-
// type vec[vtbl_mthd], not vec[@ast::method].
8170-
let vec[vtbl_mthd] addtl_meths = [];
8171-
for (@ast::method m in ob.methods) {
8172-
addtl_meths += [normal_mthd(m)];
8173-
}
8174-
auto f = bind filtering_fn(_, addtl_meths);
8175-
8176-
// Filter out any methods that we don't need forwarding slots for
8177-
// (namely, those that are being replaced).
8188+
auto f = bind filtering_fn(cx, _, ob.methods);
81788189
meths = std::vec::filter_map[vtbl_mthd, vtbl_mthd](f, meths);
81798190

81808191
// And now add the additional ones (both replacements and entirely
8181-
// new ones).
8182-
meths += addtl_meths;
8192+
// new ones). These'll just be normal methods.
8193+
for (@ast::method m in ob.methods) {
8194+
meths += [normal_mthd(m)];
8195+
}
81838196
}
81848197
}
81858198

src/test/run-pass/anon-obj-overloading.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ fn main() {
1616

1717
auto my_a = a();
1818

19-
// An anonymous object that overloads the 'foo' method. Adding
20-
// support for this is issue #543 (making this work in the
21-
// presence of self-calls is the tricky part).
19+
// An anonymous object that overloads the 'foo' method.
2220
auto my_b = obj() {
2321
fn foo() -> int {
2422
ret 3;
@@ -27,15 +25,7 @@ fn main() {
2725
with my_a
2826
};
2927

28+
// FIXME: raises a valgrind error (issue #543).
3029
assert (my_b.foo() == 3);
31-
32-
// The tricky part -- have to be sure to tie the knot in the right
33-
// place, so that bar() knows about the new foo().
34-
35-
// Right now, this just fails with "unknown method 'bar' of obj",
36-
// but that's the easier of our worries; that'll be fixed when
37-
// issue #539 is fixed. The bigger problem will be when we do
38-
// 'fall through' to bar() on the original object -- then we have
39-
// to be sure that self refers to the extended object.
4030
assert (my_b.bar() == 3);
4131
}

0 commit comments

Comments
 (0)