Skip to content

Cannot call a Vec<Box<Fn()>> without explicit dereferencing #36786

Closed
@shepmaster

Description

This code works:

fn main() {
    let func: Box<Fn()> = Box::new(|| println!("called"));
    func();
}

As does placing it in an array:

fn main() {
    let func: [Box<Fn()>; 1] = [Box::new(|| println!("called"))];
    func[0]();
}

However, using a Vec fails:

fn main() {
    let func: Vec<Box<Fn()>> = vec![Box::new(|| println!("called"))];
    func[0](); // error: expected function, found `Box<std::ops::Fn()>`
}

Instead, it must be explicitly dereferenced:

fn main() {
    let func: Vec<Box<Fn()>> = vec![Box::new(|| println!("called"))];
    (*func[0])();
}

It's even more annoying for Vec<Box<FnMut()>>:

fn main() {
    let mut func: Vec<Box<FnMut()>> = vec![Box::new(|| println!("called"))];
    // func[0](); // expected function, found `Box<std::ops::FnMut()>`
    // (*func[0])(); // cannot borrow immutable `Box` content as mutable
    (*&mut func[0])();
}

Activity

Aatch

Aatch commented on Sep 29, 2016

@Aatch
Contributor

The fact that this works for arrays, but not Vec suggests that it's probably related to associated types. It's possible that wherever the coercion from &Box<Fn()> to &Fn() is done sees &<Vec<Box<Fn()>> as Index<usize>>::Output instead.

added a commit that references this issue on Sep 29, 2016
ec2e051
added a commit that references this issue on Sep 30, 2016

Auto merge of #36822 - Aatch:resolve-callee-expr, r=luqmana

1d64acd
added a commit that references this issue on Oct 1, 2016
9f433af
jonhoo

jonhoo commented on Mar 7, 2017

@jonhoo
Contributor

This doesn't seem to be fully resolved:

use std::sync::Mutex;

pub struct Foo(Mutex<Box<FnMut()>>);

impl Foo {
    pub fn foo(&self) {
        // self.0.lock().unwrap()(); // cannot borrow immutable `Box` content as mutable
        // (*self.0.lock().unwrap())(); // cannot borrow immutable `Box` content as mutable
        // (&mut self.0.lock().unwrap())(); // cannot borrow immutable `Box` content as mutable
        (&mut *self.0.lock().unwrap())();
    }
}

fn main() {
    Foo(Mutex::new(Box::new(|| println!("called")))).foo()
}
shepmaster

shepmaster commented on Nov 12, 2017

@shepmaster
MemberAuthor

@jonhoo That may be #26186 instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Cannot call a Vec<Box<Fn()>> without explicit dereferencing · Issue #36786 · rust-lang/rust