Skip to content

Commit edd9bad

Browse files
committed
std::comm: use Unsafe to avoid U.B. & -> &mut transmutes.
1 parent 781ac3e commit edd9bad

File tree

1 file changed

+49
-34
lines changed

1 file changed

+49
-34
lines changed

src/libstd/comm/mod.rs

+49-34
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,6 @@
271271
// And now that you've seen all the races that I found and attempted to fix,
272272
// here's the code for you to find some more!
273273

274-
use cast;
275274
use cell::Cell;
276275
use clone::Clone;
277276
use iter::Iterator;
@@ -284,6 +283,7 @@ use result::{Ok, Err, Result};
284283
use rt::local::Local;
285284
use rt::task::{Task, BlockedTask};
286285
use sync::arc::UnsafeArc;
286+
use ty::Unsafe;
287287

288288
pub use comm::select::{Select, Handle};
289289

@@ -318,19 +318,14 @@ mod stream;
318318
mod shared;
319319
mod sync;
320320

321-
// FIXME #13933: Remove/justify all `&T` to `&mut T` transmutes
322-
unsafe fn transmute_mut<'a,T>(x: &'a T) -> &'a mut T {
323-
cast::transmute::<&_, &mut _>(x)
324-
}
325-
326321
// Use a power of 2 to allow LLVM to optimize to something that's not a
327322
// division, this is hit pretty regularly.
328323
static RESCHED_FREQ: int = 256;
329324

330325
/// The receiving-half of Rust's channel type. This half can only be owned by
331326
/// one task
332327
pub struct Receiver<T> {
333-
inner: Flavor<T>,
328+
inner: Unsafe<Flavor<T>>,
334329
receives: Cell<uint>,
335330
// can't share in an arc
336331
marker: marker::NoShare,
@@ -346,7 +341,7 @@ pub struct Messages<'a, T> {
346341
/// The sending-half of Rust's asynchronous channel type. This half can only be
347342
/// owned by one task, but it can be cloned to send to other tasks.
348343
pub struct Sender<T> {
349-
inner: Flavor<T>,
344+
inner: Unsafe<Flavor<T>>,
350345
sends: Cell<uint>,
351346
// can't share in an arc
352347
marker: marker::NoShare,
@@ -395,6 +390,27 @@ enum Flavor<T> {
395390
Sync(UnsafeArc<sync::Packet<T>>),
396391
}
397392

393+
#[doc(hidden)]
394+
trait UnsafeFlavor<T> {
395+
fn inner_unsafe<'a>(&'a self) -> &'a Unsafe<Flavor<T>>;
396+
unsafe fn mut_inner<'a>(&'a self) -> &'a mut Flavor<T> {
397+
&mut *self.inner_unsafe().get()
398+
}
399+
unsafe fn inner<'a>(&'a self) -> &'a Flavor<T> {
400+
&*self.inner_unsafe().get()
401+
}
402+
}
403+
impl<T> UnsafeFlavor<T> for Sender<T> {
404+
fn inner_unsafe<'a>(&'a self) -> &'a Unsafe<Flavor<T>> {
405+
&self.inner
406+
}
407+
}
408+
impl<T> UnsafeFlavor<T> for Receiver<T> {
409+
fn inner_unsafe<'a>(&'a self) -> &'a Unsafe<Flavor<T>> {
410+
&self.inner
411+
}
412+
}
413+
398414
/// Creates a new asynchronous channel, returning the sender/receiver halves.
399415
///
400416
/// All data sent on the sender will become available on the receiver, and no
@@ -463,7 +479,7 @@ pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
463479

