From b5f171f03d57f4a1d5c2773b07d90a8e8ea14fca Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 15 Nov 2012 18:04:25 -0800 Subject: [PATCH] Make staticness mismatch a fatal error Exit with a fatal error, instead of recording a non-fatal error, when we encounter an impl method that's static when its corresponding trait method isn't (or vice versa). This is because code later on in the typechecker will expect the staticness of the two methods to be consistent and ICE otherwise. As per #3969 --- src/librustc/middle/typeck/collect.rs | 29 ++++++++++++++------ src/test/compile-fail/issue-3969.rs | 15 ++++++++++ src/test/compile-fail/staticness-mismatch.rs | 2 +- 3 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 src/test/compile-fail/issue-3969.rs diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 4faf34b3078ce..62ec991f77971 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -296,11 +296,27 @@ fn compare_impl_method(tcx: ty::ctxt, // implementable by an `&const self` method (the impl assumes less // than the trait provides). if impl_m.self_ty != trait_m.self_ty { - tcx.sess.span_err( - cm.span, - fmt!("method `%s`'s self type does \ - not match the trait method's \ - self type", tcx.sess.str_of(impl_m.ident))); + if impl_m.self_ty == ast::sty_static { + // Needs to be a fatal error because otherwise, + // method::transform_self_type_for_method ICEs + tcx.sess.span_fatal(cm.span, + fmt!("method `%s` is declared as \ + static in its impl, but not in \ + its trait", tcx.sess.str_of(impl_m.ident))); + } + else if trait_m.self_ty == ast::sty_static { + tcx.sess.span_fatal(cm.span, + fmt!("method `%s` is declared as \ + static in its trait, but not in \ + its impl", tcx.sess.str_of(impl_m.ident))); + } + else { + tcx.sess.span_err( + cm.span, + fmt!("method `%s`'s self type does \ + not match the trait method's \ + self type", tcx.sess.str_of(impl_m.ident))); + } } if impl_m.tps.len() != trait_m.tps.len() { @@ -348,9 +364,6 @@ fn compare_impl_method(tcx: ty::ctxt, pluralize(trait_param_bounds.len(), ~"bound"))); return; } - // tjc: I'm mildly worried that there's something I'm - // not checking that require_same_types doesn't catch, - // but I can't figure out what. } // Replace any references to the self region in the self type with diff --git a/src/test/compile-fail/issue-3969.rs b/src/test/compile-fail/issue-3969.rs new file mode 100644 index 0000000000000..f82d2a45b10d6 --- /dev/null +++ b/src/test/compile-fail/issue-3969.rs @@ -0,0 +1,15 @@ +struct Bike { + name: ~str, +} + +trait BikeMethods { + fn woops(&const self) -> ~str; +} + +pub impl Bike : BikeMethods { + static fn woops(&const self) -> ~str { ~"foo" } + //~^ ERROR method `woops` is declared as static in its impl, but not in its trait +} + +pub fn main() { +} diff --git a/src/test/compile-fail/staticness-mismatch.rs b/src/test/compile-fail/staticness-mismatch.rs index 51c7a81986033..1edc668e2f320 100644 --- a/src/test/compile-fail/staticness-mismatch.rs +++ b/src/test/compile-fail/staticness-mismatch.rs @@ -4,7 +4,7 @@ trait foo { } impl int: foo { - fn bar() {} //~ ERROR self type does not match the trait method's + fn bar() {} //~ ERROR method `bar` is declared as static in its trait, but not in its impl } fn main() {}