Created
September 17, 2015 05:01
-
-
Save Sgeo/393f49417fdf63d4bbed to your computer and use it in GitHub Desktop.
split_mut.rs. This is almost certainly a bad idea
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(dead_code)] | |
use std::fmt; | |
use std::error; | |
#[derive(Debug)] | |
enum SplitMutError { | |
AliasedMut | |
} | |
impl fmt::Display for SplitMutError { | |
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
use std::error::Error; | |
write!(f, "{}", self.description()) | |
} | |
} | |
impl error::Error for SplitMutError { | |
fn description(&self) -> &str { | |
match self { | |
&SplitMutError::AliasedMut => "Aliased mutability" | |
} | |
} | |
} | |
fn split_mut<'a, T, RA: 'static, RB: 'static, FA, FB>(t: &'a mut T, mut fa: FA, mut fb: FB) -> Result<(&'a mut RA, &'a mut RB), SplitMutError> | |
where FA: for<'any> FnMut(&'any mut T) -> &'any mut RA, | |
FB: for<'any> FnMut(&'any mut T) -> &'any mut RB { | |
let mut_a: *mut RA; | |
let mut_b: *mut RB; | |
{ | |
let reborrow = &mut *t; | |
mut_a = fa(reborrow) as *mut RA | |
} | |
{ | |
let reborrow = &mut *t; | |
mut_b = fb(reborrow) as *mut RB | |
} | |
if mut_a as usize == mut_b as usize { | |
return Err(SplitMutError::AliasedMut); | |
} | |
Ok((unsafe { &mut *mut_a }, unsafe { &mut *mut_b })) | |
} | |
fn main() { | |
let mut foo = ["a", "b"]; | |
{ | |
let (a, b) = split_mut(&mut foo, |o| &mut o[0], |o| &mut o[1]).unwrap(); | |
*a = "c"; | |
*b = "d"; | |
} | |
println!("{:?}", foo); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment