Skip to content

closure type fails to be inferred properly for vec foldl method #4319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
thestinger opened this issue Dec 31, 2012 · 4 comments
Closed

closure type fails to be inferred properly for vec foldl method #4319

thestinger opened this issue Dec 31, 2012 · 4 comments
Labels
A-type-system Area: Type system

Comments

@thestinger
Copy link
Contributor

This snippet works:

fn combine_flags(flags: &[MagicFlag]) -> c_int {
   vec::foldl(0, flags, |a: c_int, b: &MagicFlag| a | (*b as c_int))
}

Changing to the following doesn't compile because it gets inferred as an @ closure:

fn combine_flags(flags: &[MagicFlag]) -> c_int {
    flags.foldl(0, |a: c_int, b: &MagicFlag| a | (*b as c_int))
}

Error:

magic.rs:62:15: 62:61 error: mismatched types: expected `&fn(&core::libc::types::os::arch::c95::c_int, &MagicFlag) -> core::libc::types::os::arch::c95::c_int` but found `&fn(core::libc::types::os::arch::c95::c_int, &MagicFlag) -> core::libc::types::os::arch::c95::c_int` (expected &-ptr but found core::libc::types::os::arch::c95::c_int)
magic.rs:62   flags.foldl(0, |a: c_int, b: &MagicFlag| a | (*b as c_int))
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
zsh: exit 101   rustc magic.rs --test -O

The full code is in this repo.

@huonw
Copy link
Member

huonw commented Dec 31, 2012

It looks like the problem is actually the first argument of the closure: it should be of type &c_int in the second example.

Confusingly, the foldl method (from iter) and the function in vec have subtly different types for the closure (the standalone function in iter has the same type as the method).

@nikomatsakis
Copy link
Contributor

Not critical for 0.6; removing milestone

@nikomatsakis
Copy link
Contributor

The vec function has the correct signature. The iter signature is weaker
(it does not pass the accumulator by value but rather by reference). This
is partly because, in the generic iter case, you cannot safely write the
vec signature. The compiler isn't smart enough to permit the moves (it fears
recursion). One option might be to pass in &mut, or else have iter::foldl use
a bit of unsafe code. But anyway this sounds like a separate issue.

@catamorphism
Copy link
Contributor

It doesn't look like there's a bug here. Reopen if I'm wrong.

RalfJung added a commit to RalfJung/rust that referenced this issue May 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system
Projects
None yet
Development

No branches or pull requests

4 participants