Skip to content

Instantly share code, notes, and snippets.

@Sgeo
Created September 17, 2015 05:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sgeo/393f49417fdf63d4bbed to your computer and use it in GitHub Desktop.
Save Sgeo/393f49417fdf63d4bbed to your computer and use it in GitHub Desktop.
split_mut.rs. This is almost certainly a bad idea
#![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