From 8919f32f8320847501182e517b26b9755fc97041 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 3 May 2013 16:05:18 -0700 Subject: [PATCH] Remove mutable fields from comm by using casts. Also mark the cast in cell. --- src/libcore/comm.rs | 91 +++++++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index 56c301cd1c7..072562233de 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -12,7 +12,7 @@ Message passing */ -use cast::transmute; +use cast::{transmute, transmute_mut}; use cast; use either::{Either, Left, Right}; use kinds::Owned; @@ -119,13 +119,15 @@ pub mod streamp { } /// An endpoint that can send many messages. +#[unsafe_mut_field(endp)] pub struct Chan { - mut endp: Option> + endp: Option> } /// An endpoint that can receive many messages. +#[unsafe_mut_field(endp)] pub struct Port { - mut endp: Option>, + endp: Option>, } /** Creates a `(Port, Chan)` pair. @@ -136,30 +138,39 @@ These allow sending or receiving an unlimited number of messages. pub fn stream() -> (Port, Chan) { let (c, s) = streamp::init(); - (Port { endp: Some(s) }, Chan { endp: Some(c) }) + (Port { + endp: Some(s) + }, Chan { + endp: Some(c) + }) } impl GenericChan for Chan { #[inline(always)] fn send(&self, x: T) { - let mut endp = None; - endp <-> self.endp; - self.endp = Some( - streamp::client::data(endp.unwrap(), x)) + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + *self_endp = Some(streamp::client::data(endp.unwrap(), x)) + } } } impl GenericSmartChan for Chan { #[inline(always)] fn try_send(&self, x: T) -> bool { - let mut endp = None; - endp <-> self.endp; - match streamp::client::try_data(endp.unwrap(), x) { - Some(next) => { - self.endp = Some(next); - true + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + match streamp::client::try_data(endp.unwrap(), x) { + Some(next) => { + *self_endp = Some(next); + true + } + None => false } - None => false } } } @@ -167,23 +178,29 @@ impl GenericSmartChan for Chan { impl GenericPort for Port { #[inline(always)] fn recv(&self) -> T { - let mut endp = None; - endp <-> self.endp; - let streamp::data(x, endp) = recv(endp.unwrap()); - self.endp = Some(endp); - x + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + let streamp::data(x, endp) = recv(endp.unwrap()); + *self_endp = Some(endp); + x + } } #[inline(always)] fn try_recv(&self) -> Option { - let mut endp = None; - endp <-> self.endp; - match try_recv(endp.unwrap()) { - Some(streamp::data(x, endp)) => { - self.endp = Some(endp); - Some(x) + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + match try_recv(endp.unwrap()) { + Some(streamp::data(x, endp)) => { + *self_endp = Some(endp); + Some(x) + } + None => None } - None => None } } } @@ -191,14 +208,17 @@ impl GenericPort for Port { impl Peekable for Port { #[inline(always)] fn peek(&self) -> bool { - let mut endp = None; - endp <-> self.endp; - let peek = match endp { - Some(ref mut endp) => peek(endp), - None => fail!(~"peeking empty stream") - }; - self.endp <-> endp; - peek + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + let peek = match endp { + Some(ref mut endp) => peek(endp), + None => fail!(~"peeking empty stream") + }; + *self_endp <-> endp; + peek + } } } @@ -219,7 +239,6 @@ pub struct PortSet { } pub impl PortSet { - fn new() -> PortSet { PortSet { ports: ~[]