Skip to content

in impl A for B, report trait/impl sig inconsistency before method/body inconsistency #15657

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

Closed
pnkfelix opened this issue Jul 14, 2014 · 0 comments · Fixed by #17215
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints

Comments

@pnkfelix
Copy link
Member

How often have you seen a message like:

error: mismatched types: expected () but found int (expected () but found int)

when writing an impl, and responded (with some head-scratching): "Nonsense! This trait's method definitely returns an int, not unit!" ... only to then read further down the compiler output and see:

error: method foo has an incompatible type for trait: expected int but found ()

I know it happens to me a lot.


Sample code to illustrate this:

#![crate_type="lib"]
trait A {
    fn foo(self) -> int;
}
struct B;
impl A for B {
    fn foo(self) {
        if 0i == 1i {
            return 3i;
        }
        *4i; // (insert an arbitary number of ill-typed expressions here.)
        3i
    }
}

which yields the transcript:

% DYLD_LIBRARY_PATH=./objdir-dbgopt/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib ./objdir-dbgopt/x86_64-apple-darwin/stage2/bin/rustc /tmp/g.rs 
/tmp/g.rs:9:20: 9:22 error: mismatched types: expected `()` but found `int` (expected () but found int)
/tmp/g.rs:9             return 3i;
                               ^~
/tmp/g.rs:11:9: 11:12 error: type `int` cannot be dereferenced
/tmp/g.rs:11         *4i; // (insert an arbitary number of ill-typed expressions here.)
                     ^~~
/tmp/g.rs:12:9: 12:11 error: mismatched types: expected `()` but found `int` (expected () but found int)
/tmp/g.rs:12         3i
                     ^~
/tmp/g.rs:7:5: 13:6 error: method `foo` has an incompatible type for trait: expected int but found ()
/tmp/g.rs:7     fn foo(self) {
/tmp/g.rs:8         if 0i == 1i {
/tmp/g.rs:9             return 3i;
/tmp/g.rs:10         }
/tmp/g.rs:11         *4i; // (insert an arbitary number of ill-typed expressions here.)
/tmp/g.rs:12         3i
             ...
error: aborting due to 4 previous errors

As noted in the program comment, there can be an arbitrary number of type errors before one sees the report of the signature mismatch between the trait and its impl.


In principle there is no "100% right" ordering here between these messages, because there are scenarios where the right response to this message is to revise the trait definition (so that its method signature is changed to match the one in the impl you are writing).

But I believe that in most cases, the trait definition has been worked out long ahead of time (and is often fixed/unchangeable), while the impl itself is under active development, and therefore it would be more helpful to the user if in the final error report, the mismatches between the trait and its impl(s) are reported before the error when attempting to type-check the body of the impl itself.


(I am not super familiar with the code that drives these checks; it could be that fixing this is as simple as reordering a few statements.)

@pnkfelix pnkfelix added I-papercut and removed A-ARM labels Jul 14, 2014
bors added a commit that referenced this issue Sep 22, 2014
This updates the `unused` lint group to include more lints, updates the `non_snake_case` lint to give better suggestions, adds a note explaining why a lifetime cannot be elided, and tweaks various error messages. This also updates the `non_uppercase_statics` lint to be warn-by-default to match the other naming lints. For statics, this lint is particularly useful, because a non-uppercase static can easily collide with a pattern binding, resulting in very confusing errors.

Closes #15914.
Closes #15657.
Closes #17337.
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

Successfully merging a pull request may close this issue.

1 participant