about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlavio Percoco <flaper87@gmail.com>2015-03-11 18:53:55 -0500
committerFlavio Percoco <flaper87@gmail.com>2015-03-20 16:43:11 +0100
commit38dbcb2e3718eab4bac9f5a3ec8226d7ee4f40a7 (patch)
treef315ac84816c98b0251edcf98e1f3f92ff182fed
parent01d24297eb6fe16abdf7869c60519650e3490faf (diff)
downloadrust-38dbcb2e3718eab4bac9f5a3ec8226d7ee4f40a7.tar.gz
rust-38dbcb2e3718eab4bac9f5a3ec8226d7ee4f40a7.zip
Check trait unsafety for defaulted traits
-rw-r--r--src/libcore/marker.rs4
-rw-r--r--src/librustc_typeck/coherence/unsafety.rs93
-rw-r--r--src/test/compile-fail/coherence-default-trait-impl.rs10
3 files changed, 64 insertions, 43 deletions
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index e980858c443..0197ee82c77 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -39,7 +39,7 @@ pub unsafe trait Send : MarkerTrait {
     // empty.
 }
 
-impl Send for .. { }
+unsafe impl Send for .. { }
 
 impl<T> !Send for *const T { }
 impl<T> !Send for *mut T { }
@@ -205,7 +205,7 @@ pub unsafe trait Sync : MarkerTrait {
     // Empty
 }
 
-impl Sync for .. { }
+unsafe impl Sync for .. { }
 
 impl<T> !Sync for *const T { }
 impl<T> !Sync for *mut T { }
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index 867dea95885..e4926b119d5 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -27,55 +27,66 @@ struct UnsafetyChecker<'cx, 'tcx:'cx> {
     tcx: &'cx ty::ctxt<'tcx>
 }
 
-impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
-    fn visit_item(&mut self, item: &'v ast::Item) {
-        match item.node {
-            ast::ItemImpl(unsafety, polarity, _, _, _, _) => {
-                match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) {
-                    None => {
-                        // Inherent impl.
-                        match unsafety {
-                            ast::Unsafety::Normal => { /* OK */ }
-                            ast::Unsafety::Unsafe => {
-                                span_err!(self.tcx.sess, item.span, E0197,
-                                    "inherent impls cannot be declared as unsafe");
-                            }
-                        }
+impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
+    fn check_unsafety_coherence(&mut self, item: &'v ast::Item,
+                                unsafety: ast::Unsafety,
+                                polarity: ast::ImplPolarity) {
+        match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) {
+            None => {
+                // Inherent impl.
+                match unsafety {
+                    ast::Unsafety::Normal => { /* OK */ }
+                    ast::Unsafety::Unsafe => {
+                        span_err!(self.tcx.sess, item.span, E0197,
+                                  "inherent impls cannot be declared as unsafe");
                     }
+                }
+            }
 
-                    Some(trait_ref) => {
-                        let trait_def = ty::lookup_trait_def(self.tcx, trait_ref.def_id);
-                        match (trait_def.unsafety, unsafety, polarity) {
-                            (ast::Unsafety::Unsafe,
-                             ast::Unsafety::Unsafe, ast::ImplPolarity::Negative) => {
-                                span_err!(self.tcx.sess, item.span, E0198,
-                                    "negative implementations are not unsafe");
-                            }
+            Some(trait_ref) => {
+                let trait_def = ty::lookup_trait_def(self.tcx, trait_ref.def_id);
+                match (trait_def.unsafety, unsafety, polarity) {
+                    (ast::Unsafety::Unsafe,
+                     ast::Unsafety::Unsafe, ast::ImplPolarity::Negative) => {
+                        span_err!(self.tcx.sess, item.span, E0198,
+                                  "negative implementations are not unsafe");
+                    }
 
-                            (ast::Unsafety::Normal, ast::Unsafety::Unsafe, _) => {
-                                span_err!(self.tcx.sess, item.span, E0199,
-                                    "implementing the trait `{}` is not unsafe",
-                                            trait_ref.user_string(self.tcx));
-                            }
+                    (ast::Unsafety::Normal, ast::Unsafety::Unsafe, _) => {
+                        span_err!(self.tcx.sess, item.span, E0199,
+                                  "implementing the trait `{}` is not unsafe",
+                                  trait_ref.user_string(self.tcx));
+                    }
 
-                            (ast::Unsafety::Unsafe,
-                             ast::Unsafety::Normal, ast::ImplPolarity::Positive) => {
-                                span_err!(self.tcx.sess, item.span, E0200,
-                                    "the trait `{}` requires an `unsafe impl` declaration",
-                                            trait_ref.user_string(self.tcx));
-                            }
+                    (ast::Unsafety::Unsafe,
+                     ast::Unsafety::Normal, ast::ImplPolarity::Positive) => {
+                        span_err!(self.tcx.sess, item.span, E0200,
+                                  "the trait `{}` requires an `unsafe impl` declaration",
+                                  trait_ref.user_string(self.tcx));
+                    }
 
-                            (ast::Unsafety::Unsafe,
-                             ast::Unsafety::Normal, ast::ImplPolarity::Negative) |
-                            (ast::Unsafety::Unsafe,
-                             ast::Unsafety::Unsafe, ast::ImplPolarity::Positive) |
-                            (ast::Unsafety::Normal, ast::Unsafety::Normal, _) => {
-                                /* OK */
-                            }
-                        }
+                    (ast::Unsafety::Unsafe,
+                     ast::Unsafety::Normal, ast::ImplPolarity::Negative) |
+                    (ast::Unsafety::Unsafe,
+                     ast::Unsafety::Unsafe, ast::ImplPolarity::Positive) |
+                    (ast::Unsafety::Normal, ast::Unsafety::Normal, _) => {
+                        /* OK */
                     }
                 }
             }
+        }
+    }
+}
+
+impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
+    fn visit_item(&mut self, item: &'v ast::Item) {
+        match item.node {
+            ast::ItemDefaultImpl(unsafety, _) => {
+                self.check_unsafety_coherence(item, unsafety, ast::ImplPolarity::Positive);
+            }
+            ast::ItemImpl(unsafety, polarity, _, _, _, _) => {
+                self.check_unsafety_coherence(item, unsafety, polarity);
+            }
             _ => { }
         }
 
diff --git a/src/test/compile-fail/coherence-default-trait-impl.rs b/src/test/compile-fail/coherence-default-trait-impl.rs
index 6bcbefb904d..a5b31730737 100644
--- a/src/test/compile-fail/coherence-default-trait-impl.rs
+++ b/src/test/compile-fail/coherence-default-trait-impl.rs
@@ -21,4 +21,14 @@ impl MyTrait for .. {}
 impl MyTrait for .. {}
 //~^ ERROR conflicting implementations for trait `MyTrait`
 
+trait MySafeTrait: MarkerTrait {}
+
+unsafe impl MySafeTrait for .. {}
+//~^ ERROR implementing the trait `MySafeTrait` is not unsafe
+
+unsafe trait MyUnsafeTrait: MarkerTrait {}
+
+impl MyUnsafeTrait for .. {}
+//~^ ERROR the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
+
 fn main() {}