rollup merge of #23211: FlaPer87/oibit-send-and-friends
Fixes #23225 r? @nikomatsakis
This commit is contained in:
@@ -39,6 +39,8 @@ pub unsafe trait Send : MarkerTrait {
|
|||||||
// empty.
|
// empty.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for .. { }
|
||||||
|
|
||||||
impl<T> !Send for *const T { }
|
impl<T> !Send for *const T { }
|
||||||
impl<T> !Send for *mut T { }
|
impl<T> !Send for *mut T { }
|
||||||
impl !Send for Managed { }
|
impl !Send for Managed { }
|
||||||
@@ -203,6 +205,8 @@ pub unsafe trait Sync : MarkerTrait {
|
|||||||
// Empty
|
// Empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Sync for .. { }
|
||||||
|
|
||||||
impl<T> !Sync for *const T { }
|
impl<T> !Sync for *const T { }
|
||||||
impl<T> !Sync for *mut T { }
|
impl<T> !Sync for *mut T { }
|
||||||
impl !Sync for Managed { }
|
impl !Sync for Managed { }
|
||||||
|
|||||||
@@ -5989,10 +5989,7 @@ pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
|
|||||||
|
|
||||||
pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool {
|
pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool {
|
||||||
populate_implementations_for_trait_if_necessary(tcx, trait_def_id);
|
populate_implementations_for_trait_if_necessary(tcx, trait_def_id);
|
||||||
match tcx.lang_items.to_builtin_kind(trait_def_id) {
|
tcx.traits_with_default_impls.borrow().contains_key(&trait_def_id)
|
||||||
Some(BoundSend) | Some(BoundSync) => true,
|
|
||||||
_ => tcx.traits_with_default_impls.borrow().contains_key(&trait_def_id),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Records a trait-to-implementation mapping.
|
/// Records a trait-to-implementation mapping.
|
||||||
|
|||||||
@@ -27,54 +27,65 @@ struct UnsafetyChecker<'cx, 'tcx:'cx> {
|
|||||||
tcx: &'cx ty::ctxt<'tcx>
|
tcx: &'cx ty::ctxt<'tcx>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
(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::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> {
|
impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
|
||||||
fn visit_item(&mut self, item: &'v ast::Item) {
|
fn visit_item(&mut self, item: &'v ast::Item) {
|
||||||
match item.node {
|
match item.node {
|
||||||
|
ast::ItemDefaultImpl(unsafety, _) => {
|
||||||
|
self.check_unsafety_coherence(item, unsafety, ast::ImplPolarity::Positive);
|
||||||
|
}
|
||||||
ast::ItemImpl(unsafety, polarity, _, _, _, _) => {
|
ast::ItemImpl(unsafety, polarity, _, _, _, _) => {
|
||||||
match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) {
|
self.check_unsafety_coherence(item, unsafety, polarity);
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
(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::Negative) |
|
|
||||||
(ast::Unsafety::Unsafe,
|
|
||||||
ast::Unsafety::Unsafe, ast::ImplPolarity::Positive) |
|
|
||||||
(ast::Unsafety::Normal, ast::Unsafety::Normal, _) => {
|
|
||||||
/* OK */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => { }
|
_ => { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, _, _, _, _) => {
|
ast::ItemImpl(_, polarity, _, _, _, _) => {
|
||||||
match polarity {
|
match polarity {
|
||||||
ast::ImplPolarity::Negative => {
|
ast::ImplPolarity::Negative => {
|
||||||
|
|||||||
@@ -21,4 +21,14 @@ impl MyTrait for .. {}
|
|||||||
impl MyTrait for .. {}
|
impl MyTrait for .. {}
|
||||||
//~^ ERROR conflicting implementations for trait `MyTrait`
|
//~^ 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() {}
|
fn main() {}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(optin_builtin_traits)]
|
||||||
|
|
||||||
pub mod bar {
|
pub mod bar {
|
||||||
use std::marker;
|
use std::marker;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user