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

Inference should be able to determine closure argument types from usage #35714

Closed
Manishearth opened this issue Aug 16, 2016 · 8 comments
Closed
Labels
A-closures Area: closures (`|args| { .. }`) A-typesystem Area: The type system

Comments

@Manishearth
Copy link
Member

struct Bar;
impl Bar {
    fn frob(&self) {}
}

fn foo() {
    let closure = |bar| {
        bar.frob();
    };

    closure(Bar);
}

(playpen)

gives:

error: the type of this value must be known in this context
 --> <anon>:8:9
8 |>         bar.frob();
  |>         ^^^^^^^^^^

The typechecker should be able to figure out that the type is Bar, since that's what the closure is used with.

@nagisa mentioned that it might be that the closure is polymorphic over the argument, but that's not the case -- trying to feed it two types doesn't work (example) and it's clear that the closure type gets decided when it is fed a Bar.

@Manishearth Manishearth added the A-typesystem Area: The type system label Aug 16, 2016
@eddyb
Copy link
Member

eddyb commented Aug 16, 2016

The closure is type-checked first and no type has seen by then. Closures outside of call argument position are poorly supported and should be avoided where possible.

@bluss bluss added the A-closures Area: closures (`|args| { .. }`) label Oct 29, 2016
@shepmaster
Copy link
Member

shepmaster commented Apr 9, 2017

Similar:

#[derive(Debug)]
struct Foo<T>(T);

fn main() {
    let f = Foo(42);
    
    let cls = |foo| {
        // println!("{:?}", foo); // Works
        foo.0; // Does not work
    };
    
    cls(f);
}

What's strange about this to me is that the type of foo is inferred just fine. It's only when "descending" to the nested type that the inference fails.

@shepmaster
Copy link
Member

Closures outside of call argument position are poorly supported and should be avoided where possible.

@eddyb do you know if this is an inherent limitation, or is it just a "we haven't gotten around to fixing this yet" situation?

@eddyb
Copy link
Member

eddyb commented Apr 9, 2017

It's not something you "fix", it's something you rewrite your whole type-checker for, from scratch, sadly.
That said, @nikomatsakis has been thinking about this and may have plausible avenues of exploration.

The explanation for your example is that foo is always inferred, but only when calling cls, whereas foo.0 is type-checked before. And our type-checker is too eager to allow this to work (see above).

@shepmaster
Copy link
Member

rewrite your whole type-checker for, from scratch

Ah, so just a few hours of low-impact work, gotcha! 😸

Thank you for the detailed explanation of my case.

@nikomatsakis
Copy link
Contributor

I'm going to close this issue -- this is a known limitation of the current type-checker, but not one that we plan to imminently change, and I don't think having this issue open will help us track it in particular. Feel free to let me know if you disagree.

@shepmaster
Copy link
Member

@nikomatsakis sounds good.

Is there another place where these "bigger picture" issues are tracked? Maybe some kind of document of known limitations? I'd like to have a place to point people who stumble across the same problem. Keeping it in our heads is useful to us, but not others 😉

@nikomatsakis
Copy link
Contributor

I'm not aware of any such place. I'm not really sure what would be the best such place either... :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: closures (`|args| { .. }`) A-typesystem Area: The type system
Projects
None yet
Development

No branches or pull requests

5 participants