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

Provide better error reporting for unimplemented traits #19950

Closed
flaper87 opened this issue Dec 17, 2014 · 4 comments
Closed

Provide better error reporting for unimplemented traits #19950

flaper87 opened this issue Dec 17, 2014 · 4 comments
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints

Comments

@flaper87
Copy link
Contributor

struct NoCopy;

enum Test {
    MyVariant(NoCopy)
}

impl Copy for Test {}

fn main() {}

Compiling the above code generates the following error:

phantom /tmp $ rustc test.rs
test.rs:7:1: 7:22 error: the trait `Copy` may not be implemented for this type; variant `MyVariant` does not implement `Copy`
test.rs:7 impl Copy for Test {}
          ^~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

The error mentions that MyVariant doesn't implement Copy without pointing to the right type in the constructor that is actually missing the implementation NoCopy.

@flaper87 flaper87 self-assigned this Dec 17, 2014
@flaper87 flaper87 added the A-diagnostics Area: Messages for errors, warnings, and lints label Dec 17, 2014
@mzabaluev
Copy link
Contributor

It can be much worse for closures:

use std::ptr;
use std::thread::Thread;

mod obscure {
    struct Obscure {
        ptr: *const ()
    }
}

struct A {
    inner: obscure::Obscure
}

impl A {
    fn new() -> A {
        A { inner: obscure::Obscure { ptr: ptr::null() } }
    }
}

fn main() {
    let me_bad = A::new();
    let me_ok = 0i32;
    Thread::spawn(|| {
        let _guess_where_it_is = (me_bad, me_ok);
    });
}

Fails compilation with:

<anon>:23:5: 23:18 error: the trait `core::marker::Send` is not implemented for the type `*const ()`
<anon>:23     Thread::spawn(|| {
              ^~~~~~~~~~~~~

@nham
Copy link
Contributor

nham commented May 13, 2015

Triage: The error message seems much better. This code:

struct NoCopy;

enum Test {
    MyVariant(NoCopy)
}

impl Copy for Test {}

fn main() {}

results in (on rustc 1.1.0-nightly (4b88e8f63 2015-05-11) (built 2015-05-12)):

iss_19950.rs:7:1: 7:22 error: the trait `Copy` may not be implemented for this type; variant `MyVariant` does not implement `Copy` [E0205]
iss_19950.rs:7 impl Copy for Test {}
               ^~~~~~~~~~~~~~~~~~~~~
iss_19950.rs:7:1: 7:22 error: the trait `core::clone::Clone` is not implemented for the type `Test` [E0277]
iss_19950.rs:7 impl Copy for Test {}
               ^~~~~~~~~~~~~~~~~~~~~
error: aborting due to 2 previous errors

However, there may still be room for improvement for @mzabaluev 's example. The updated code seems to be:

use std::ptr;
use std::thread;

mod obscure {
    struct Obscure {
        ptr: *const ()
    }
}

struct A {
    inner: obscure::Obscure
}

impl A {
    fn new() -> A {
        A { inner: obscure::Obscure { ptr: ptr::null() } }
    }
}

fn main() {
    let me_bad = A::new();
    let me_ok = 0i32;
    thread::spawn(|| {
        let _guess_where_it_is = (me_bad, me_ok);
    });
}

and the error message is now:

iss_19950_2.rs:23:5: 23:18 error: the trait `core::marker::Send` is not implemented for the type `*const ()` [E0277]
iss_19950_2.rs:23     thread::spawn(|| {
                      ^~~~~~~~~~~~~
iss_19950_2.rs:23:5: 23:18 note: `*const ()` cannot be sent between threads safely
iss_19950_2.rs:23     thread::spawn(|| {
                      ^~~~~~~~~~~~~
error: aborting due to previous error

@arielb1
Copy link
Contributor

arielb1 commented Sep 25, 2015

The closure example currently reports

<anon>:23:5: 23:18 error: the trait `core::marker::Send` is not implemented for the type `*const ()` [E0277]
<anon>:23     thread::spawn(|| {
              ^~~~~~~~~~~~~
<anon>:23:5: 23:18 help: see the detailed explanation for E0277
<anon>:23:5: 23:18 note: `*const ()` cannot be sent between threads safely
<anon>:23:5: 23:18 note: required because it appears within the type `obscure::Obscure`
<anon>:23:5: 23:18 note: required because it appears within the type `A`
<anon>:23:5: 23:18 note: required because it appears within the type `[closure@<anon>:23:19: 25:6 me_bad:A, me_ok:&i32]`
<anon>:23:5: 23:18 note: required by `std::thread::spawn`
error: aborting due to previous error

So I think this it is solved (we could improve this by adding the upvar name, but it seems clear enough).

Copy could note the field name, however.

@arielb1
Copy link
Contributor

arielb1 commented Jan 5, 2017

The Copy case is fixed by #38152 with a test.

@arielb1 arielb1 closed this as completed Jan 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints
Projects
None yet
Development

No branches or pull requests

4 participants