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

Type inference error: the type of this value must be known in this context #23012

Closed
carllerche opened this issue Mar 4, 2015 · 7 comments · Fixed by #101834
Closed

Type inference error: the type of this value must be known in this context #23012

carllerche opened this issue Mar 4, 2015 · 7 comments · Fixed by #101834
Labels
A-implied-bounds Area: Implied bounds / inferred outlives-bounds A-inference Area: Type inference C-bug Category: This is a bug. S-types-deferred Status: Identified as a valid potential future enhancement that is not currently being worked on T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@carllerche
Copy link
Member

Repro:

pub trait Receive<T: Send, E: Send> : FnOnce(Result<T, E>) + Send {
    fn receive(self, res: Result<T, E>);
}

impl<T: Send, E: Send, F: FnOnce(Result<T, E>) + Send> Receive<T, E> for F {
    fn receive(self, res: Result<T, E>) {
        self(res)
    }
}

pub trait Async<T, E> {
    fn receive<F: Receive<T, E>>(self, f: F);
}

impl<T, E> Async<T, E> for Result<T, E> {
    fn receive<F: Receive<T, E>>(self, f: F) {
        f(self)
    }
}

fn res() -> Result<u32, ()> {
    Ok(123)
}

pub fn main() {
    res().receive(|res| println!("{}", res.unwrap()))
}

Output:

$ rustc fn.rs
fn.rs:26:40: 26:52 error: the type of this value must be known in this context
fn.rs:26     res().receive(|res| println!("{}", res.unwrap()))
                                                ^~~~~~~~~~~~
note: in expansion of format_args!
<std macros>:2:43: 2:76 note: expansion site
<std macros>:1:1: 2:78 note: in expansion of println!
fn.rs:26:25: 26:54 note: expansion site
error: aborting due to previous error
@emberian
Copy link
Member

emberian commented Mar 4, 2015

cc @nikomatsakis

@nikomatsakis
Copy link
Contributor

What's causing this is that we currently inspect the obligations in scope for Fn(...) obligations, but in this case the obligation is Receive (which implies a Fn obligation as a supertrait). This is expected but unfortunate, yes. We could probably fix this particular case in a relatively straightforward way by trying to upcast each pending obligation to a Fn obligation.

@nikomatsakis
Copy link
Contributor

I imagine that atm this could be worked around by changing:

    fn receive<F: Receive<T, E>>(self, f: F)

to

    fn receive<F: Receive<T, E>+FnOnce(Result<T,E>)>(self, f: F)

@steveklabnik steveklabnik added the A-typesystem Area: The type system label Mar 4, 2015
@steveklabnik
Copy link
Member

Today, this gives a completely different error about T not implementing Send...

@Mark-Simulacrum
Copy link
Member

Updated code to not give the unrelated Send error (by removing Send bounds everywhere), still gives the type must be known error.

pub trait Receive<T, E>: FnOnce(Result<T, E>) {
    fn receive(self, res: Result<T, E>);
}

impl<T, E, F: FnOnce(Result<T, E>)> Receive<T, E> for F {
    fn receive(self, res: Result<T, E>) {
        self(res)
    }
}

pub trait Async<T, E> {
    fn receive<F: Receive<T, E>>(self, f: F);
}

impl<T, E> Async<T, E> for Result<T, E> {
    fn receive<F: Receive<T, E>>(self, f: F) {
        f(self)
    }
}

pub fn main() {
    Ok::<u32, ()>(123).receive(|res| res.unwrap())
}

@nikomatsakis
Copy link
Contributor

nikomatsakis commented May 2, 2017

This comes up for me fairly regularly. It would be really nice to fix it. (e.g., it came up recently in rayon-rs/rayon#318)

@Mark-Simulacrum Mark-Simulacrum added A-inference Area: Type inference and removed A-typesystem Area: The type system labels Jun 22, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@nikomatsakis nikomatsakis added E-needs-mentor T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 2, 2017
@jackh726 jackh726 added WG-traits Working group: Traits, https://internals.rust-lang.org/t/announcing-traits-working-group/6804 and removed WG-compiler-middle labels Jan 29, 2022
@nikomatsakis nikomatsakis added the A-implied-bounds Area: Implied bounds / inferred outlives-bounds label Jun 10, 2022
@jackh726 jackh726 added T-types Relevant to the types team, which will review and decide on the PR/issue. S-types-deferred Status: Identified as a valid potential future enhancement that is not currently being worked on and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-traits Working group: Traits, https://internals.rust-lang.org/t/announcing-traits-working-group/6804 labels Jun 10, 2022
@nikomatsakis
Copy link
Contributor

We discussed this in the types team 'backlog bonanza' meeting today.

Our conclusion was that this is a "nice to have" and that directly fixing this issue felt like a types team FCP, because it's a tweak to the inference rules.

TL;DR right now we say

  • If there is some trait obligation ?T: FnOnce(A...), then we take the args from A...

...but it seems reasonable to say

  • If there is some trait obligation that implies (through the "invariants", in a-mir-formality terms) ?T: FnOnce(A...), then we take the args from A...

...and that would fix this example (types team FCP would be required).

However, I believe that beyond this specific example, most people who wind up here are trying to do something a bit more sophisticated, such as having an argument that might be a closure but might not, or have extended varieties of closures (as described in this rayon change). It is possible that just making the above change would fix those problems, but it's likely that further changes would be required. Those scope feels like a lang-team initiative.

Still may be worth making this change just to screen out the easy cases, mind you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-implied-bounds Area: Implied bounds / inferred outlives-bounds A-inference Area: Type inference C-bug Category: This is a bug. S-types-deferred Status: Identified as a valid potential future enhancement that is not currently being worked on T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants