about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-02-23 15:27:55 -0500
committerNiko Matsakis <niko@alum.mit.edu>2015-02-23 15:28:27 -0500
commitfd9f7da68ed23934ace0ae86b39d47f6078011a0 (patch)
tree87be8792470f52f715ae1d82595fe699d1c249aa
parentfe512dacc84932de7eb044c0961598f9203446b9 (diff)
downloadrust-fd9f7da68ed23934ace0ae86b39d47f6078011a0.tar.gz
rust-fd9f7da68ed23934ace0ae86b39d47f6078011a0.zip
Make traits with by-value-self be considered object safe.
-rw-r--r--src/librustc/middle/traits/object_safety.rs13
-rw-r--r--src/librustc_typeck/check/vtable.rs8
-rw-r--r--src/test/compile-fail/fn-trait-formatting.rs3
-rw-r--r--src/test/compile-fail/object-safety-by-value-self-use.rs29
-rw-r--r--src/test/compile-fail/object-safety-by-value-self.rs26
5 files changed, 44 insertions, 35 deletions
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<Self>`.
+    // The method's first parameter must be something that derefs (or
+    // autorefs) to `&self`. For now, we only accept `self`, `&self`
+    // and `Box<Self>`.
     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<F>(x: F) where F: Fn(isize) -> isize {}
 
 fn main() {
     let _: () = (box |_: isize| {}) as Box<FnOnce(isize)>;
-    //~^ ERROR object-safe
-    //~| ERROR mismatched types
+    //~^ ERROR mismatched types
     //~| expected `()`
     //~| found `Box<core::ops::FnOnce(isize)>`
     //~| 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Bar>) {
+    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: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:Bar>(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: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:Baz>(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:Quux>(t: &T) -> &Quux {
@@ -57,5 +50,6 @@ fn make_quux_explicit<T:Quux>(t: &T) -> &Quux {
     t as &Quux
 }
 
-fn main() {
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
 }