464480
impl<T: Send> Sender<T> {
465481
fn new(inner: Flavor<T>) -> Sender<T> {
466-
Sender { inner: inner, sends: Cell::new(0), marker: marker::NoShare }
482+
Sender { inner: Unsafe::new(inner), sends: Cell::new(0), marker: marker::NoShare }
467483
}
468484

469485
/// Sends a value along this channel to be received by the corresponding
@@ -537,7 +553,7 @@ impl<T: Send> Sender<T> {
537553
task.map(|t| t.maybe_yield());
538554
}
539555

540-
let (new_inner, ret) = match self.inner {
556+
let (new_inner, ret) = match *unsafe { self.inner() } {
541557
Oneshot(ref p) => {
542558
let p = p.get();
543559
unsafe {
@@ -569,16 +585,16 @@ impl<T: Send> Sender<T> {
569585
};
570586

571587
unsafe {
572-
let mut tmp = Sender::new(Stream(new_inner));
573-
mem::swap(&mut transmute_mut(self).inner, &mut tmp.inner);
588+
let tmp = Sender::new(Stream(new_inner));
589+
mem::swap(self.mut_inner(), tmp.mut_inner());
574590
}
575591
return ret;
576592
}
577593
}
578594

579595
impl<T: Send> Clone for Sender<T> {
580596
fn clone(&self) -> Sender<T> {
581-
let (packet, sleeper) = match self.inner {
597+
let (packet, sleeper) = match *unsafe { self.inner() } {
582598
Oneshot(ref p) => {
583599
let (a, b) = UnsafeArc::new2(shared::Packet::new());
584600
match unsafe { (*p.get()).upgrade(Receiver::new(Shared(a))) } {
@@ -603,8 +619,8 @@ impl<T: Send> Clone for Sender<T> {
603619
unsafe {
604620
(*packet.get()).inherit_blocker(sleeper);
605621

606-
let mut tmp = Sender::new(Shared(packet.clone()));
607-
mem::swap(&mut transmute_mut(self).inner, &mut tmp.inner);
622+
let tmp = Sender::new(Shared(packet.clone()));
623+
mem::swap(self.mut_inner(), tmp.mut_inner());
608624
}
609625
Sender::new(Shared(packet))
610626
}
@@ -613,7 +629,7 @@ impl<T: Send> Clone for Sender<T> {
613629
#[unsafe_destructor]
614630
impl<T: Send> Drop for Sender<T> {
615631
fn drop(&mut self) {
616-
match self.inner {
632+
match *unsafe { self.mut_inner() } {
617633
Oneshot(ref mut p) => unsafe { (*p.get()).drop_chan(); },
618634
Stream(ref mut p) => unsafe { (*p.get()).drop_chan(); },
619635
Shared(ref mut p) => unsafe { (*p.get()).drop_chan(); },
@@ -710,7 +726,7 @@ impl<T: Send> Drop for SyncSender<T> {
710726

711727
impl<T: Send> Receiver<T> {
712728
fn new(inner: Flavor<T>) -> Receiver<T> {
713-
Receiver { inner: inner, receives: Cell::new(0), marker: marker::NoShare }
729+
Receiver { inner: Unsafe::new(inner), receives: Cell::new(0), marker: marker::NoShare }
714730
}
715731

716732
/// Blocks waiting for a value on this receiver
@@ -762,7 +778,7 @@ impl<T: Send> Receiver<T> {
762778
}
763779

764780
loop {
765-
let mut new_port = match self.inner {
781+
let new_port = match *unsafe { self.inner() } {
766782
Oneshot(ref p) => {
767783
match unsafe { (*p.get()).try_recv() } {
768784
Ok(t) => return Ok(t),
@@ -795,8 +811,8 @@ impl<T: Send> Receiver<T> {
795811
}
796812
};
797813
unsafe {
798-
mem::swap(&mut transmute_mut(self).inner,
799-
&mut new_port.inner);
814+
mem::swap(self.mut_inner(),
815+
new_port.mut_inner());
800816
}
801817
}
802818
}
@@ -815,7 +831,7 @@ impl<T: Send> Receiver<T> {
815831
/// the value found on the receiver is returned.
816832
pub fn recv_opt(&self) -> Result<T, ()> {
817833
loop {
818-
let mut new_port = match self.inner {
834+
let new_port = match *unsafe { self.inner() } {
819835
Oneshot(ref p) => {
820836
match unsafe { (*p.get()).recv() } {
821837
Ok(t) => return Ok(t),
@@ -842,8 +858,7 @@ impl<T: Send> Receiver<T> {
842858
Sync(ref p) => return unsafe { (*p.get()).recv() }
843859
};
844860
unsafe {
845-
mem::swap(&mut transmute_mut(self).inner,
846-
&mut new_port.inner);
861+
mem::swap(self.mut_inner(), new_port.mut_inner());
847862
}
848863
}
849864
}
@@ -858,7 +873,7 @@ impl<T: Send> Receiver<T> {
858873
impl<T: Send> select::Packet for Receiver<T> {
859874
fn can_recv(&self) -> bool {
860875
loop {
861-
let mut new_port = match self.inner {
876+
let new_port = match *unsafe { self.inner() } {
862877
Oneshot(ref p) => {
863878
match unsafe { (*p.get()).can_recv() } {
864879
Ok(ret) => return ret,
@@ -879,15 +894,15 @@ impl<T: Send> select::Packet for Receiver<T> {
879894
}
880895
};
881896
unsafe {
882-
mem::swap(&mut transmute_mut(self).inner,
883-
&mut new_port.inner);
897+
mem::swap(self.mut_inner(),
898+
new_port.mut_inner());
884899
}
885900
}
886901
}
887902

888903
fn start_selection(&self, mut task: BlockedTask) -> Result<(), BlockedTask>{
889904
loop {
890-
let (t, mut new_port) = match self.inner {
905+
let (t, new_port) = match *unsafe { self.inner() } {
891906
Oneshot(ref p) => {
892907
match unsafe { (*p.get()).start_selection(task) } {
893908
oneshot::SelSuccess => return Ok(()),
@@ -911,16 +926,16 @@ impl<T: Send> select::Packet for Receiver<T> {
911926
};
912927
task = t;
913928
unsafe {
914-
mem::swap(&mut transmute_mut(self).inner,
915-
&mut new_port.inner);
929+
mem::swap(self.mut_inner(),
930+
new_port.mut_inner());
916931
}
917932
}
918933
}
919934

920935
fn abort_selection(&self) -> bool {
921936
let mut was_upgrade = false;
922937
loop {
923-
let result = match self.inner {
938+
let result = match *unsafe { self.inner() } {
924939
Oneshot(ref p) => unsafe { (*p.get()).abort_selection() },
925940
Stream(ref p) => unsafe {
926941
(*p.get()).abort_selection(was_upgrade)
@@ -932,11 +947,11 @@ impl<T: Send> select::Packet for Receiver<T> {
932947
(*p.get()).abort_selection()
933948
},
934949
};
935-
let mut new_port = match result { Ok(b) => return b, Err(p) => p };
950+
let new_port = match result { Ok(b) => return b, Err(p) => p };
936951
was_upgrade = true;
937952
unsafe {
938-
mem::swap(&mut transmute_mut(self).inner,
939-
&mut new_port.inner);
953+
mem::swap(self.mut_inner(),
954+
new_port.mut_inner());
940955
}
941956
}
942957
}
@@ -949,7 +964,7 @@ impl<'a, T: Send> Iterator<T> for Messages<'a, T> {
949964
#[unsafe_destructor]
950965
impl<T: Send> Drop for Receiver<T> {
951966
fn drop(&mut self) {
952-
match self.inner {
967+
match *unsafe { self.mut_inner() } {
953968
Oneshot(ref mut p) => unsafe { (*p.get()).drop_port(); },
954969
Stream(ref mut p) => unsafe { (*p.get()).drop_port(); },
955970
Shared(ref mut p) => unsafe { (*p.get()).drop_port(); },

0 commit comments

Comments
 (0)