Skip to content

Commit ee2bfae

Browse files
committed
auto merge of #20972 : FlaPer87/rust/oibit-send-and-friends, r=nikomatsakis
This PR adds rules for negative implementations. It follows pretty much what the [RFC](https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md) says with 1 main difference: Instead of positive implementations override negative implementations, this have been implemented in a way that a negative implementation of `Trait` for `T` will overlap with a positive implementation, causing a coherence error. @nikomatsakis r? cc #13231 [breaking-change]
2 parents f3d71be + cb85223 commit ee2bfae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+676
-105
lines changed

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
#![allow(unknown_features)]
6969
#![feature(lang_items, unsafe_destructor)]
7070
#![feature(box_syntax)]
71+
#![feature(optin_builtin_traits)]
7172
#![allow(unknown_features)] #![feature(int_uint)]
7273

7374
#[macro_use]

src/liballoc/rc.rs

+159
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ struct RcBox<T> {
174174
/// See the [module level documentation](../index.html) for more details.
175175
#[unsafe_no_drop_flag]
176176
#[stable]
177+
#[cfg(stage0)] // NOTE remove impl after next snapshot
177178
pub struct Rc<T> {
178179
// FIXME #12808: strange names to try to avoid interfering with field accesses of the contained
179180
// type via Deref
@@ -182,6 +183,24 @@ pub struct Rc<T> {
182183
_noshare: marker::NoSync
183184
}
184185

186+
/// An immutable reference-counted pointer type.
187+
///
188+
/// See the [module level documentation](../index.html) for more details.
189+
#[unsafe_no_drop_flag]
190+
#[stable]
191+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
192+
pub struct Rc<T> {
193+
// FIXME #12808: strange names to try to avoid interfering with field accesses of the contained
194+
// type via Deref
195+
_ptr: NonZero<*mut RcBox<T>>,
196+
}
197+
198+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
199+
impl<T> !marker::Send for Rc<T> {}
200+
201+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
202+
impl<T> !marker::Sync for Rc<T> {}
203+
185204
impl<T> Rc<T> {
186205
/// Constructs a new `Rc<T>`.
187206
///
@@ -193,6 +212,7 @@ impl<T> Rc<T> {
193212
/// let five = Rc::new(5i);
194213
/// ```
195214
#[stable]
215+
#[cfg(stage0)] // NOTE remove after next snapshot
196216
pub fn new(value: T) -> Rc<T> {
197217
unsafe {
198218
Rc {
@@ -210,6 +230,32 @@ impl<T> Rc<T> {
210230
}
211231
}
212232

233+
/// Constructs a new `Rc<T>`.
234+
///
235+
/// # Examples
236+
///
237+
/// ```
238+
/// use std::rc::Rc;
239+
///
240+
/// let five = Rc::new(5i);
241+
/// ```
242+
#[stable]
243+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
244+
pub fn new(value: T) -> Rc<T> {
245+
unsafe {
246+
Rc {
247+
// there is an implicit weak pointer owned by all the strong pointers, which
248+
// ensures that the weak destructor never frees the allocation while the strong
249+
// destructor is running, even if the weak pointer is stored inside the strong one.
250+
_ptr: NonZero::new(transmute(box RcBox {
251+
value: value,
252+
strong: Cell::new(1),
253+
weak: Cell::new(1)
254+
})),
255+
}
256+
}
257+
}
258+
213259
/// Downgrades the `Rc<T>` to a `Weak<T>` reference.
214260
///
215261
/// # Examples
@@ -221,6 +267,7 @@ impl<T> Rc<T> {
221267
///
222268
/// let weak_five = five.downgrade();
223269
/// ```
270+
#[cfg(stage0)] // NOTE remove after next snapshot
224271
#[unstable = "Weak pointers may not belong in this module"]
225272
pub fn downgrade(&self) -> Weak<T> {
226273
self.inc_weak();
@@ -230,6 +277,24 @@ impl<T> Rc<T> {
230277
_noshare: marker::NoSync
231278
}
232279
}
280+
281+
/// Downgrades the `Rc<T>` to a `Weak<T>` reference.
282+
///
283+
/// # Examples
284+
///
285+
/// ```
286+
/// use std::rc::Rc;
287+
///
288+
/// let five = Rc::new(5i);
289+
///
290+
/// let weak_five = five.downgrade();
291+
/// ```
292+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
293+
#[unstable = "Weak pointers may not belong in this module"]
294+
pub fn downgrade(&self) -> Weak<T> {
295+
self.inc_weak();
296+
Weak { _ptr: self._ptr }
297+
}
233298
}
234299

235300
/// Get the number of weak references to this value.
@@ -432,10 +497,31 @@ impl<T> Clone for Rc<T> {
432497
/// five.clone();
433498
/// ```
434499
#[inline]
500+
#[cfg(stage0)] // NOTE remove after next snapshot
435501
fn clone(&self) -> Rc<T> {
436502
self.inc_strong();
437503
Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }
438504
}
505+
506+
/// Makes a clone of the `Rc<T>`.
507+
///
508+
/// This increases the strong reference count.
509+
///
510+
/// # Examples
511+
///
512+
/// ```
513+
/// use std::rc::Rc;
514+
///
515+
/// let five = Rc::new(5i);
516+
///
517+
/// five.clone();
518+
/// ```
519+
#[inline]
520+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
521+
fn clone(&self) -> Rc<T> {
522+
self.inc_strong();
523+
Rc { _ptr: self._ptr }
524+
}
439525
}
440526

441527
#[stable]
@@ -636,6 +722,7 @@ impl<T: fmt::String> fmt::String for Rc<T> {
636722
/// See the [module level documentation](../index.html) for more.
637723
#[unsafe_no_drop_flag]
638724
#[unstable = "Weak pointers may not belong in this module."]
725+
#[cfg(stage0)] // NOTE remove impl after next snapshot
639726
pub struct Weak<T> {
640727
// FIXME #12808: strange names to try to avoid interfering with
641728
// field accesses of the contained type via Deref
@@ -644,6 +731,29 @@ pub struct Weak<T> {
644731
_noshare: marker::NoSync
645732
}
646733

734+
/// A weak version of `Rc<T>`.
735+
///
736+
/// Weak references do not count when determining if the inner value should be dropped.
737+
///
738+
/// See the [module level documentation](../index.html) for more.
739+
#[unsafe_no_drop_flag]
740+
#[unstable = "Weak pointers may not belong in this module."]
741+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
742+
pub struct Weak<T> {
743+
// FIXME #12808: strange names to try to avoid interfering with
744+
// field accesses of the contained type via Deref
745+
_ptr: NonZero<*mut RcBox<T>>,
746+
}
747+
748+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
749+
#[allow(unstable)]
750+
impl<T> !marker::Send for Weak<T> {}
751+
752+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
753+
#[allow(unstable)]
754+
impl<T> !marker::Sync for Weak<T> {}
755+
756+
647757
#[unstable = "Weak pointers may not belong in this module."]
648758
impl<T> Weak<T> {
649759
/// Upgrades a weak reference to a strong reference.
@@ -663,6 +773,7 @@ impl<T> Weak<T> {
663773
///
664774
/// let strong_five: Option<Rc<_>> = weak_five.upgrade();
665775
/// ```
776+
#[cfg(stage0)] // NOTE remove after next snapshot
666777
pub fn upgrade(&self) -> Option<Rc<T>> {
667778
if self.strong() == 0 {
668779
None
@@ -671,6 +782,33 @@ impl<T> Weak<T> {
671782
Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync })
672783
}
673784
}
785+
786+
/// Upgrades a weak reference to a strong reference.
787+
///
788+
/// Upgrades the `Weak<T>` reference to an `Rc<T>`, if possible.
789+
///
790+
/// Returns `None` if there were no strong references and the data was destroyed.
791+
///
792+
/// # Examples
793+
///
794+
/// ```
795+
/// use std::rc::Rc;
796+
///
797+
/// let five = Rc::new(5i);
798+
///
799+
/// let weak_five = five.downgrade();
800+
///
801+
/// let strong_five: Option<Rc<_>> = weak_five.upgrade();
802+
/// ```
803+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
804+
pub fn upgrade(&self) -> Option<Rc<T>> {
805+
if self.strong() == 0 {
806+
None
807+
} else {
808+
self.inc_strong();
809+
Some(Rc { _ptr: self._ptr })
810+
}
811+
}
674812
}
675813

676814
#[unsafe_destructor]
@@ -733,10 +871,31 @@ impl<T> Clone for Weak<T> {
733871
/// weak_five.clone();
734872
/// ```
735873
#[inline]
874+
#[cfg(stage0)] // NOTE remove after next snapshot
736875
fn clone(&self) -> Weak<T> {
737876
self.inc_weak();
738877
Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }
739878
}
879+
880+
/// Makes a clone of the `Weak<T>`.
881+
///
882+
/// This increases the weak reference count.
883+
///
884+
/// # Examples
885+
///
886+
/// ```
887+
/// use std::rc::Rc;
888+
///
889+
/// let weak_five = Rc::new(5i).downgrade();
890+
///
891+
/// weak_five.clone();
892+
/// ```
893+
#[inline]
894+
#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
895+
fn clone(&self) -> Weak<T> {
896+
self.inc_weak();
897+
Weak { _ptr: self._ptr }
898+
}
740899
}
741900

742901
#[unstable = "Show is experimental."]

src/libcore/cell.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -509,12 +509,13 @@ impl<'b, T> DerefMut for RefMut<'b, T> {
509509
///
510510
/// ```rust
511511
/// use std::cell::UnsafeCell;
512-
/// use std::marker;
512+
/// use std::marker::Sync;
513513
///
514514
/// struct NotThreadSafe<T> {
515515
/// value: UnsafeCell<T>,
516-
/// marker: marker::NoSync
517516
/// }
517+
///
518+
/// unsafe impl<T> Sync for NotThreadSafe<T> {}
518519
/// ```
519520
///
520521
/// **NOTE:** `UnsafeCell<T>` fields are public to allow static initializers. It

src/libcore/marker.rs

+2
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ pub struct InvariantLifetime<'a>;
286286
#[unstable = "likely to change with new variance strategy"]
287287
#[lang="no_send_bound"]
288288
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
289+
#[cfg(stage0)] // NOTE remove impl after next snapshot
289290
pub struct NoSend;
290291

291292
/// A type which is considered "not POD", meaning that it is not
@@ -303,6 +304,7 @@ pub struct NoCopy;
303304
#[unstable = "likely to change with new variance strategy"]
304305
#[lang="no_sync_bound"]
305306
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
307+
#[cfg(stage0)] // NOTE remove impl after next snapshot
306308
pub struct NoSync;
307309

308310
/// A type which is considered managed by the GC. This is typically

src/librustc/metadata/csearch.rs

+9
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,15 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
262262
}
263263
}
264264

265+
pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
266+
def: ast::DefId)
267+
-> Option<ast::ImplPolarity>
268+
{
269+
let cstore = &tcx.sess.cstore;
270+
let cdata = cstore.get_crate_data(def.krate);
271+
decoder::get_impl_polarity(&*cdata, def.node)
272+
}
273+
265274
// Given a def_id for an impl, return the trait it implements,
266275
// if there is one.
267276
pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,

src/librustc/metadata/decoder.rs

+23
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,15 @@ fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
371371
}
372372
}
373373

374+
fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity {
375+
let polarity_doc = reader::get_doc(item_doc, tag_polarity);
376+
if reader::doc_as_u8(polarity_doc) != 0 {
377+
ast::ImplPolarity::Negative
378+
} else {
379+
ast::ImplPolarity::Positive
380+
}
381+
}
382+
374383
fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
375384
let names_doc = reader::get_doc(item_doc, tag_associated_type_names);
376385
let mut names = Vec::new();
@@ -436,6 +445,20 @@ pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
436445
}
437446
}
438447

448+
pub fn get_impl_polarity<'tcx>(cdata: Cmd,
449+
id: ast::NodeId)
450+
-> Option<ast::ImplPolarity>
451+
{
452+
let item_doc = lookup_item(id, cdata.data());
453+
let fam = item_family(item_doc);
454+
match fam {
455+
Family::Impl => {
456+
Some(parse_polarity(item_doc))
457+
}
458+
_ => None
459+
}
460+
}
461+
439462
pub fn get_impl_trait<'tcx>(cdata: Cmd,
440463
id: ast::NodeId,
441464
tcx: &ty::ctxt<'tcx>)

0 commit comments

Comments
 (0)