about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-11-06 23:36:06 -0800
committerbors <bors@rust-lang.org>2013-11-06 23:36:06 -0800
commita5f6f853f10ec88dc2608a8d2f969a4cf9e2e07d (patch)
tree7c29cb5e2a7c33c090c444a696c006f1bc01e697
parent7fc689305cd38a0168ed5b139f4c118f81e2217e (diff)
parent8662141c21720e9398dd3230d6503c41db9de59e (diff)
downloadrust-a5f6f853f10ec88dc2608a8d2f969a4cf9e2e07d.tar.gz
rust-a5f6f853f10ec88dc2608a8d2f969a4cf9e2e07d.zip
auto merge of #10322 : thestinger/rust/no_freeze, r=alexcrichton
-rw-r--r--src/libstd/rc.rs45
-rw-r--r--src/test/compile-fail/no_freeze-rc.rs19
2 files changed, 43 insertions, 21 deletions
diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs
index 41e834cf37c..cc2f739ce98 100644
--- a/src/libstd/rc.rs
+++ b/src/libstd/rc.rs
@@ -48,12 +48,21 @@ impl<T: Freeze> Rc<T> {
     }
 }
 
+impl<T: Send> Rc<T> {
+    /// Construct a new reference-counted box from a `Send` value
+    #[inline]
+    pub fn from_send(value: T) -> Rc<T> {
+        unsafe {
+            Rc::new_unchecked(value)
+        }
+    }
+}
+
 impl<T> Rc<T> {
     /// Unsafety construct a new reference-counted box from any value.
     ///
-    /// If the type is not `Freeze`, the `Rc` box will incorrectly still be considered as a `Freeze`
-    /// type. It is also possible to create cycles, which will leak, and may interact poorly with
-    /// managed pointers.
+    /// It is possible to create cycles, which will leak, and may interact
+    /// poorly with managed pointers.
     #[inline]
     pub unsafe fn new_unchecked(value: T) -> Rc<T> {
         Rc{ptr: transmute(~RcBox{value: value, count: 1})}
@@ -104,26 +113,22 @@ mod test_rc {
 
     #[test]
     fn test_clone() {
-        unsafe {
-            let x = Rc::new_unchecked(Cell::new(5));
-            let y = x.clone();
-            do x.borrow().with_mut_ref |inner| {
-                *inner = 20;
-            }
-            assert_eq!(y.borrow().take(), 20);
+        let x = Rc::from_send(Cell::new(5));
+        let y = x.clone();
+        do x.borrow().with_mut_ref |inner| {
+            *inner = 20;
         }
+        assert_eq!(y.borrow().take(), 20);
     }
 
     #[test]
     fn test_deep_clone() {
-        unsafe {
-            let x = Rc::new_unchecked(Cell::new(5));
-            let y = x.deep_clone();
-            do x.borrow().with_mut_ref |inner| {
-                *inner = 20;
-            }
-            assert_eq!(y.borrow().take(), 5);
+        let x = Rc::from_send(Cell::new(5));
+        let y = x.deep_clone();
+        do x.borrow().with_mut_ref |inner| {
+            *inner = 20;
         }
+        assert_eq!(y.borrow().take(), 5);
     }
 
     #[test]
@@ -142,10 +147,8 @@ mod test_rc {
 
     #[test]
     fn test_destructor() {
-        unsafe {
-            let x = Rc::new_unchecked(~5);
-            assert_eq!(**x.borrow(), 5);
-        }
+        let x = Rc::from_send(~5);
+        assert_eq!(**x.borrow(), 5);
     }
 }
 
diff --git a/src/test/compile-fail/no_freeze-rc.rs b/src/test/compile-fail/no_freeze-rc.rs
new file mode 100644
index 00000000000..6185ccf2e7e
--- /dev/null
+++ b/src/test/compile-fail/no_freeze-rc.rs
@@ -0,0 +1,19 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::rc::Rc;
+use std::cell::Cell;
+
+fn bar<T: Freeze>(_: T) {}
+
+fn main() {
+    let x = Rc::from_send(Cell::new(5));
+    bar(x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::cell::Cell<int>>`, which does not fulfill `Freeze`
+}