Skip to content

Point at return type always when type mismatch against it - #43484

Merged
bors merged 3 commits into
rust-lang:masterfrom
estebank:point-to-return
Aug 9, 2017
Merged

Point at return type always when type mismatch against it#43484
bors merged 3 commits into
rust-lang:masterfrom
estebank:point-to-return

Conversation

@estebank

Copy link
Copy Markdown
Contributor

Before this, the diagnostic errors would only point at the return type
when changing it would be a possible solution to a type error. Add a
label to the return type without a suggestion to change in order to make
the source of the expected type obvious.

Follow up to #42850, fixes#25133, fixes#41897.

@rust-highfive

Copy link
Copy Markdown
Contributor

r? @arielb1

(rust_highfive has picked a reviewer for you, use r? to override)

Before this, the diagnostic errors would only point at the return type
when changing it would be a possible solution to a type error. Add a
label to the return type without a suggestion to change in order to make
the source of the expected type obvious.
Follow up to rust-lang#42850, fixesrust-lang#25133, fixesrust-lang#41897.
@estebank

Copy link
Copy Markdown
ContributorAuthor

r? @Mark-Simulacrum as this PR was prompted by this comment.

@Mark-SimulacrumMark-Simulacrum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very happy to see this, thanks for working on it!

16 | pub fn get_enum_struct_variant() -> () {
| -- expected `()` because of return type
17 | Enum::EnumStructVariant { x: 1, y: 2, z: 3 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `a::Enum`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, it looks like in the new note we put the empty tuple in backticks, but don't in the old text. This seems odd; any chance it's an easy fix?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted to the original output at @arielb1's request.

--> $DIR/equality.rs:25:5
|
21 | fn two(x: bool) -> impl Foo {
| -------- expected `_` because of return type

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This note seems odd; presumably we expected i32? I'm not sure, but that seems to be the case here...

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed all suggestions involving impl Trait.

@alexcrichtonalexcrichton added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jul 27, 2017
@aidanhs

Copy link
Copy Markdown
Contributor

@estebank have you had a chance to have a look at the review comments yet? Just want to make sure this doesn't get lost!

@Mark-Simulacrum

Copy link
Copy Markdown
Member

Ah, this should also be r? @arielb1 or someone else, I'm not sufficiently familiar with these compiler internals.

@estebank

Copy link
Copy Markdown
ContributorAuthor

I am worried about that the current approach isn't 100% accurate. Although this will point out the cause of the expected type most of the time, src/test/ui/impl-trait/equality.stderr shows a case where where type inference caused the expected type to be caused not by the fn's return type, but by the type inference's interaction with if branches of different types. I've come across other examples, but I'm failing to find them now.

I'm hesitant to merge this if it will ever be misleading, but making it work 100% of the time would mean start keeping track of the traceback for all inferred types, something that I've been thinking about doing (but has the potential to make the compiler use a bit more memory).

Comment threadsrc/librustc/hir/map/mod.rs Outdated
NodeExpr(ref expr) => {
match expr.node {
ExprWhile(..) | ExprLoop(..) => true,
ExprWhile(..) | ExprLoop(..) | ExprIf(..) => true,

@arielb1arielb1Aug 7, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes the comment above wrong. Why?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted. I was considering removing all suggestions when involving if blocks due to the accuracy problem mentioned earlier. Given that now I only provide the suggestion if the types are the same, it can be safely reverted.

@arielb1

arielb1 commented Aug 8, 2017

Copy link
Copy Markdown
Contributor

@estebank

About the expected _ because of return type case: the only time the return type can contain inference variables is because we have an impl Trait with intra-function conflicts. I think we should just disable the error message if the return type contains impl Trait, because that indicates a conflict (there are also cases such as the return type being Option<impl Trait> where we could try to separate conflicts from non-conflicts, so we could instead try to check whether our type can be coerced into the return type if we wanted. I'm fine with it either way).

Comment threadsrc/librustc_typeck/check/mod.rs Outdated
let quote = if let TypeVariants::TyTuple(ref slice, _) = expected.sty {
if slice.len() == 0 { // don't use backtics for ()
""
} else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this?

In normal error messages:

fnmain(){let x:u32 = ();}

The backticks appear when mentioning the type name, but not when mentioning the type "constructor":


error[E0308]: mismatched types
--> src/main.rs:2:18
|
2 | let x: u32 = ();
| ^^ expected u32, found ()
|
= note: expected type `u32`
found type `()`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless you are going to change that error message too to not have backticks, I'll want to remove this check.

@arielb1

Copy link
Copy Markdown
Contributor

r=me with the backticks back.

@estebank

Copy link
Copy Markdown
ContributorAuthor

@bors r=arielb1

@bors

bors commented Aug 9, 2017

Copy link
Copy Markdown
Collaborator

📌 Commit 9bd62a4 has been approved by arielb1

@bors

bors commented Aug 9, 2017

Copy link
Copy Markdown
Collaborator

⌛ Testing commit 9bd62a4 with merge f142499...

bors added a commit that referenced this pull request Aug 9, 2017
Point at return type always when type mismatch against it
Before this, the diagnostic errors would only point at the return type
when changing it would be a possible solution to a type error. Add a
label to the return type without a suggestion to change in order to make
the source of the expected type obvious.
Follow up to #42850, fixes#25133, fixes#41897.
@bors

bors commented Aug 9, 2017

Copy link
Copy Markdown
Collaborator

☀️ Test successful - status-appveyor, status-travis
Approved by: arielb1
Pushing f142499 to master...

@bors
bors merged commit 9bd62a4 into rust-lang:masterAug 9, 2017
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-authorStatus: This is awaiting some action (such as code changes or more information) from the author.

Projects

None yet

7 participants

@estebank@rust-highfive@aidanhs@Mark-Simulacrum@arielb1@bors@alexcrichton