ICE: "aliasability violation with closure" in Boxed FnMut

088126b
Opened by Alex at 2015-07-08 21:09:59

The specific error occurs in this commit on my bugfix fork of conrod.

An FnMut is created, boxed, and passed to a function that takes a Box<FnMut(bool) + 'a>. The closure modifies its environment:

conrod/examples/all_widgets.rs:318:36: 318:97 error: internal compiler error: aliasability violation with closure
conrod/examples/all_widgets.rs:318                 .callback(Box::new(|&mut: new_val: bool| {demo.bool_matrix[col][row] = new_val;}))
                                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1. @alexchandel could you reduce this to a self-contained test case?

    Tamir Duberstein at 2015-04-21 23:13:54

  2. No idea, it occurred deep in the conrod example, which has been extensively refactored since then. If you're capable of Boxing a non-moving FnMut that modifies its environment, and passing it to a function that takes a Box, at least 5 times in one function, then it may have been fixed in rustc since then.

    Alex at 2015-04-29 15:19:14

  3. Something like this?

    fn invoke_fn<F>(f: &mut Box<&mut F>) where F: FnMut() {
      (*f)()
    }
    
    fn main() {
      let mut option = None;
      let mut fn_mut = || {
        option = Some(7)
      };
      let mut boxed_fn = Box::new(&mut fn_mut);
    
      invoke_fn(&mut boxed_fn);
      invoke_fn(&mut boxed_fn);
    }
    

    This compiles without error.

    Tamir Duberstein at 2015-04-29 19:16:41

  4. Alternatively:

    fn attach_fn(opt_fn: &mut Box<FnMut()>) {
      let mut option = None;
      *opt_fn = Box::new(|| { option = Some(7) });
    }
    
    fn main() {
      let mut optional_fn = Box::new(|| {});
      attach_fn(&mut optional_fn);
    }
    

    Attempts to leak an environment-mutating closure out of its closure, and fails without ICE:

    $ rustc main.rs
    main.rs:8:13: 8:29 error: mismatched types:
     expected `&mut Box<core::ops::FnMut()>`,
        found `&mut Box<[closure main.rs:7:34: 7:39]>`
    (expected trait core::ops::FnMut,
        found closure) [E0308]
    main.rs:8   attach_fn(&mut optional_fn);
                          ^~~~~~~~~~~~~~~~
    error: aborting due to previous error
    

    I think this issue should be closed; it's unlikely to yield anything actionable. @steveklabnik?

    Tamir Duberstein at 2015-04-29 19:25:11

  5. Seems like a duplicate of #21390, and unlikely to be reproduced. Closing.

    Ariel Ben-Yehuda at 2015-07-08 21:09:59