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

"Unable to infer enough type information" when spawning thread and looping. #20454

Closed
jfager opened this issue Jan 3, 2015 · 7 comments · Fixed by #21808
Closed

"Unable to infer enough type information" when spawning thread and looping. #20454

jfager opened this issue Jan 3, 2015 · 7 comments · Fixed by #21808
Labels
A-closures Area: closures (`|args| { .. }`) A-typesystem Area: The type system

Comments

@jfager
Copy link
Contributor

jfager commented Jan 3, 2015

use std::thread;

fn main() {
    thread::Thread::spawn(move || {
        loop { // Remove the loop and everything works fine.
            println!("hello");
        }
        // This gives you:
        //
        // type_inf.rs:4:5: 4:26 error: unable to infer enough type information about `_`; type annotations required
        // type_inf.rs:4     thread::Thread::spawn(move || {
        //                   ^~~~~~~~~~~~~~~~~~~~~
        // error: aborting due to previous error


        // Uncomment the `()` below, and the error changes to a warning:
        //
        // type_inf.rs:8:9: 9:6 warning: unreachable expression, #[warn(unreachable_code)] on by default
        // type_inf.rs:8         ()
        // type_inf.rs:9     }).detach();

        // ()
    }).detach();
}

$ rustc --version
rustc 0.13.0-nightly (39d7402 2015-01-01 15:51:08 +0000)

@jfager
Copy link
Contributor Author

jfager commented Jan 3, 2015

Replacing loop with while true spits out a warning to use loop instead but compiles and runs as expected.

@alexcrichton
Copy link
Member

This is largely because the spawn function has a type parameter T indicating the return value of the closure.

In the case of loop, the closure return value cannot be inferred (as the function never returns). In the case of while the closure return value is () because the compiler assumes all while loops eventually terminate.

To use loop, you can invoke spawn like so:

Thread::spawn(|| -> T {
    loop { /* ... */ }
});

Here the -> T is a manual ascription of what the return type should be, and it can be -> () to say that it's the "unit return value"

@ghost
Copy link

ghost commented Jan 3, 2015

Actually, for diverging type variables (which is what a loop without a break gets typeck'ed to) we normally fall back to (). However, that happens at the very end of type checking and so the fall back will not be used for dispatch resolution. Maybe we should do it earlier, then.

@viperscape
Copy link

Here's the same issue:

use std::thread::Thread;
use std::sync::mpsc::{channel};

fn main() {
    let (chs,chr) = channel();

    Thread::spawn(move || {
        chs.send(1u8); //must specifically annotate
    });
}

As seen here

It took me a bit to realize the issue was actually regarding the channel type, as I thought it was referring to the thread's move fn itself with the error:

error: unable to infer enough type information about `closure[<anon>:8:24: 10:6]`; type annotations required
<anon>:8     Thread::spawn(move || {
             ^~~~~~~~~~~~~

@sixohsix
Copy link

I'm stuck with the same-looking bug, but the loop is apparently not the cause:

    for i in range(0, 4) {
        let my_numbers = shared_numbers.clone();
        let my_frame_counter = shared_frame_counter.clone();
        Thread::spawn(move || -> () {
            loop {
                my_numbers[i] = (my_frame_counter.frame() / i as i32) % 240;
                t::delay(16);
            }
            return ();
        });
    }

When I comment-out the my_numbers[i] = line, I get no errors. When the line is there, I get the error.

error: unable to infer enough type information about `closure[/Users/XXX/projects/rust-test/src/main.rs:109:28: 115:10]`; type annotations required
/Users/XXX/projects/rust-test/src/main.rs:109         Thread::spawn(move || -> () {
                                                      ^~~~~~~~~~~~~
error: aborting due to previous error

Unfortunately I don't yet know enough to figure out what's wrong with that line. However, the error message is extremely confusing.

@sixohsix
Copy link

My mistake was trying to use mutable state across threads. Using AtomicUsize solved the problem. To be clear: the only issue is that the message "unable to infer enough type information" is confusing because it has nothing to do with the real problem. The loop statement without break caused no problems for me.

@kmcallister kmcallister added A-typesystem Area: The type system A-closures Area: closures (`|args| { .. }`) labels Jan 14, 2015
@starwing
Copy link

I have the same issue event with the program in "A 30-minute Introduction to Rust":

use std::thread::Thread;
use std::sync::{Arc,Mutex};

fn main() {
    let numbers = Arc::new(Mutex::new(vec![1, 2, 3]));

    for i in range(0, 3) {
        let number = numbers.clone();
        Thread::spawn(|&:| {
            let i = 5;
            let mut array = number.lock().unwrap();
            (*array)[i] += 1;
            println!("numbers[{}] is {}", i, (*array)[i]);
        });
    }
}

it has the same error:

noname\2015-01-26-1.rs|9 col 9| 9:22 error: unable to infer enough type information about `closure[noname\2015-01-26-1.rs:9:23: 14:10]`; type annotations required [E0282]
|| noname\2015-01-26-1.rs:9         Thread::spawn(|&:| {
||                                  ^~~~~~~~~~~~~
|| error: aborting due to previous error
|| rustc returned 101

jfager added a commit to jfager/rust that referenced this issue Feb 2, 2015
alexcrichton added a commit to alexcrichton/rust that referenced this issue Feb 2, 2015
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

Successfully merging a pull request may close this issue.

6 participants