diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index 76568280282..64835a666fa 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -42,9 +42,6 @@ pub enum ObjectSafetyViolation<'tcx> { /// Reasons a method might not be object-safe. #[derive(Copy,Clone,Debug)] pub enum MethodViolationCode { - /// e.g., `fn(self)` - ByValueSelf, - /// e.g., `fn foo()` StaticMethod, @@ -204,17 +201,15 @@ fn object_safety_violations_for_method<'tcx>(tcx: &ty::ctxt<'tcx>, return None; } - // The method's first parameter must be something that derefs to - // `&self`. For now, we only accept `&self` and `Box`. + // The method's first parameter must be something that derefs (or + // autorefs) to `&self`. For now, we only accept `self`, `&self` + // and `Box`. match method.explicit_self { - ty::ByValueExplicitSelfCategory => { - return Some(MethodViolationCode::ByValueSelf); - } - ty::StaticExplicitSelfCategory => { return Some(MethodViolationCode::StaticMethod); } + ty::ByValueExplicitSelfCategory | ty::ByReferenceExplicitSelfCategory(..) | ty::ByBoxExplicitSelfCategory => { } diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 3666b69d1c6..630530cf11f 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -133,14 +133,6 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>, in the supertrait listing"); } - ObjectSafetyViolation::Method(method, MethodViolationCode::ByValueSelf) => { - tcx.sess.span_note( - span, - &format!("method `{}` has a receiver type of `Self`, \ - which cannot be used with a trait object", - method.name.user_string(tcx))); - } - ObjectSafetyViolation::Method(method, MethodViolationCode::StaticMethod) => { tcx.sess.span_note( span, diff --git a/src/test/compile-fail/fn-trait-formatting.rs b/src/test/compile-fail/fn-trait-formatting.rs index 71e1f7091b2..d682ef7d70c 100644 --- a/src/test/compile-fail/fn-trait-formatting.rs +++ b/src/test/compile-fail/fn-trait-formatting.rs @@ -15,8 +15,7 @@ fn needs_fn(x: F) where F: Fn(isize) -> isize {} fn main() { let _: () = (box |_: isize| {}) as Box; - //~^ ERROR object-safe - //~| ERROR mismatched types + //~^ ERROR mismatched types //~| expected `()` //~| found `Box` //~| expected () diff --git a/src/test/compile-fail/object-safety-by-value-self-use.rs b/src/test/compile-fail/object-safety-by-value-self-use.rs new file mode 100644 index 00000000000..1b20a902c9d --- /dev/null +++ b/src/test/compile-fail/object-safety-by-value-self-use.rs @@ -0,0 +1,29 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Check that while a trait with by-value self is object-safe, we +// can't actually invoke it from an object (yet...?). + +#![feature(rustc_attrs)] + +trait Bar { + fn bar(self); +} + +trait Baz { + fn baz(self: Self); +} + +fn use_bar(t: Box) { + t.bar() //~ ERROR cannot move a value of type Bar +} + +fn main() { } + diff --git a/src/test/compile-fail/object-safety-by-value-self.rs b/src/test/compile-fail/object-safety-by-value-self.rs index 71dedbe2799..976717249e8 100644 --- a/src/test/compile-fail/object-safety-by-value-self.rs +++ b/src/test/compile-fail/object-safety-by-value-self.rs @@ -8,9 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Check that we correctly prevent users from making trait objects -// from traits with a `fn(self)` method, unless `where Self : Sized` -// is present on the method. +// Check that a trait with by-value self is considered object-safe. + +#![feature(rustc_attrs)] +#![allow(dead_code)] trait Bar { fn bar(self); @@ -26,27 +27,19 @@ trait Quux { } fn make_bar(t: &T) -> &Bar { - t - //~^ ERROR `Bar` is not object-safe - //~| NOTE method `bar` has a receiver type of `Self` + t // legal } fn make_bar_explicit(t: &T) -> &Bar { - t as &Bar - //~^ ERROR `Bar` is not object-safe - //~| NOTE method `bar` has a receiver type of `Self` + t as &Bar // legal } fn make_baz(t: &T) -> &Baz { - t - //~^ ERROR `Baz` is not object-safe - //~| NOTE method `baz` has a receiver type of `Self` + t // legal } fn make_baz_explicit(t: &T) -> &Baz { - t as &Baz - //~^ ERROR `Baz` is not object-safe - //~| NOTE method `baz` has a receiver type of `Self` + t as &Baz // legal } fn make_quux(t: &T) -> &Quux { @@ -57,5 +50,6 @@ fn make_quux_explicit(t: &T) -> &Quux { t as &Quux } -fn main() { +#[rustc_error] +fn main() { //~ ERROR compilation successful }