Skip to content
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

Expected type for closure arguments not inferred through two nested func calls #16473

Open
nikomatsakis opened this issue Aug 13, 2014 · 5 comments
Labels
A-closures Area: Closures (`|…| { … }`) A-inference Area: Type inference C-bug Category: This is a bug.

Comments

@nikomatsakis
Copy link
Contributor

Test case:

struct Foo;

struct FooClosure<'a>(Option<|&mut Foo|:'a>);

fn foo(closure: |&mut Foo, &int|:'static, inputs: &[int]) {
    for input in inputs.iter() {
        FooClosure(Some(|f| closure(f, input)));
    }
}

fn main() {}

This yields an error:

/home/nmatsakis/tmp/foo.rs:7:20: 7:47 error: mismatched types: expected `core::option::Option<|&mut Foo|>` but found `core::option::Option<|&mut Foo|>` (expected concrete lifetime, but found bound lifetime parameter )                                                                                                                  

which occurs because we did not propagate the expected type and thus instantiated the type of the closure parameter with a fresh variable, rather than using a bound region. Another solution to this issue would be finding a better way to decide when we can generalize lifetimes in closure parameters, rather than relying on the closure type.

There is a workaround: just manually annotate the parameter type.

@alvaro-cuesta
Copy link

Found a similar bug, but wanted to check since I'm not sure if it's a simplified version of this issue or I should open a new one.

Test case (playpen):

fn process_123(processor: |&[u8]| -> Vec<u8>) -> Vec<u8> {
    processor(&[1, 2, 3])
}

fn main() {
    let make_vec = |input/*: &_*/| {  // UNCOMMENT THIS TO FIX
        let mut vector = Vec::new();
        vector.push_all(input);
        vector
    };

    assert_eq!(process_123(make_vec), vec![1, 2, 3]);
}

Yields error:

mismatched types: expected `|&[u8]| -> collections::vec::Vec<u8>`, found `|&[_]| -> collections::vec::Vec<_>` (expected concrete lifetime, found bound lifetime parameter )

As you can see, explicitly typing the closure param as &_ fixes the issue. My intuition is similar to yours: there's a problem when propagating the expected type.

@steveklabnik steveklabnik added the A-closures Area: Closures (`|…| { … }`) label Jan 27, 2015
@seanmonstar
Copy link
Contributor

Assuming this is what is causing this playpen to fail: http://is.gd/E7sskd

This makes the easy case for a hyper Server fail, which would be a major bummer for those trying hyper at 1.0.0:

Server::http(|req, res| {

}).listen(8080);

@steveklabnik
Copy link
Member

Triage: @seanmonstar s playpen still fails today.

@Mark-Simulacrum Mark-Simulacrum added the A-inference Area: Type inference label May 16, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 21, 2017
@steveklabnik
Copy link
Member

Triage: no change

1 similar comment
@Spoonbender
Copy link

Triage: no change

bors added a commit to rust-lang-ci/rust that referenced this issue Mar 17, 2024
…b, r=Veykril

Stop eagerly resolving inlay hint text edits for VSCode

Send less json over the wire.
After microsoft/vscode#193124 was fixed, this change is not needed anymore.

VSCode 1.86.0 now supports double click for unresolved hint data too.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: Closures (`|…| { … }`) A-inference Area: Type inference C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

6 participants