提交 b36a9488 编写于 作者: D Daniel Micay

stop treating `Rc` cycles as unsafe

上级 63ba93f9
......@@ -406,14 +406,14 @@ fn encode(&self, s: &mut S) {
}
}
impl<S:Encoder,T:Encodable<S> + Freeze> Encodable<S> for Rc<T> {
impl<S:Encoder,T:Encodable<S>> Encodable<S> for Rc<T> {
#[inline]
fn encode(&self, s: &mut S) {
self.borrow().encode(s)
}
}
impl<D:Decoder,T:Decodable<D> + Freeze> Decodable<D> for Rc<T> {
impl<D:Decoder,T:Decodable<D> + NonManaged> Decodable<D> for Rc<T> {
#[inline]
fn decode(d: &mut D) -> Rc<T> {
Rc::new(Decodable::decode(d))
......
......@@ -19,9 +19,8 @@
use ptr::RawPtr;
use unstable::intrinsics::transmute;
use ops::Drop;
use kinds::{Freeze, Send};
use kinds::NonManaged;
use clone::{Clone, DeepClone};
use cell::RefCell;
use cmp::{Eq, TotalEq, Ord, TotalOrd, Ordering};
struct RcBox<T> {
......@@ -36,46 +35,17 @@ pub struct Rc<T> {
priv ptr: *mut RcBox<T>
}
impl<T: Freeze> Rc<T> {
/// Construct a new reference-counted box from a `Freeze` value
impl<T: NonManaged> Rc<T> {
/// Construct a new reference-counted box
#[inline]
pub fn new(value: T) -> Rc<T> {
unsafe {
Rc::new_unchecked(value)
}
}
}
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: Freeze> Rc<RefCell<T>> {
/// Construct a new reference-counted box from a `RefCell`-wrapped `Freeze` value
#[inline]
pub fn from_mut(value: RefCell<T>) -> Rc<RefCell<T>> {
unsafe {
Rc::new_unchecked(value)
Rc { ptr: transmute(~RcBox { value: value, count: 1 }) }
}
}
}
impl<T> Rc<T> {
/// Unsafety construct a new reference-counted box from any value.
///
/// 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})}
}
/// Borrow the value contained in the reference-counted box
#[inline]
pub fn borrow<'r>(&'r self) -> &'r T {
......@@ -147,10 +117,10 @@ fn clone(&self) -> Rc<T> {
}
}
impl<T: DeepClone> DeepClone for Rc<T> {
impl<T: NonManaged + DeepClone> DeepClone for Rc<T> {
#[inline]
fn deep_clone(&self) -> Rc<T> {
unsafe { Rc::new_unchecked(self.borrow().deep_clone()) }
Rc::new(self.borrow().deep_clone())
}
}
......@@ -176,7 +146,7 @@ mod test_rc {
#[test]
fn test_clone() {
let x = Rc::from_send(RefCell::new(5));
let x = Rc::new(RefCell::new(5));
let y = x.clone();
x.borrow().with_mut(|inner| {
*inner = 20;
......@@ -186,7 +156,7 @@ fn test_clone() {
#[test]
fn test_deep_clone() {
let x = Rc::from_send(RefCell::new(5));
let x = Rc::new(RefCell::new(5));
let y = x.deep_clone();
x.borrow().with_mut(|inner| {
*inner = 20;
......@@ -210,13 +180,7 @@ fn test_simple_clone() {
#[test]
fn test_destructor() {
let x = Rc::from_send(~5);
let x = Rc::new(~5);
assert_eq!(**x.borrow(), 5);
}
#[test]
fn test_from_mut() {
let a = 10;
let _x = Rc::from_mut(RefCell::new(&a));
}
}
......@@ -37,7 +37,7 @@ struct A
fn main()
{
let a = A {v: ~B{v: None} as ~Foo}; //~ ERROR cannot pack type `~B`, which does not fulfill `Send`
let v = Rc::from_send(RefCell::new(a));
let v = Rc::new(RefCell::new(a));
let w = v.clone();
let b = v.borrow();
let mut b = b.borrow_mut();
......
......@@ -14,6 +14,6 @@
fn bar<T: Freeze>(_: T) {}
fn main() {
let x = Rc::from_send(RefCell::new(5));
let x = Rc::new(RefCell::new(5));
bar(x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Freeze`
}
// 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::cell::RefCell;
use std::rc::Rc;
fn o<T: Send>(_: &T) {}
fn c<T: Freeze>(_: &T) {}
fn main() {
let x = Rc::from_send(RefCell::new(0));
o(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Send`
c(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Freeze`
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册