Borrow checker's strange error


#1
#![feature(unboxed_closures)]
#![feature(const_vec_new)]
#![feature(fn_traits)]

pub struct PackBytes;

static mut HANDLERS: Vec<Box<dyn FnMut<&mut PackBytes, Output=()>>> = Vec::new();

fn main() {
    
    let mut pack = PackBytes;
    unsafe { HANDLERS[0].as_mut().call_mut(&mut pack); }
}
error[E0597]: `pack` does not live long enough
  --> src/main.rs:15:35
   |
15 |     HANDLERS[0].as_mut().call_mut(&mut pack); }
   |     ------------------------------^^^^^^^^^-
   |     |                             |
   |     |                             borrowed value does not live long enough
   |     argument requires that `pack` is borrowed for `'static`
16 | }
   | - `pack` dropped here while still borrowed

Moreover

#![feature(unboxed_closures)]
#![feature(const_vec_new)]
#![feature(fn_traits)]
pub struct PackBytes;



static mut HANDLERS: Vec<Box<dyn for<'a> FnMut<&'a mut PackBytes, Output=()>>> = Vec::new();

fn main() {
    
    let mut pack = PackBytes;
    unsafe { HANDLERS[0].as_mut().call_mut(&mut pack); }
}
error: internal compiler error: src/librustc_codegen_llvm/abi.rs:433: argument to function with "rust-call" ABI is not a tuple

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:590:9
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: aborting due to previous error


note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.33.0-nightly (b92552d55 2019-01-06) running on x86_64-unknown-linux-gnu

note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type bin

note: some of the compiler flags provided by cargo are hidden


#2

Congratulations, you discovered an ICE :slight_smile: (Issue https://github.com/rust-lang/rust/issues/57404)

About the error you got, why is it so unexpected? HANDLERS has a static lifetime, while pack only has a lifetime of main. You are doing very scary things there!


#3

Thank you, it’s a great honour.

But this one works just fine.

fn test(pack:&mut PackBytes){}

fn main() {
    let mut pack = PackBytes;
    test(&mut pack);
}

test - has a static lifetime, while pack still has a lifetime of the main
so am I expected…that this is kind of HRTB problem.

You are doing very scary things there!

no, I do not. This is a stripped sample. All this stuff are working in a single dispatcher thread.


#4

this works

#![feature(const_vec_new)]
pub struct PackBytes;



static mut HANDLERS: Vec<Box<dyn for<'a> FnMut(&'a mut PackBytes) -> ()>> = Vec::new();

fn main() {
    
    let mut pack = PackBytes;
    unsafe { (HANDLERS[0].as_mut())(&mut pack); }
}