diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 1b866501b8ea1..0197ee82c7740 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -39,6 +39,8 @@ pub unsafe trait Send : MarkerTrait { // empty. } +unsafe impl Send for .. { } + impl !Send for *const T { } impl !Send for *mut T { } impl !Send for Managed { } @@ -203,6 +205,8 @@ pub unsafe trait Sync : MarkerTrait { // Empty } +unsafe impl Sync for .. { } + impl !Sync for *const T { } impl !Sync for *mut T { } impl !Sync for Managed { } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 99c35c6e54258..c4fcf882cfb03 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -5980,10 +5980,7 @@ pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc { pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool { populate_implementations_for_trait_if_necessary(tcx, trait_def_id); - match tcx.lang_items.to_builtin_kind(trait_def_id) { - Some(BoundSend) | Some(BoundSync) => true, - _ => tcx.traits_with_default_impls.borrow().contains_key(&trait_def_id), - } + tcx.traits_with_default_impls.borrow().contains_key(&trait_def_id) } /// Records a trait-to-implementation mapping. diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 867dea9588568..e4926b119d5db 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/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 0a9980c892527..f5e891a9dd643 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -563,6 +563,13 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } } + ast::ItemDefaultImpl(..) => { + self.gate_feature("optin_builtin_traits", + i.span, + "default trait implementations are experimental \ + and possibly buggy"); + } + ast::ItemImpl(_, polarity, _, _, _, _) => { match polarity { ast::ImplPolarity::Negative => { diff --git a/src/test/compile-fail/coherence-default-trait-impl.rs b/src/test/compile-fail/coherence-default-trait-impl.rs index 6bcbefb904d9e..a5b317307379e 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() {} diff --git a/src/test/run-make/rustdoc-default-impl/foo.rs b/src/test/run-make/rustdoc-default-impl/foo.rs index 08f3bd10e74a7..4c30c7b22a60d 100644 --- a/src/test/run-make/rustdoc-default-impl/foo.rs +++ b/src/test/run-make/rustdoc-default-impl/foo.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(optin_builtin_traits)] + pub mod bar { use std::marker;