diff options
| author | Flavio Percoco <flaper87@gmail.com> | 2015-03-11 18:53:55 -0500 |
|---|---|---|
| committer | Flavio Percoco <flaper87@gmail.com> | 2015-03-20 16:43:11 +0100 |
| commit | 38dbcb2e3718eab4bac9f5a3ec8226d7ee4f40a7 (patch) | |
| tree | f315ac84816c98b0251edcf98e1f3f92ff182fed | |
| parent | 01d24297eb6fe16abdf7869c60519650e3490faf (diff) | |
| download | rust-38dbcb2e3718eab4bac9f5a3ec8226d7ee4f40a7.tar.gz rust-38dbcb2e3718eab4bac9f5a3ec8226d7ee4f40a7.zip | |
Check trait unsafety for defaulted traits
| -rw-r--r-- | src/libcore/marker.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/coherence/unsafety.rs | 93 | ||||
| -rw-r--r-- | src/test/compile-fail/coherence-default-trait-impl.rs | 10 |
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() {} |
