Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 33375a3

Browse files
committedNov 24, 2013
auto merge of #10514 : sfackler/rust/mut, r=cmr
This is based off of @blake2-ppc's work on #9429. That PR bitrotted and I haven't been able to contact the original author so I decided to take up the cause. Overview ====== `Mut` encapsulates a mutable, non-nullable slot. The `Cell` type is currently used to do this, but `Cell` is much more commonly used as a workaround for the inability to move values into non-once functions. `Mut` provides a more robust API. `Mut` duplicates the semantics of borrowed pointers with enforcement at runtime instead of compile time. ```rust let x = Mut::new(0); { // make some immutable borrows let p = x.borrow(); let y = *p.get() + 10; // multiple immutable borrows are allowed simultaneously let p2 = x.borrow(); // this would throw a runtime failure // let p_mut = x.borrow_mut(); } // now we can mutably borrow let p = x.borrow_mut(); *p.get() = 10; ``` `borrow` returns a `Ref` type and `borrow_mut` returns a `RefMut` type, both of which are simple smart pointer types with a single method, `get`, which returns a reference to the wrapped data. This also allows `RcMut<T>` to be deleted, as it can be replaced with `Rc<Mut<T>>`. Changes ====== I've done things a little bit differently than the original proposal. * I've added `try_borrow` and `try_borrow_mut` methods that return `Option<Ref<T>>` and `Option<RefMut<T>>` respectively instead of failing on a borrow check failure. I'm not totally sure when that'd be useful, but I don't see any reason to not put them in and @cmr requested them. * `ReadPtr` and `WritePtr` have been renamed to `Ref` and `RefMut` respectively, as `Ref` is to `ref foo` and `RefMut` is to `ref mut foo` as `Mut` is to `mut foo`. * `get` on `MutRef` now takes `&self` instead of `&mut self` for consistency with `&mut`. As @alexcrichton pointed, out this violates soundness by allowing aliasing `&mut` references. * `Cell` is being left as is. It solves a different problem than `Mut` is designed to solve. * There are no longer methods implemented for `Mut<Option<T>>`. Since `Cell` isn't going away, there's less of a need for these, and I didn't feel like they provided a huge benefit, especially as that kind of `impl` is very uncommon in the standard library. Open Questions ============ * `Cell` should now be used exclusively for movement into closures. Should this be enforced by reducing its API to `new` and `take`? It seems like this use case will be completely going away once the transition to `proc` and co. finishes. * Should there be `try_map` and `try_map_mut` methods along with `map` and `map_mut`?
2 parents 6cbc57c + bdfaf04 commit 33375a3

File tree

12 files changed

+437
-360
lines changed

12 files changed

+437
-360
lines changed
 

‎src/librustc/middle/typeck/infer/region_inference/mod.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use middle::graph::{Direction, NodeIndex};
2424
use util::common::indenter;
2525
use util::ppaux::{Repr};
2626

27-
use std::cell::Cell;
2827
use std::hashmap::{HashMap, HashSet};
2928
use std::uint;
3029
use std::vec;
@@ -106,16 +105,15 @@ pub struct RegionVarBindings {
106105
undo_log: ~[UndoLogEntry],
107106

108107
// This contains the results of inference. It begins as an empty
109-
// cell and only acquires a value after inference is complete.
110-
// We use a cell vs a mutable option to circumvent borrowck errors.
111-
values: Cell<~[VarValue]>,
108+
// option and only acquires a value after inference is complete.
109+
values: Option<~[VarValue]>,
112110
}
113111

