From 3595f1f966227022164dc2e1e7b0d90e6d667899 Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Fri, 29 Jul 2011 13:42:02 -0700 Subject: [PATCH] Disallow overloading a method with one of different type. Closes #703. --- src/comp/middle/trans.rs | 5 ----- src/comp/middle/typeck.rs | 14 ++++++++++++-- ...g-type.rs => anon-obj-overriding-wrong-type.rs} | 10 +++------- 3 files changed, 15 insertions(+), 14 deletions(-) rename src/test/compile-fail/{anon-obj-overloading-wrong-type.rs => anon-obj-overriding-wrong-type.rs} (60%) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index bc473fd441e..48a7e9abbb1 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -6777,11 +6777,6 @@ fn create_vtbl(cx: @local_ctxt, sp: &span, outer_obj_ty: ty::t, // member of addtl_meths. Instead, we have to go // through addtl_meths and see if there's some method // in it that has the same name as fm. - - // FIXME (part of #543): We're only checking names - // here. If a method is replacing another, it also - // needs to have the same type, but this should - // probably be enforced in typechecking. for am: @ast::method in addtl_meths { if str::eq(am.node.ident, fm.ident) { ret none; } } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 4398d3a6063..dc32e006287 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -2427,19 +2427,29 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool { // Whenever an outer method overrides an inner, we need to remove // that inner from the type. Filter inner_obj_methods to remove // any methods that share a name with an outer method. - fn filtering_fn(m: &ty::method, + fn filtering_fn(ccx: @crate_ctxt, + m: &ty::method, outer_obj_methods: (@ast::method)[]) -> option::t[ty::method] { for om: @ast::method in outer_obj_methods { if str::eq(om.node.ident, m.ident) { + // We'd better be overriding with one of the same + // type. Check to make sure. + let new_type = ty_of_method(ccx, om); + if new_type != m { + ccx.tcx.sess.span_fatal( + om.span, + "Attempted to override method " + + m.ident + " with one of a different type"); + } ret none; } } ret some(m); } - let f = bind filtering_fn(_, ao.methods); + let f = bind filtering_fn(fcx.ccx, _, ao.methods); inner_obj_methods = std::ivec::filter_map[ty::method, ty::method](f, inner_obj_methods); diff --git a/src/test/compile-fail/anon-obj-overloading-wrong-type.rs b/src/test/compile-fail/anon-obj-overriding-wrong-type.rs similarity index 60% rename from src/test/compile-fail/anon-obj-overloading-wrong-type.rs rename to src/test/compile-fail/anon-obj-overriding-wrong-type.rs index 604c4560762..5f8fa86e1c1 100644 --- a/src/test/compile-fail/anon-obj-overloading-wrong-type.rs +++ b/src/test/compile-fail/anon-obj-overriding-wrong-type.rs @@ -1,7 +1,4 @@ -//xfail-stage0 -//xfail-stage1 -//xfail-stage2 -//xfail-stage3 +//error-pattern: with one of a different type use std; fn main() { @@ -13,8 +10,7 @@ fn main() { let my_a = a(); - // This compiles and shouldn't. You should only be able to - // overload a method with one of the same type. Issue #703. + // Attempting to override a method with one of a different type. let my_b = obj () { fn foo() -> str { ret "hello"; } @@ -23,4 +19,4 @@ fn main() { }; log_err my_b.foo(); -} \ No newline at end of file +}