From bba0680cb0801bc52d2abfc87bbf0885dc0355f8 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 2 May 2013 22:51:12 -0700 Subject: [PATCH] libstd: Remove mutable fields from future and par --- src/libstd/future.rs | 77 ++++++++++++++++++++++++++++++++------------ src/libstd/par.rs | 4 +-- 2 files changed, 58 insertions(+), 23 deletions(-) diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 5e3e64b2f1c..209859e3096 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -29,7 +29,7 @@ use core::task; #[doc = "The future type"] pub struct Future { - priv mut state: FutureState, + priv state: FutureState, } // FIXME(#2829) -- futures should not be copyable, because they close @@ -47,13 +47,14 @@ priv enum FutureState { /// Methods on the `future` type pub impl Future { - fn get(&self) -> A { + fn get(&mut self) -> A { //! Get the value of the future *(self.get_ref()) } } pub impl Future { + #[cfg(stage0)] fn get_ref<'a>(&'a self) -> &'a A { /*! * Executes the future's closure and then returns a borrowed @@ -61,19 +62,53 @@ pub impl Future { * the future. */ unsafe { - match self.state { - Forced(ref mut v) => { return cast::transmute(v); } - Evaluating => fail!(~"Recursive forcing of future!"), - Pending(_) => {} + { + match self.state { + Forced(ref mut v) => { return cast::transmute(v); } + Evaluating => fail!(~"Recursive forcing of future!"), + Pending(_) => {} + } } + { + let mut state = Evaluating; + self.state <-> state; + match state { + Forced(_) | Evaluating => fail!(~"Logic error."), + Pending(f) => { + self.state = Forced(f()); + cast::transmute(self.get_ref()) + } + } + } + } + } - let mut state = Evaluating; - self.state <-> state; - match state { - Forced(_) | Evaluating => fail!(~"Logic error."), - Pending(f) => { - self.state = Forced(f()); - self.get_ref() + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn get_ref<'a>(&'a mut self) -> &'a A { + /*! + * Executes the future's closure and then returns a borrowed + * pointer to the result. The borrowed pointer lasts as long as + * the future. + */ + unsafe { + { + match self.state { + Forced(ref mut v) => { return cast::transmute(v); } + Evaluating => fail!(~"Recursive forcing of future!"), + Pending(_) => {} + } + } + { + let mut state = Evaluating; + self.state <-> state; + match state { + Forced(_) | Evaluating => fail!(~"Logic error."), + Pending(f) => { + self.state = Forced(f()); + cast::transmute(self.get_ref()) + } } } } @@ -150,7 +185,7 @@ mod test { #[test] fn test_from_value() { - let f = from_value(~"snail"); + let mut f = from_value(~"snail"); assert!(f.get() == ~"snail"); } @@ -158,31 +193,31 @@ mod test { fn test_from_port() { let (po, ch) = oneshot(); send_one(ch, ~"whale"); - let f = from_port(po); + let mut f = from_port(po); assert!(f.get() == ~"whale"); } #[test] fn test_from_fn() { - let f = from_fn(|| ~"brail"); + let mut f = from_fn(|| ~"brail"); assert!(f.get() == ~"brail"); } #[test] fn test_interface_get() { - let f = from_value(~"fail"); + let mut f = from_value(~"fail"); assert!(f.get() == ~"fail"); } #[test] fn test_get_ref_method() { - let f = from_value(22); + let mut f = from_value(22); assert!(*f.get_ref() == 22); } #[test] fn test_spawn() { - let f = spawn(|| ~"bale"); + let mut f = spawn(|| ~"bale"); assert!(f.get() == ~"bale"); } @@ -190,14 +225,14 @@ mod test { #[should_fail] #[ignore(cfg(target_os = "win32"))] fn test_futurefail() { - let f = spawn(|| fail!()); + let mut f = spawn(|| fail!()); let _x: ~str = f.get(); } #[test] fn test_sendable_future() { let expected = ~"schlorf"; - let f = do spawn { copy expected }; + let mut f = do spawn { copy expected }; do task::spawn || { let actual = f.get(); assert!(actual == expected); diff --git a/src/libstd/par.rs b/src/libstd/par.rs index cfedbb66caa..cf0eba9d30c 100644 --- a/src/libstd/par.rs +++ b/src/libstd/par.rs @@ -73,10 +73,10 @@ fn map_slices( info!("num_tasks: %?", (num_tasks, futures.len())); assert!((num_tasks == futures.len())); - let r = do futures.map() |ys| { + let r = do vec::map_consume(futures) |ys| { + let mut ys = ys; ys.get() }; - assert!((r.len() == futures.len())); r } }