// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Runtime move semantics
+//! Types dealing with dynamic mutability
#[missing_doc];
-use cast::transmute_mut;
use prelude::*;
+use cast;
+use util::NonCopyable;
+
/*
A dynamic, mutable location.
/// Yields the value, failing if the cell is empty.
pub fn take(&self) -> T {
- let this = unsafe { transmute_mut(self) };
+ let this = unsafe { cast::transmute_mut(self) };
if this.is_empty() {
fail!("attempt to take an empty cell");
}
/// Yields the value if the cell is full, or `None` if it is empty.
pub fn take_opt(&self) -> Option<T> {
- let this = unsafe { transmute_mut(self) };
+ let this = unsafe { cast::transmute_mut(self) };
this.value.take()
}
value_cell.take();
value_cell.take();
}
+
+
+/// A mutable memory location with dynamically checked borrow rules
+#[no_freeze]
+pub struct RefCell<T> {
+ priv value: T,
+ priv borrow: BorrowFlag,
+ priv nc: NonCopyable
+}
+
+// Values [1, MAX-1] represent the number of `Ref` active
+// (will not outgrow its range since `uint` is the size of the address space)
+type BorrowFlag = uint;
+static UNUSED: BorrowFlag = 0;
+static WRITING: BorrowFlag = -1;
+
+impl<T> RefCell<T> {
+ /// Create a new `RefCell` containing `value`
+ pub fn new(value: T) -> RefCell<T> {
+ RefCell {
+ value: value,
+ borrow: UNUSED,
+ nc: NonCopyable
+ }
+ }
+
+ /// Consumes the `RefCell`, returning the wrapped value.
+ pub fn unwrap(self) -> T {
+ assert!(self.borrow == UNUSED);
+ self.value
+ }
+
+ unsafe fn as_mut<'a>(&'a self) -> &'a mut RefCell<T> {
+ cast::transmute_mut(self)
+ }
+
+ /// Attempts to immutably borrow the wrapped value.
+ ///
+ /// The borrow lasts until the returned `Ref` exits scope. Multiple
+ /// immutable borrows can be taken out at the same time.
+ ///
+ /// Returns `None` if the value is currently mutably borrowed.
+ pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
+ match self.borrow {
+ WRITING => None,
+ _ => {
+ unsafe { self.as_mut().borrow += 1; }
+ Some(Ref { parent: self })
+ }
+ }
+ }
+
+ /// Immutably borrows the wrapped value.
+ ///
+ /// The borrow lasts until the returned `Ref` exits scope. Multiple
+ /// immutable borrows can be taken out at the same time.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the value is currently mutably borrowed.
+ pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
+ match self.try_borrow() {
+ Some(ptr) => ptr,
+ None => fail!("RefCell<T> already mutably borrowed")
+ }
+ }
+
+ /// Mutably borrows the wrapped value.
+ ///
+ /// The borrow lasts untile the returned `RefMut` exits scope. The value
+ /// cannot be borrowed while this borrow is active.
+ ///
+ /// Returns `None` if the value is currently borrowed.
+ pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
+ match self.borrow {
+ UNUSED => unsafe {
+ let mut_self = self.as_mut();
+ mut_self.borrow = WRITING;
+ Some(RefMut { parent: mut_self })
+ },
+ _ => None
+ }
+ }
+
+ /// Mutably borrows the wrapped value.
+ ///
+ /// The borrow lasts untile the returned `RefMut` exits scope. The value
+ /// cannot be borrowed while this borrow is active.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the value is currently borrowed.
+ pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
+ match self.try_borrow_mut() {
+ Some(ptr) => ptr,
+ None => fail!("RefCell<T> already borrowed")
+ }
+ }
+
+ /// Immutably borrows the wrapped value and applies `blk` to it.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the value is currently mutably borrowed.
+ #[inline]
+ pub fn with<U>(&self, blk: |&T| -> U) -> U {
+ let ptr = self.borrow();
+ blk(ptr.get())
+ }
+
+ /// Mutably borrows the wrapped value and applies `blk` to it.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the value is currently borrowed.
+ #[inline]
+ pub fn with_mut<U>(&self, blk: |&mut T| -> U) -> U {
+ let mut ptr = self.borrow_mut();
+ blk(ptr.get())
+ }
+}
+
+impl<T: Clone> Clone for RefCell<T> {
+ fn clone(&self) -> RefCell<T> {
+ let x = self.borrow();
+ RefCell::new(x.get().clone())
+ }
+}
+
+impl<T: DeepClone> DeepClone for RefCell<T> {
+ fn deep_clone(&self) -> RefCell<T> {
+ let x = self.borrow();
+ RefCell::new(x.get().deep_clone())
+ }
+}
+
+impl<T: Eq> Eq for RefCell<T> {
+ fn eq(&self, other: &RefCell<T>) -> bool {
+ let a = self.borrow();
+ let b = other.borrow();
+ a.get() == b.get()
+ }
+}
+
+/// Wraps a borrowed reference to a value in a `RefCell` box.
+pub struct Ref<'box, T> {
+ priv parent: &'box RefCell<T>
+}
+
+#[unsafe_destructor]
+impl<'box, T> Drop for Ref<'box, T> {
+ fn drop(&mut self) {
+ assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED);
+ unsafe { self.parent.as_mut().borrow -= 1; }
+ }
+}
+
+impl<'box, T> Ref<'box, T> {
+ /// Retrieve an immutable reference to the stored value.
+ #[inline]
+ pub fn get<'a>(&'a self) -> &'a T {
+ &self.parent.value
+ }
+}
+
+/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
+pub struct RefMut<'box, T> {
+ priv parent: &'box mut RefCell<T>
+}
+
+#[unsafe_destructor]
+impl<'box, T> Drop for RefMut<'box, T> {
+ fn drop(&mut self) {
+ assert!(self.parent.borrow == WRITING);
+ self.parent.borrow = UNUSED;
+ }
+}
+
+impl<'box, T> RefMut<'box, T> {
+ /// Retrieve a mutable reference to the stored value.
+ #[inline]
+ pub fn get<'a>(&'a mut self) -> &'a mut T {
+ &mut self.parent.value
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn double_imm_borrow() {
+ let x = RefCell::new(0);
+ let _b1 = x.borrow();
+ x.borrow();
+ }
+
+ #[test]
+ fn no_mut_then_imm_borrow() {
+ let x = RefCell::new(0);
+ let _b1 = x.borrow_mut();
+ assert!(x.try_borrow().is_none());
+ }
+
+ #[test]
+ fn no_imm_then_borrow_mut() {
+ let x = RefCell::new(0);
+ let _b1 = x.borrow();
+ assert!(x.try_borrow_mut().is_none());
+ }
+
+ #[test]
+ fn no_double_borrow_mut() {
+ let x = RefCell::new(0);
+ let _b1 = x.borrow_mut();
+ assert!(x.try_borrow_mut().is_none());
+ }
+
+ #[test]
+ fn imm_release_borrow_mut() {
+ let x = RefCell::new(0);
+ {
+ let _b1 = x.borrow();
+ }
+ x.borrow_mut();
+ }
+
+ #[test]
+ fn mut_release_borrow_mut() {
+ let x = RefCell::new(0);
+ {
+ let _b1 = x.borrow_mut();
+ }
+ x.borrow();
+ }
+
+ #[test]
+ fn double_borrow_single_release_no_borrow_mut() {
+ let x = RefCell::new(0);
+ let _b1 = x.borrow();
+ {
+ let _b2 = x.borrow();
+ }
+ assert!(x.try_borrow_mut().is_none());
+ }
+
+ #[test]
+ fn with_ok() {
+ let x = RefCell::new(0);
+ assert_eq!(1, x.with(|x| *x+1));
+ }
+
+ #[test]
+ #[should_fail]
+ fn mut_borrow_with() {
+ let x = RefCell::new(0);
+ let _b1 = x.borrow_mut();
+ x.with(|x| *x+1);
+ }
+
+ #[test]
+ fn borrow_with() {
+ let x = RefCell::new(0);
+ let _b1 = x.borrow();
+ assert_eq!(1, x.with(|x| *x+1));
+ }
+
+ #[test]
+ fn with_mut_ok() {
+ let x = RefCell::new(0);
+ x.with_mut(|x| *x += 1);
+ let b = x.borrow();
+ assert_eq!(1, *b.get());
+ }
+
+ #[test]
+ #[should_fail]
+ fn borrow_with_mut() {
+ let x = RefCell::new(0);
+ let _b = x.borrow();
+ x.with_mut(|x| *x += 1);
+ }
+
+ #[test]
+ #[should_fail]
+ fn discard_doesnt_unborrow() {
+ let x = RefCell::new(0);
+ let _b = x.borrow();
+ let _ = _b;
+ let _b = x.borrow_mut();
+ }
+}
#[cfg(test)]
mod tests {
use super::*;
- use cell::Cell;
+ use cell::RefCell;
#[test]
fn test_clone() {
- let x = Gc::new(Cell::new(5));
+ let x = Gc::new(RefCell::new(5));
let y = x.clone();
- do x.borrow().with_mut_ref |inner| {
+ do x.borrow().with_mut |inner| {
*inner = 20;
}
- assert_eq!(y.borrow().take(), 20);
+ assert_eq!(y.borrow().with(|x| *x), 20);
}
#[test]
fn test_deep_clone() {
- let x = Gc::new(Cell::new(5));
+ let x = Gc::new(RefCell::new(5));
let y = x.deep_clone();
- do x.borrow().with_mut_ref |inner| {
+ do x.borrow().with_mut |inner| {
*inner = 20;
}
- assert_eq!(y.borrow().take(), 5);
+ assert_eq!(y.borrow().with(|x| *x), 5);
}
#[test]
pub mod either;
pub mod hashmap;
pub mod cell;
-pub mod mutable;
pub mod trie;
+++ /dev/null
-// 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.
-
-//! A mutable memory location with dynamically checked borrow rules
-
-use prelude::*;
-
-use cast;
-use util::NonCopyable;
-
-/// A mutable memory location with dynamically checked borrow rules
-#[no_freeze]
-pub struct Mut<T> {
- priv value: T,
- priv borrow: BorrowFlag,
- priv nc: NonCopyable
-}
-
-// Values [1, MAX-1] represent the number of `Ref` active
-// (will not outgrow its range since `uint` is the size of the address space)
-type BorrowFlag = uint;
-static UNUSED: BorrowFlag = 0;
-static WRITING: BorrowFlag = -1;
-
-impl<T> Mut<T> {
- /// Create a new `Mut` containing `value`
- pub fn new(value: T) -> Mut<T> {
- Mut {
- value: value,
- borrow: UNUSED,
- nc: NonCopyable
- }
- }
-
- /// Consumes the `Mut`, returning the wrapped value.
- pub fn unwrap(self) -> T {
- assert!(self.borrow == UNUSED);
- self.value
- }
-
- unsafe fn as_mut<'a>(&'a self) -> &'a mut Mut<T> {
- cast::transmute_mut(self)
- }
-
- /// Attempts to immutably borrow the wrapped value.
- ///
- /// The borrow lasts until the returned `Ref` exits scope. Multiple
- /// immutable borrows can be taken out at the same time.
- ///
- /// Returns `None` if the value is currently mutably borrowed.
- pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
- match self.borrow {
- WRITING => None,
- _ => {
- unsafe { self.as_mut().borrow += 1; }
- Some(Ref { parent: self })
- }
- }
- }
-
- /// Immutably borrows the wrapped value.
- ///
- /// The borrow lasts until the returned `Ref` exits scope. Multiple
- /// immutable borrows can be taken out at the same time.
- ///
- /// # Failure
- ///
- /// Fails if the value is currently mutably borrowed.
- pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
- match self.try_borrow() {
- Some(ptr) => ptr,
- None => fail!("Mut<T> already mutably borrowed")
- }
- }
-
- /// Mutably borrows the wrapped value.
- ///
- /// The borrow lasts untile the returned `RefMut` exits scope. The value
- /// cannot be borrowed while this borrow is active.
- ///
- /// Returns `None` if the value is currently borrowed.
- pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
- match self.borrow {
- UNUSED => unsafe {
- let mut_self = self.as_mut();
- mut_self.borrow = WRITING;
- Some(RefMut { parent: mut_self })
- },
- _ => None
- }
- }
-
- /// Mutably borrows the wrapped value.
- ///
- /// The borrow lasts untile the returned `RefMut` exits scope. The value
- /// cannot be borrowed while this borrow is active.
- ///
- /// # Failure
- ///
- /// Fails if the value is currently borrowed.
- pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
- match self.try_borrow_mut() {
- Some(ptr) => ptr,
- None => fail!("Mut<T> already borrowed")
- }
- }
-
- /// Immutably borrows the wrapped value and applies `blk` to it.
- ///
- /// # Failure
- ///
- /// Fails if the value is currently mutably borrowed.
- #[inline]
- pub fn with<U>(&self, blk: |&T| -> U) -> U {
- let ptr = self.borrow();
- blk(ptr.get())
- }
-
- /// Mutably borrows the wrapped value and applies `blk` to it.
- ///
- /// # Failure
- ///
- /// Fails if the value is currently borrowed.
- #[inline]
- pub fn with_mut<U>(&self, blk: |&mut T| -> U) -> U {
- let mut ptr = self.borrow_mut();
- blk(ptr.get())
- }
-}
-
-impl<T: Clone> Clone for Mut<T> {
- fn clone(&self) -> Mut<T> {
- let x = self.borrow();
- Mut::new(x.get().clone())
- }
-}
-
-impl<T: DeepClone> DeepClone for Mut<T> {
- fn deep_clone(&self) -> Mut<T> {
- let x = self.borrow();
- Mut::new(x.get().deep_clone())
- }
-}
-
-impl<T: Eq> Eq for Mut<T> {
- fn eq(&self, other: &Mut<T>) -> bool {
- let a = self.borrow();
- let b = other.borrow();
- a.get() == b.get()
- }
-}
-
-/// Wraps a borrowed reference to a value in a `Mut` box.
-pub struct Ref<'box, T> {
- priv parent: &'box Mut<T>
-}
-
-#[unsafe_destructor]
-impl<'box, T> Drop for Ref<'box, T> {
- fn drop(&mut self) {
- assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED);
- unsafe { self.parent.as_mut().borrow -= 1; }
- }
-}
-
-impl<'box, T> Ref<'box, T> {
- /// Retrieve an immutable reference to the stored value.
- #[inline]
- pub fn get<'a>(&'a self) -> &'a T {
- &self.parent.value
- }
-}
-
-/// Wraps a mutable borrowed reference to a value in a `Mut` box.
-pub struct RefMut<'box, T> {
- priv parent: &'box mut Mut<T>
-}
-
-#[unsafe_destructor]
-impl<'box, T> Drop for RefMut<'box, T> {
- fn drop(&mut self) {
- assert!(self.parent.borrow == WRITING);
- self.parent.borrow = UNUSED;
- }
-}
-
-impl<'box, T> RefMut<'box, T> {
- /// Retrieve a mutable reference to the stored value.
- #[inline]
- pub fn get<'a>(&'a mut self) -> &'a mut T {
- &mut self.parent.value
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn double_imm_borrow() {
- let x = Mut::new(0);
- let _b1 = x.borrow();
- x.borrow();
- }
-
- #[test]
- fn no_mut_then_imm_borrow() {
- let x = Mut::new(0);
- let _b1 = x.borrow_mut();
- assert!(x.try_borrow().is_none());
- }
-
- #[test]
- fn no_imm_then_borrow_mut() {
- let x = Mut::new(0);
- let _b1 = x.borrow();
- assert!(x.try_borrow_mut().is_none());
- }
-
- #[test]
- fn no_double_borrow_mut() {
- let x = Mut::new(0);
- let _b1 = x.borrow_mut();
- assert!(x.try_borrow_mut().is_none());
- }
-
- #[test]
- fn imm_release_borrow_mut() {
- let x = Mut::new(0);
- {
- let _b1 = x.borrow();
- }
- x.borrow_mut();
- }
-
- #[test]
- fn mut_release_borrow_mut() {
- let x = Mut::new(0);
- {
- let _b1 = x.borrow_mut();
- }
- x.borrow();
- }
-
- #[test]
- fn double_borrow_single_release_no_borrow_mut() {
- let x = Mut::new(0);
- let _b1 = x.borrow();
- {
- let _b2 = x.borrow();
- }
- assert!(x.try_borrow_mut().is_none());
- }
-
- #[test]
- fn with_ok() {
- let x = Mut::new(0);
- assert_eq!(1, x.with(|x| *x+1));
- }
-
- #[test]
- #[should_fail]
- fn mut_borrow_with() {
- let x = Mut::new(0);
- let _b1 = x.borrow_mut();
- x.with(|x| *x+1);
- }
-
- #[test]
- fn borrow_with() {
- let x = Mut::new(0);
- let _b1 = x.borrow();
- assert_eq!(1, x.with(|x| *x+1));
- }
-
- #[test]
- fn with_mut_ok() {
- let x = Mut::new(0);
- x.with_mut(|x| *x += 1);
- let b = x.borrow();
- assert_eq!(1, *b.get());
- }
-
- #[test]
- #[should_fail]
- fn borrow_with_mut() {
- let x = Mut::new(0);
- let _b = x.borrow();
- x.with_mut(|x| *x += 1);
- }
-
- #[test]
- #[should_fail]
- fn discard_doesnt_unborrow() {
- let x = Mut::new(0);
- let _b = x.borrow();
- let _ = _b;
- let _b = x.borrow_mut();
- }
-}
use ops::Drop;
use kinds::{Freeze, Send};
use clone::{Clone, DeepClone};
-use mutable::Mut;
+use cell::RefCell;
struct RcBox<T> {
value: T,
}
}
-impl<T: Freeze> Rc<Mut<T>> {
- /// Construct a new reference-counted box from a `Mut`-wrapped `Freeze` 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: Mut<T>) -> Rc<Mut<T>> {
+ pub fn from_mut(value: RefCell<T>) -> Rc<RefCell<T>> {
unsafe {
Rc::new_unchecked(value)
}
#[cfg(test)]
mod test_rc {
use super::*;
- use mutable::Mut;
+ use cell::RefCell;
#[test]
fn test_clone() {
- let x = Rc::from_send(Mut::new(5));
+ let x = Rc::from_send(RefCell::new(5));
let y = x.clone();
do x.borrow().with_mut |inner| {
*inner = 20;
#[test]
fn test_deep_clone() {
- let x = Rc::from_send(Mut::new(5));
+ let x = Rc::from_send(RefCell::new(5));
let y = x.deep_clone();
do x.borrow().with_mut |inner| {
*inner = 20;
#[test]
fn test_from_mut() {
let a = 10;
- let _x = Rc::from_mut(Mut::new(&a));
+ let _x = Rc::from_mut(RefCell::new(&a));
}
}
use util;
use util::Void;
use comm::{GenericChan, GenericSmartChan, GenericPort, Peekable, SendDeferred};
-use cell::Cell;
+use cell::{Cell, RefCell};
use clone::Clone;
use tuple::ImmutableTuple;
-use mutable::Mut;
/// A combined refcount / BlockedTask-as-uint pointer.
///
/// A channel with unbounded size.
pub struct Chan<T> {
- // FIXME #5372. Using Mut because we don't take &mut self
- next: Mut<StreamChanOne<T>>
+ // FIXME #5372. Using RefCell because we don't take &mut self
+ next: RefCell<StreamChanOne<T>>
}
/// An port with unbounded size.
pub struct Port<T> {
- // FIXME #5372. Using Mut because we don't take &mut self
- next: Mut<Option<StreamPortOne<T>>>
+ // FIXME #5372. Using RefCell because we don't take &mut self
+ next: RefCell<Option<StreamPortOne<T>>>
}
pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
let (pone, cone) = oneshot();
- let port = Port { next: Mut::new(Some(pone)) };
- let chan = Chan { next: Mut::new(cone) };
+ let port = Port { next: RefCell::new(Some(pone)) };
+ let chan = Chan { next: RefCell::new(cone) };
return (port, chan);
}
// except according to those terms.
use std::rc::Rc;
-use std::mutable::Mut;
+use std::cell::RefCell;
trait Foo
{
- fn set(&mut self, v: Rc<Mut<A>>);
+ fn set(&mut self, v: Rc<RefCell<A>>);
}
struct B
{
- v: Option<Rc<Mut<A>>>
+ v: Option<Rc<RefCell<A>>>
}
impl Foo for B
{
- fn set(&mut self, v: Rc<Mut<A>>)
+ fn set(&mut self, v: Rc<RefCell<A>>)
{
self.v = Some(v);
}
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(Mut::new(a));
+ let v = Rc::from_send(RefCell::new(a));
let w = v.clone();
let b = v.borrow();
let mut b = b.borrow_mut();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::mutable::Mut;
+use std::cell::RefCell;
fn main() {
- let m = Mut::new(0);
+ let m = RefCell::new(0);
let mut b = m.borrow_mut();
let b1 = b.get();
let b2 = b.get(); //~ ERROR cannot borrow `b` as mutable more than once at a time
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::mutable::Mut;
+use std::cell::RefCell;
fn f<T: Freeze>(_: T) {}
fn main() {
- let x = Mut::new(0);
+ let x = RefCell::new(0);
f(x); //~ ERROR: which does not fulfill `Freeze`
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::mutable::Mut;
+use std::cell::RefCell;
fn main() {
- let m = Mut::new(0);
+ let m = RefCell::new(0);
let p;
{
let b = m.borrow();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::mutable::Mut;
+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(Mut::new(0));
- o(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::mutable::Mut<int>>`, which does not fulfill `Send`
- c(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::mutable::Mut<int>>`, which does not fulfill `Freeze`
+ 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`
}