Skip to content

Commit a5f6f85

Browse files
committed
auto merge of #10322 : thestinger/rust/no_freeze, r=alexcrichton
2 parents 7fc6893 + 8662141 commit a5f6f85

File tree

2 files changed

+43
-21
lines changed

2 files changed

+43
-21
lines changed

src/libstd/rc.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,21 @@ impl<T: Freeze> Rc<T> {
4848
}
4949
}
5050

51+
impl<T: Send> Rc<T> {
52+
/// Construct a new reference-counted box from a `Send` value
53+
#[inline]
54+
pub fn from_send(value: T) -> Rc<T> {
55+
unsafe {
56+
Rc::new_unchecked(value)
57+
}
58+
}
59+
}
60+
5161
impl<T> Rc<T> {
5262
/// Unsafety construct a new reference-counted box from any value.
5363
///
54-
/// If the type is not `Freeze`, the `Rc` box will incorrectly still be considered as a `Freeze`
55-
/// type. It is also possible to create cycles, which will leak, and may interact poorly with
56-
/// managed pointers.
64+
/// It is possible to create cycles, which will leak, and may interact
65+
/// poorly with managed pointers.
5766
#[inline]
5867
pub unsafe fn new_unchecked(value: T) -> Rc<T> {
5968
Rc{ptr: transmute(~RcBox{value: value, count: 1})}
@@ -104,26 +113,22 @@ mod test_rc {
104113

105114
#[test]
106115
fn test_clone() {
107-
unsafe {
108-
let x = Rc::new_unchecked(Cell::new(5));
109-
let y = x.clone();
110-
do x.borrow().with_mut_ref |inner| {
111-
*inner = 20;
112-
}
113-
assert_eq!(y.borrow().take(), 20);
116+
let x = Rc::from_send(Cell::new(5));
117+
let y = x.clone();
118+
do x.borrow().with_mut_ref |inner| {
119+
*inner = 20;
114120
}
121+
assert_eq!(y.borrow().take(), 20);
115122
}
116123

117124
#[test]
118125
fn test_deep_clone() {
119-
unsafe {
120-
let x = Rc::new_unchecked(Cell::new(5));
121-
let y = x.deep_clone();
122-
do x.borrow().with_mut_ref |inner| {
123-
*inner = 20;
124-
}
125-
assert_eq!(y.borrow().take(), 5);
126+
let x = Rc::from_send(Cell::new(5));
127+
let y = x.deep_clone();
128+
do x.borrow().with_mut_ref |inner| {
129+
*inner = 20;
126130
}
131+
assert_eq!(y.borrow().take(), 5);
127132
}
128133

129134
#[test]
@@ -142,10 +147,8 @@ mod test_rc {
142147

143148
#[test]
144149
fn test_destructor() {
145-
unsafe {
146-
let x = Rc::new_unchecked(~5);
147-
assert_eq!(**x.borrow(), 5);
148-
}
150+
let x = Rc::from_send(~5);
151+
assert_eq!(**x.borrow(), 5);
149152
}
150153
}
151154

src/test/compile-fail/no_freeze-rc.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::rc::Rc;
12+
use std::cell::Cell;
13+
14+
fn bar<T: Freeze>(_: T) {}
15+
16+
fn main() {
17+
let x = Rc::from_send(Cell::new(5));
18+
bar(x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::cell::Cell<int>>`, which does not fulfill `Freeze`
19+
}

0 commit comments

Comments
 (0)