RustVis Specs

All specs show result as intended when the variable target is selected.

Legend

available
borrowed
mutably borrowed
error

borrow1 (play/run) (link to this)

#[derive(Debug)]
struct Foo;

fn main() {
    let target = Foo;
    let b = ⌖
    println!("{:?}", b);
}

borrow2 (play/run) (link to this)

#[derive(Debug)]
struct Foo;

fn main() {
    let target = Foo;
    {
        let b = ⌖
        println!("{:?}", b);
    }
    // potentially more code
}

borrow3 (play/run) (link to this)

#[derive(Debug)]
struct Foo;

fn main() {
    let target = Foo;
    {
        let b = ⌖
        let c = ⌖
        println!("{:?} {:?}", b, c);
    }
    // potentially more code
}

closure1 (play/run) (link to this)

fn main() {
    let mut target = 5;
    let plus_target = |x: i32| x + target;
    let y = &mut target;
    // cannot borrow `target` as mutable because it is also borrowed as immutable
}

closure2 (play/run) (link to this)

struct Foo;

fn main() {
    let target = Foo;
    let get_target = move || target;
    let y = ⌖
    // use of moved value: `target`
}

does-not-live-long-enough-1 (play/run) (link to this)

struct Foo;

fn max<'a>(x: &'a Foo, y: &'a Foo) -> &'a Foo {
    x
}

fn main() {
    let a = Foo;
    let y: &Foo;
    {
        let target = Foo;
        y = max(&a, &target);
        // error: `b` does not live long enough
    }
    // potentially more code
}

generic1 (play/run) (link to this)

struct Foo<T> {
    value: Option<T>
}

struct Bar;

fn insert<T>(map: &mut Foo<T>, value: T) {}

fn main() {
    let mut map = Foo { value: None };
    {
        let target = Bar;
        let text = &target;

        insert(&mut map, text);
    }

    // potentially more code
}

lifetime1 (play/run) (link to this)

struct Foo;

struct Bar<'b> {
    f: Option<&'b i32>
}

impl <'c> Bar<'c> {
    fn restrict<'a>(&'a mut self, x: &'c Foo) {}
}

fn main() {
    let mut target = Foo;
    let mut b = Bar { f: None };
    b.restrict(&target);
    target = Foo;
    // cannot assign to `target` because it is borrowed
}

lifetime2 (play/run) (link to this)

struct Foo;

struct Bar<'b> {
    f: Option<&'b i32>
}

impl <'c> Bar<'c> {
    fn restrict<'a>(&'a mut self, x: &'c Foo) {}
}

fn borrow(x: &Foo) {}

fn main() {
    let mut target = Foo;
    let mut b = Bar { f: None };
    b.restrict(&mut target);
    borrow(&target);
    // cannot borrow `target` as immutable because it is also borrowed as mutable
}

lifetime3 (play/run) (link to this)

struct Foo;

struct Bar<'b> {
    f: Option<&'b i32>
}

impl <'c> Bar<'c> {
    fn restrict<'a>(&'a self, x: &'c Foo) {}
}

fn borrow(x: &Foo) {}

fn main() {
    let mut target = Foo;
    let mut b = Bar { f: None };
    b.restrict(&mut target);
    borrow(&target);
}

lifetime4 (play/run) (link to this)

struct Foo;

struct Bar<'b> {
    f: Option<&'b i32>
}

fn restrict<'a, 'b>(y: &'a mut Bar<'b>, x: &'b Foo) {}

fn borrow(x: &Foo) {}

fn main() {
    let mut target = Foo;
    let mut b = Bar { f: None };
    restrict(&mut b, &mut target);
    borrow(&mut target);
    // cannot borrow `target` as mutable more than once at a time
}

lifetime5 (play/run) (link to this)

struct Foo;

struct Bar<'b> {
    f: Option<&'b i32>
}