114112
pub fn RegionVarBindings(tcx: ty::ctxt) -> RegionVarBindings {
115113
RegionVarBindings {
116114
tcx: tcx,
117115
var_origins: ~[],
118-
values: Cell::new_empty(),
116+
values: None,
119117
constraints: HashMap::new(),
120118
lubs: HashMap::new(),
121119
glbs: HashMap::new(),
@@ -226,7 +224,7 @@ impl RegionVarBindings {
226224
constraint: Constraint,
227225
origin: SubregionOrigin) {
228226
// cannot add constraints once regions are resolved
229-
assert!(self.values.is_empty());
227+
assert!(self.values.is_none());
230228

231229
debug!("RegionVarBindings: add_constraint({:?})", constraint);
232230

@@ -242,7 +240,7 @@ impl RegionVarBindings {
242240
sub: Region,
243241
sup: Region) {
244242
// cannot add constraints once regions are resolved
245-
assert!(self.values.is_empty());
243+
assert!(self.values.is_none());
246244

247245
debug!("RegionVarBindings: make_subregion({:?}, {:?})", sub, sup);
248246
match (sub, sup) {
@@ -277,7 +275,7 @@ impl RegionVarBindings {
277275
b: Region)
278276
-> Region {
279277
// cannot add constraints once regions are resolved
280-
assert!(self.values.is_empty());
278+
assert!(self.values.is_none());
281279

282280
debug!("RegionVarBindings: lub_regions({:?}, {:?})", a, b);
283281
match (a, b) {
@@ -300,7 +298,7 @@ impl RegionVarBindings {
300298
b: Region)
301299
-> Region {
302300
// cannot add constraints once regions are resolved
303-
assert!(self.values.is_empty());
301+
assert!(self.values.is_none());
304302

305303
debug!("RegionVarBindings: glb_regions({:?}, {:?})", a, b);
306304
match (a, b) {
@@ -319,14 +317,14 @@ impl RegionVarBindings {
319317
}
320318

321319
pub fn resolve_var(&mut self, rid: RegionVid) -> ty::Region {
322-
if self.values.is_empty() {
323-
self.tcx.sess.span_bug(
320+
let v = match self.values {
321+
None => self.tcx.sess.span_bug(
324322
self.var_origins[rid.to_uint()].span(),
325323
format!("Attempt to resolve region variable before values have \
326-
been computed!"));
327-
}
324+
been computed!")),
325+
Some(ref values) => values[rid.to_uint()]
326+
};
328327

329-
let v = self.values.with_ref(|values| values[rid.to_uint()]);
330328
debug!("RegionVarBindings: resolve_var({:?}={})={:?}",
331329
rid, rid.to_uint(), v);
332330
match v {
@@ -482,7 +480,7 @@ impl RegionVarBindings {
482480
debug!("RegionVarBindings: resolve_regions()");
483481
let mut errors = opt_vec::Empty;
484482
let v = self.infer_variable_values(&mut errors);
485-
self.values.put_back(v);
483+
self.values = Some(v);
486484
errors
487485
}
488486
}

‎src/libstd/cell.rs

Lines changed: 294 additions & 56 deletions
Large diffs are not rendered by default.

‎src/libstd/gc.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,26 +55,26 @@ impl<T: DeepClone + Send + 'static> DeepClone for Gc<T> {
5555
#[cfg(test)]
5656
mod tests {
5757
use super::*;
58-
use cell::Cell;
58+
use cell::RefCell;
5959

6060
#[test]
6161
fn test_clone() {
62-
let x = Gc::new(Cell::new(5));
62+
let x = Gc::new(RefCell::new(5));
6363
let y = x.clone();
64-
do x.borrow().with_mut_ref |inner| {
64+
do x.borrow().with_mut |inner| {
6565
*inner = 20;
6666
}
67-
assert_eq!(y.borrow().take(), 20);
67+
assert_eq!(y.borrow().with(|x| *x), 20);
6868
}
6969

7070
#[test]
7171
fn test_deep_clone() {
72-
let x = Gc::new(Cell::new(5));
72+
let x = Gc::new(RefCell::new(5));
7373
let y = x.deep_clone();
74-
do x.borrow().with_mut_ref |inner| {
74+
do x.borrow().with_mut |inner| {
7575
*inner = 20;
7676
}
77-
assert_eq!(y.borrow().take(), 5);
77+
assert_eq!(y.borrow().with(|x| *x), 5);
7878
}
7979

8080
#[test]

‎src/libstd/rc.rs

Lines changed: 21 additions & 241 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,14 @@ The `Rc` type provides shared ownership of an immutable value. Destruction is de
1414
will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
1515
overhead of atomic reference counting.
1616
17-
The `RcMut` type provides shared ownership of a mutable value. Since multiple owners prevent
18-
inherited mutability, a dynamic freezing check is used to maintain the invariant that an `&mut`
19-
reference is a unique handle and the type is marked as non-`Freeze`.
20-
2117
*/
2218

2319
use ptr::RawPtr;
2420
use unstable::intrinsics::transmute;
2521
use ops::Drop;
2622
use kinds::{Freeze, Send};
2723
use clone::{Clone, DeepClone};
24+
use cell::RefCell;
2825

2926
struct RcBox<T> {
3027
value: T,
@@ -58,6 +55,16 @@ impl<T: Send> Rc<T> {
5855
}
5956
}
6057

58+
impl<T: Freeze> Rc<RefCell<T>> {
59+
/// Construct a new reference-counted box from a `RefCell`-wrapped `Freeze` value
60+
#[inline]
61+
pub fn from_mut(value: RefCell<T>) -> Rc<RefCell<T>> {
62+
unsafe {
63+
Rc::new_unchecked(value)
64+
}
65+
}
66+
}
67+
6168
impl<T> Rc<T> {
6269
/// Unsafety construct a new reference-counted box from any value.
6370
///
@@ -109,26 +116,26 @@ impl<T> Drop for Rc<T> {
109116
#[cfg(test)]
110117
mod test_rc {
111118
use super::*;
112-
use cell::Cell;
119+
use cell::RefCell;
113120

114121
#[test]
115122
fn test_clone() {
116-
let x = Rc::from_send(Cell::new(5));
123+
let x = Rc::from_send(RefCell::new(5));
117124
let y = x.clone();
118-
do x.borrow().with_mut_ref |inner| {
125+
do x.borrow().with_mut |inner| {
119126
*inner = 20;
120127
}
121-
assert_eq!(y.borrow().take(), 20);
128+
assert_eq!(y.borrow().with(|v| *v), 20);
122129
}
123130

124131
#[test]
125132
fn test_deep_clone() {
126-
let x = Rc::from_send(Cell::new(5));
133+
let x = Rc::from_send(RefCell::new(5));
127134
let y = x.deep_clone();
128-
do x.borrow().with_mut_ref |inner| {
135+
do x.borrow().with_mut |inner| {
129136
*inner = 20;
130137
}
131-
assert_eq!(y.borrow().take(), 5);
138+
assert_eq!(y.borrow().with(|v| *v), 5);
132139
}
133140

134141
#[test]
@@ -150,237 +157,10 @@ mod test_rc {
150157
let x = Rc::from_send(~5);
151158
assert_eq!(**x.borrow(), 5);
152159
}
153-
}
154-
155-
#[deriving(Eq)]
156-
enum Borrow {
157-
Mutable,
158-
Immutable,
159-
Nothing
160-
}
161-
162-
struct RcMutBox<T> {
163-
value: T,
164-
count: uint,
165-
borrow: Borrow
166-
}
167-
168-
/// Mutable reference counted pointer type
169-
#[no_send]
170-
#[no_freeze]
171-
#[unsafe_no_drop_flag]
172-
pub struct RcMut<T> {
173-
priv ptr: *mut RcMutBox<T>,
174-
}
175-
176-
impl<T: Freeze> RcMut<T> {
177-
/// Construct a new mutable reference-counted box from a `Freeze` value
178-
#[inline]
179-
pub fn new(value: T) -> RcMut<T> {
180-
unsafe { RcMut::new_unchecked(value) }
181-
}
182-
}
183-
184-
impl<T: Send> RcMut<T> {
185-
/// Construct a new mutable reference-counted box from a `Send` value
186-
#[inline]
187-
pub fn from_send(value: T) -> RcMut<T> {
188-
unsafe { RcMut::new_unchecked(value) }
189-
}
190-
}
191-
192-
impl<T> RcMut<T> {
193-
/// Unsafety construct a new mutable reference-counted box from any value.
194-
///
195-
/// It is possible to create cycles, which will leak, and may interact
196-
/// poorly with managed pointers.
197-
#[inline]
198-
pub unsafe fn new_unchecked(value: T) -> RcMut<T> {
199-
RcMut{ptr: transmute(~RcMutBox{value: value, count: 1, borrow: Nothing})}
200-
}
201-
}
202-
203-
impl<T> RcMut<T> {
204-
/// Fails if there is already a mutable borrow of the box
205-
#[inline]
206-
pub fn with_borrow<U>(&self, f: |&T| -> U) -> U {
207-
unsafe {
208-
assert!((*self.ptr).borrow != Mutable);
209-
let previous = (*self.ptr).borrow;
210-
(*self.ptr).borrow = Immutable;
211-
let res = f(&(*self.ptr).value);
212-
(*self.ptr).borrow = previous;
213-
res
214-
}
215-
}
216-
217-
/// Fails if there is already a mutable or immutable borrow of the box
218-
#[inline]
219-
pub fn with_mut_borrow<U>(&self, f: |&mut T| -> U) -> U {
220-
unsafe {
221-
assert_eq!((*self.ptr).borrow, Nothing);
222-
(*self.ptr).borrow = Mutable;
223-
let res = f(&mut (*self.ptr).value);
224-
(*self.ptr).borrow = Nothing;
225-
res
226-
}
227-
}
228-
}
229-
230-
#[unsafe_destructor]
231-
impl<T> Drop for RcMut<T> {
232-
fn drop(&mut self) {
233-
unsafe {
234-
if self.ptr.is_not_null() {
235-
(*self.ptr).count -= 1;
236-
if (*self.ptr).count == 0 {
237-
let _: ~RcMutBox<T> = transmute(self.ptr);
238-
}
239-
}
240-
}
241-
}
242-
}
243-
244-
impl<T> Clone for RcMut<T> {
245-
/// Return a shallow copy of the reference counted pointer.
246-
#[inline]
247-
fn clone(&self) -> RcMut<T> {
248-
unsafe {
249-
(*self.ptr).count += 1;
250-
RcMut{ptr: self.ptr}
251-
}
252-
}
253-
}
254-
255-
impl<T: DeepClone> DeepClone for RcMut<T> {
256-
/// Return a deep copy of the reference counted pointer.
257-
#[inline]
258-
fn deep_clone(&self) -> RcMut<T> {
259-
do self.with_borrow |x| {
260-
// FIXME: #6497: should avoid freeze (slow)
261-
unsafe { RcMut::new_unchecked(x.deep_clone()) }
262-
}
263-
}
264-
}
265-
266-
#[cfg(test)]
267-
mod test_rc_mut {
268-
use super::*;
269160

270161
#[test]
271-
fn test_clone() {
272-
let x = RcMut::from_send(5);
273-
let y = x.clone();
274-
do x.with_mut_borrow |value| {
275-
*value = 20;
276-
}
277-
do y.with_borrow |value| {
278-
assert_eq!(*value, 20);
279-
}
280-
}
281-
282-
#[test]
283-
fn test_deep_clone() {
284-
let x = RcMut::new(5);
285-
let y = x.deep_clone();
286-
do x.with_mut_borrow |value| {
287-
*value = 20;
288-
}
289-
do y.with_borrow |value| {
290-
assert_eq!(*value, 5);
291-
}
292-
}
293-
294-
#[test]
295-
fn borrow_many() {
296-
let x = RcMut::from_send(5);
297-
let y = x.clone();
298-
299-
do x.with_borrow |a| {
300-
assert_eq!(*a, 5);
301-
do y.with_borrow |b| {
302-
assert_eq!(*b, 5);
303-
do x.with_borrow |c| {
304-
assert_eq!(*c, 5);
305-
}
306-
}
307-
}
308-
}
309-
310-
#[test]
311-
fn modify() {
312-
let x = RcMut::new(5);
313-
let y = x.clone();
314-
315-
do y.with_mut_borrow |a| {
316-
assert_eq!(*a, 5);
317-
*a = 6;
318-
}
319-
320-
do x.with_borrow |a| {
321-
assert_eq!(*a, 6);
322-
}
323-
}
324-
325-
#[test]
326-
fn release_immutable() {
327-
let x = RcMut::from_send(5);
328-
do x.with_borrow |_| {}
329-
do x.with_mut_borrow |_| {}
330-
}
331-
332-
#[test]
333-
fn release_mutable() {
334-
let x = RcMut::new(5);
335-
do x.with_mut_borrow |_| {}
336-
do x.with_borrow |_| {}
337-
}
338-
339-
#[test]
340-
#[should_fail]
341-
fn frozen() {
342-
let x = RcMut::from_send(5);
343-
let y = x.clone();
344-
345-
do x.with_borrow |_| {
346-
do y.with_mut_borrow |_| {
347-
}
348-
}
349-
}
350-
351-
#[test]
352-
#[should_fail]
353-
fn mutable_dupe() {
354-
let x = RcMut::new(5);
355-
let y = x.clone();
356-
357-
do x.with_mut_borrow |_| {
358-
do y.with_mut_borrow |_| {
359-
}
360-
}
361-
}
362-
363-
#[test]
364-
#[should_fail]
365-
fn mutable_freeze() {
366-
let x = RcMut::from_send(5);
367-
let y = x.clone();
368-
369-
do x.with_mut_borrow |_| {
370-
do y.with_borrow |_| {
371-
}
372-
}
373-
}
374-
375-
#[test]
376-
#[should_fail]
377-
fn restore_freeze() {
378-
let x = RcMut::new(5);
379-
let y = x.clone();
380-
381-
do x.with_borrow |_| {
382-
do x.with_borrow |_| {}
383-
do y.with_mut_borrow |_| {}
384-
}
162+
fn test_from_mut() {
163+
let a = 10;
164+
let _x = Rc::from_mut(RefCell::new(&a));
385165
}
386166
}

‎src/libstd/rt/comm.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ use rt::select::{SelectInner, SelectPortInner};
2222
use select::{Select, SelectPort};
2323
use unstable::atomics::{AtomicUint, AtomicOption, Acquire, Relaxed, SeqCst};
2424
use unstable::sync::UnsafeArc;
25+
use util;
2526
use util::Void;
2627
use comm::{GenericChan, GenericSmartChan, GenericPort, Peekable, SendDeferred};
27-
use cell::Cell;
28+
use cell::{Cell, RefCell};
2829
use clone::Clone;
2930
use tuple::ImmutableTuple;
3031

@@ -431,28 +432,28 @@ type StreamPortOne<T> = PortOne<StreamPayload<T>>;
431432

432433
/// A channel with unbounded size.
433434
pub struct Chan<T> {
434-
// FIXME #5372. Using Cell because we don't take &mut self
435-
next: Cell<StreamChanOne<T>>
435+
// FIXME #5372. Using RefCell because we don't take &mut self
436+
next: RefCell<StreamChanOne<T>>
436437
}
437438

438439
/// An port with unbounded size.
439440
pub struct Port<T> {
440-
// FIXME #5372. Using Cell because we don't take &mut self
441-
next: Cell<StreamPortOne<T>>
441+
// FIXME #5372. Using RefCell because we don't take &mut self
442+
next: RefCell<Option<StreamPortOne<T>>>
442443
}
443444

444445
pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
445446
let (pone, cone) = oneshot();
446-
let port = Port { next: Cell::new(pone) };
447-
let chan = Chan { next: Cell::new(cone) };
447+
let port = Port { next: RefCell::new(Some(pone)) };
448+
let chan = Chan { next: RefCell::new(cone) };
448449
return (port, chan);
449450
}
450451

451452
impl<T: Send> Chan<T> {
452453
fn try_send_inner(&self, val: T, do_resched: bool) -> bool {
453-
let (next_pone, next_cone) = oneshot();
454-
let cone = self.next.take();
455-
self.next.put_back(next_cone);
454+
let (next_pone, mut cone) = oneshot();
455+
let mut b = self.next.borrow_mut();
456+
util::swap(&mut cone, b.get());
456457
cone.try_send_inner(StreamPayload { val: val, next: next_pone }, do_resched)
457458
}
458459
}
@@ -489,10 +490,11 @@ impl<T: Send> GenericPort<T> for Port<T> {
489490
}
490491

491492
fn try_recv(&self) -> Option<T> {
492-
do self.next.take_opt().map_default(None) |pone| {
493+
let mut b = self.next.borrow_mut();
494+
do b.get().take().map_default(None) |pone| {
493495
match pone.try_recv() {
494496
Some(StreamPayload { val, next }) => {
495-
self.next.put_back(next);
497+
*b.get() = Some(next);
496498
Some(val)
497499
}
498500
None => None
@@ -503,7 +505,7 @@ impl<T: Send> GenericPort<T> for Port<T> {
503505

504506
impl<T: Send> Peekable<T> for Port<T> {
505507
fn peek(&self) -> bool {
506-
self.next.with_mut_ref(|p| p.peek())
508+
self.next.with_mut(|p| p.get_mut_ref().peek())
507509
}
508510
}
509511

@@ -514,18 +516,18 @@ impl<T: Send> Peekable<T> for Port<T> {
514516
impl<'self, T: Send> SelectInner for &'self Port<T> {
515517
#[inline]
516518
fn optimistic_check(&mut self) -> bool {
517-
do self.next.with_mut_ref |pone| { pone.optimistic_check() }
519+
do self.next.with_mut |pone| { pone.get_mut_ref().optimistic_check() }
518520
}
519521

520522
#[inline]
521523
fn block_on(&mut self, sched: &mut Scheduler, task: BlockedTask) -> bool {
522-
let task = Cell::new(task);
523-
do self.next.with_mut_ref |pone| { pone.block_on(sched, task.take()) }
524+
let mut b = self.next.borrow_mut();
525+
b.get().get_mut_ref().block_on(sched, task)
524526
}
525527

526528
#[inline]
527529
fn unblock_from(&mut self) -> bool {
528-
do self.next.with_mut_ref |pone| { pone.unblock_from() }
530+
do self.next.with_mut |pone| { pone.get_mut_ref().unblock_from() }
529531
}
530532
}
531533

@@ -552,9 +554,10 @@ impl<T: Send> Select for Port<T> { }
552554

553555
impl<'self, T: Send> SelectPortInner<T> for &'self Port<T> {
554556
fn recv_ready(self) -> Option<T> {
555-
match self.next.take().recv_ready() {
557+
let mut b = self.next.borrow_mut();
558+
match b.get().take_unwrap().recv_ready() {
556559
Some(StreamPayload { val, next }) => {
557-
self.next.put_back(next);
560+
*b.get() = Some(next);
558561
Some(val)
559562
}
560563
None => None
@@ -571,7 +574,7 @@ pub struct SharedChan<T> {
571574

572575
impl<T: Send> SharedChan<T> {
573576
pub fn new(chan: Chan<T>) -> SharedChan<T> {
574-
let next = chan.next.take();
577+
let next = chan.next.unwrap();
575578
let next = AtomicOption::new(~next);
576579
SharedChan { next: UnsafeArc::new(next) }
577580
}
@@ -625,7 +628,7 @@ pub struct SharedPort<T> {
625628
impl<T: Send> SharedPort<T> {
626629
pub fn new(port: Port<T>) -> SharedPort<T> {
627630
// Put the data port into a new link pipe
628-
let next_data_port = port.next.take();
631+
let next_data_port = port.next.unwrap().unwrap();
629632
let (next_link_port, next_link_chan) = oneshot();
630633
next_link_chan.send(next_data_port);
631634
let next_link = AtomicOption::new(~next_link_port);

‎src/test/bench/msgsend-ring-mutex-arcs.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ fn main() {
8181
let num_tasks = from_str::<uint>(args[1]).unwrap();
8282
let msg_per_task = from_str::<uint>(args[2]).unwrap();
8383

84-
let (num_chan, num_port) = init();
85-
let num_chan = Cell::new(num_chan);
84+
let (mut num_chan, num_port) = init();
8685

8786
let start = time::precise_time_s();
8887

@@ -92,19 +91,19 @@ fn main() {
9291
for i in range(1u, num_tasks) {
9392
//error!("spawning %?", i);
9493
let (new_chan, num_port) = init();
95-
let num_chan2 = Cell::new(num_chan.take());
94+
let num_chan2 = Cell::new(num_chan);
9695
let num_port = Cell::new(num_port);
9796
let new_future = do Future::spawn() {
9897
let num_chan = num_chan2.take();
9998
let num_port1 = num_port.take();
10099
thread_ring(i, msg_per_task, num_chan, num_port1)
101100
};
102101
futures.push(new_future);
103-
num_chan.put_back(new_chan);
102+
num_chan = new_chan;
104103
};
105104

106105
// do our iteration
107-
thread_ring(0, msg_per_task, num_chan.take(), num_port);
106+
thread_ring(0, msg_per_task, num_chan, num_port);
108107

109108
// synchronize
110109
for f in futures.mut_iter() {

‎src/test/bench/msgsend-ring-rw-arcs.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ fn main() {
7777
let num_tasks = from_str::<uint>(args[1]).unwrap();
7878
let msg_per_task = from_str::<uint>(args[2]).unwrap();
7979

80-
let (num_chan, num_port) = init();
81-
let num_chan = Cell::new(num_chan);
80+
let (mut num_chan, num_port) = init();
8281

8382
let start = time::precise_time_s();
8483

@@ -88,19 +87,19 @@ fn main() {
8887
for i in range(1u, num_tasks) {
8988
//error!("spawning %?", i);
9089
let (new_chan, num_port) = init();
91-
let num_chan2 = Cell::new(num_chan.take());
90+
let num_chan2 = Cell::new(num_chan);
9291
let num_port = Cell::new(num_port);
9392
let new_future = do Future::spawn {
9493
let num_chan = num_chan2.take();
9594
let num_port1 = num_port.take();
9695
thread_ring(i, msg_per_task, num_chan, num_port1)
9796
};
9897
futures.push(new_future);
99-
num_chan.put_back(new_chan);
98+
num_chan = new_chan;
10099
};
101100

102101
// do our iteration
103-
thread_ring(0, msg_per_task, num_chan.take(), num_port);
102+
thread_ring(0, msg_per_task, num_chan, num_port);
104103

105104
// synchronize
106105
for f in futures.mut_iter() {

‎src/test/compile-fail/issue-7013.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,22 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::rc::RcMut;
11+
use std::rc::Rc;
12+
use std::cell::RefCell;
1213

1314
trait Foo
1415
{
15-
fn set(&mut self, v: RcMut<A>);
16+
fn set(&mut self, v: Rc<RefCell<A>>);
1617
}
1718

1819
struct B
1920
{
20-
v: Option<RcMut<A>>
21+
v: Option<Rc<RefCell<A>>>
2122
}
2223

2324
impl Foo for B
2425
{
25-
fn set(&mut self, v: RcMut<A>)
26+
fn set(&mut self, v: Rc<RefCell<A>>)
2627
{
2728
self.v = Some(v);
2829
}
@@ -36,7 +37,9 @@ struct A
3637
fn main()
3738
{
3839
let a = A {v: ~B{v: None} as ~Foo}; //~ ERROR cannot pack type `~B`, which does not fulfill `Send`
39-
let v = RcMut::new(a); //~ ERROR instantiating a type parameter with an incompatible type
40+
let v = Rc::from_send(RefCell::new(a));
4041
let w = v.clone();
41-
v.with_mut_borrow(|p| {p.v.set(w.clone());})
42+
let b = v.borrow();
43+
let mut b = b.borrow_mut();
44+
b.get().v.set(w.clone());
4245
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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::cell::RefCell;
12+
13+
fn main() {
14+
let m = RefCell::new(0);
15+
let mut b = m.borrow_mut();
16+
let b1 = b.get();
17+
let b2 = b.get(); //~ ERROR cannot borrow `b` as mutable more than once at a time
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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::cell::RefCell;
12+
13+
fn f<T: Freeze>(_: T) {}
14+
15+
fn main() {
16+
let x = RefCell::new(0);
17+
f(x); //~ ERROR: which does not fulfill `Freeze`
18+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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::cell::RefCell;
12+
13+
fn main() {
14+
let m = RefCell::new(0);
15+
let p;
16+
{
17+
let b = m.borrow();
18+
p = b.get(); //~ ERROR borrowed value does not live long enough
19+
}
20+
}

‎src/test/compile-fail/rcmut-not-const-and-not-owned.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::rc::RcMut;
11+
use std::cell::RefCell;
12+
use std::rc::Rc;
1213

1314
fn o<T: Send>(_: &T) {}
1415
fn c<T: Freeze>(_: &T) {}
1516

1617
fn main() {
17-
let x = RcMut::from_send(0);
18-
o(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::RcMut<int>`, which does not fulfill `Send`
19-
c(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::RcMut<int>`, which does not fulfill `Freeze`
18+
let x = Rc::from_send(RefCell::new(0));
19+
o(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Send`
20+
c(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Freeze`
2021
}

0 commit comments

Comments
 (0)
Please sign in to comment.