diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2012-09-10 16:34:31 -0700 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2012-09-10 16:50:07 -0700 |
| commit | 29003c799f41cce948bc043cdd1350ca4bee949e (patch) | |
| tree | 0e879812117977b10d42558588f952b792fa5f99 /src/libcore/mutable.rs | |
| parent | 20263595185590c8c2705b92bddbd00e3fc56713 (diff) | |
| download | rust-29003c799f41cce948bc043cdd1350ca4bee949e.tar.gz rust-29003c799f41cce948bc043cdd1350ca4bee949e.zip | |
Rename the poorly named Managed<T> type to Mut<T>.
The Mut<T> type is intended to allow freezable data stuctures to be stored in `@mut` boxes. Currently this causes borrowck to be very conserivative since it cannot prove that you are not modifying such a structure while iterating over it, for example. But if you do `@Mut<T>` instead of `@mut T`, you will effectively convert borrowck's static checks into dynamic ones. This lets you use the e.g. send_map just like a Java Map or something else.
Diffstat (limited to 'src/libcore/mutable.rs')
| -rw-r--r-- | src/libcore/mutable.rs | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/libcore/mutable.rs b/src/libcore/mutable.rs new file mode 100644 index 00000000000..eca9ff6fada --- /dev/null +++ b/src/libcore/mutable.rs @@ -0,0 +1,151 @@ +/*! + +Module for wrapping freezable data structures in managed boxes. +Normally freezable data structures require an unaliased reference, +such as `T` or `~T`, so that the compiler can track when they are +being mutated. The `managed<T>` type converts these static checks into +dynamic checks: your program will fail if you attempt to perform +mutation when the data structure should be immutable. + +*/ + +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; + +use util::with; +use unsafe::transmute_immut; + +export Mut; + +enum Mode { ReadOnly, Mutable, Immutable } + +struct Data<T> { + priv mut value: T, + priv mut mode: Mode +} + +type Mut<T> = Data<T>; + +fn Mut<T>(+t: T) -> Mut<T> { + Data {value: t, mode: ReadOnly} +} + +fn unwrap<T>(+m: Mut<T>) -> T { + // Borrowck should prevent us from calling unwrap while the value + // is in use, as that would be a move from a borrowed value. + assert (m.mode as uint) == (ReadOnly as uint); + let Data {value, mode: _} = m; + return move value; +} + +impl<T> Data<T> { + fn borrow_mut<R>(op: &fn(t: &mut T) -> R) -> R { + match self.mode { + Immutable => fail fmt!("%? currently immutable", + self.value), + ReadOnly | Mutable => {} + } + + do with(&mut self.mode, Mutable) { + op(&mut self.value) + } + } + + fn borrow_const<R>(op: &fn(t: &const T) -> R) -> R { + op(&const self.value) + } + + fn borrow_imm<R>(op: &fn(t: &T) -> R) -> R { + match self.mode { + Mutable => fail fmt!("%? currently mutable", + self.value), + ReadOnly | Immutable => {} + } + + do with(&mut self.mode, Immutable) { + op(unsafe{transmute_immut(&mut self.value)}) + } + } +} + +#[test] +#[ignore(cfg(windows))] +#[should_fail] +fn test_mut_in_imm() { + let m = @Mut(1); + do m.borrow_imm |_p| { + do m.borrow_mut |_q| { + // should not be permitted + } + } +} + +#[test] +#[ignore(cfg(windows))] +#[should_fail] +fn test_imm_in_mut() { + let m = @Mut(1); + do m.borrow_mut |_p| { + do m.borrow_imm |_q| { + // should not be permitted + } + } +} + +#[test] +fn test_const_in_mut() { + let m = @Mut(1); + do m.borrow_mut |p| { + do m.borrow_const |q| { + assert *p == *q; + *p += 1; + assert *p == *q; + } + } +} + +#[test] +fn test_mut_in_const() { + let m = @Mut(1); + do m.borrow_const |p| { + do m.borrow_mut |q| { + assert *p == *q; + *q += 1; + assert *p == *q; + } + } +} + +#[test] +fn test_imm_in_const() { + let m = @Mut(1); + do m.borrow_const |p| { + do m.borrow_imm |q| { + assert *p == *q; + } + } +} + +#[test] +fn test_const_in_imm() { + let m = @Mut(1); + do m.borrow_imm |p| { + do m.borrow_const |q| { + assert *p == *q; + } + } +} + + +#[test] +#[ignore(cfg(windows))] +#[should_fail] +fn test_mut_in_imm_in_const() { + let m = @Mut(1); + do m.borrow_const |_p| { + do m.borrow_imm |_q| { + do m.borrow_mut |_r| { + } + } + } +} |