fn restrict<'a, 'b>(y: &'a Bar<'b>, x: &'b Foo) {}

fn borrow(x: &Foo) {}

fn main() {
    let mut target = Foo;
    let mut b = Bar { f: None };
    restrict(&mut b, &mut target);
    borrow(&mut target);
}

lifetime6 (play/run) (link to this)

struct Foo;

struct Bar<'b> {
    f: Option<&'b i32>
}

fn restrict<'a, 'b>(y: &'a mut Bar<'b>, x: &'b Foo) {}

fn borrow(x: &Foo) {}

fn main() {
    let mut target = Foo;
    {
        let mut b = Bar { f: None };
        restrict(&mut b, &mut target);
    }
    borrow(&mut target);
}

lifetime7 (play/run) (link to this)

struct Foo;

struct Bar<'b> {
    f: Option<&'b i32>
}

fn restrict<'b>(x: &'b Foo) -> Bar<'b> {
    unimplemented!()
}

fn borrow(x: &Foo) {}

fn main() {
    let mut target = Foo;
    let b = restrict(&mut target);
    borrow(&target);
    // cannot borrow `target` as immutable because it is also borrowed as mutable
}

lifetime8 (play/run) (link to this)

struct Foo;

struct Bar<'b> {
    f: Option<&'b i32>
}

fn restrict<'a, 'b>(x: &'a Foo) -> Bar<'b> {
    unimplemented!()
}

fn borrow(x: &Foo) {}

fn main() {
    let mut target = Foo;
    let b = restrict(&mut target);
    borrow(&target);
}

lifetime9 (play/run) (link to this)

struct Foo;

struct Bar<'b> {
    f: Option<&'b i32>
}

fn restrict<'a: 'b, 'b>(x: &'a Foo) -> Bar<'b> {
    unimplemented!()
}

fn borrow(x: &Foo) {}

fn main() {
    let mut target = Foo;
    let b = restrict(&mut target);
    borrow(&target);
    // cannot borrow `target` as immutable because it is also borrowed as mutable
}

move1 (play/run) (link to this)

#[derive(Debug)]
struct Foo;

fn main() {
    let target = Foo;
    let b = target; // move
    println!("{:?}", b);
}

move2 (play/run) (link to this)

#[derive(Debug, Copy, Clone)]
struct Foo;

fn main() {
    let target = Foo;
    let b = target; // copy
    //println!("{:?}", b);
}

move3 (play/run) (link to this)

struct Foo;

fn main() {
    let target = Foo;
    let b = &target;
    let c = target;
    // cannot move out of `target` because it is borrowed
}

nonlexical1-current (play/run) (link to this)

fn capitalize(x: &mut [char]) {}

fn main() {
    let mut target = vec!['a', 'b', 'c'];
    let slice = &mut target[..];
    capitalize(slice);
    target.push('d');
    target.push('e');
    target.push('f');
}

nonlexical1-proposed (play/run) (link to this)

fn capitalize(x: &mut [char]) {}

fn main() {
    let mut target = vec!['a', 'b', 'c'];
    let slice = &mut target[..];
    capitalize(slice);
    target.push('d');
    target.push('e');
    target.push('f');
}

nonlexical2-current (play/run) (link to this)

use std::collections::HashMap;

fn usage<T>(x: T) {}

fn main() {
    let mut target = HashMap::new();
    let key = String::from("foo");
    let value = {
        let map_ref1 = &mut target;
        match map_ref1.get_mut(&key) {
            Some(value) => value,
            None => {
                target.insert(key.clone(), 5);
                let map_ref2 = &mut target;
                map_ref2.get_mut(&key).unwrap()
            }
        }
    };
    usage(value);
    // potentially more code
}

nonlexical2-proposed (play/run) (link to this)

use std::collections::HashMap;

fn usage<T>(x: T) {}

fn main() {
    let mut target = HashMap::new();
    let key = String::from("foo");
    let value = {
        let map_ref1 = &mut target;
        match map_ref1.get_mut(&key) {
            Some(value) => value,
            None => {
                target.insert(key.clone(), 5);
                let map_ref2 = &mut target;
                map_ref2.get_mut(&key).unwrap()
            }
        }
    };
    usage(value);
    // potentially more code
}