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

Add error explanation for E0070 #25552

Merged
merged 2 commits into from
May 21, 2015
Merged

Conversation

GuillaumeGomez
Copy link
Member

Part of #24407.

@rust-highfive
Copy link
Collaborator

r? @nrc

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

SOME_NOT_CONST = 14; // that's good !
let mut i : i32 = 1;

i = 3; // that's good !
Copy link
Contributor

Choose a reason for hiding this comment

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

This line seems redundant. Seems like the let mut i : i32 = 1; line would suffice for demonstrating a good assignment.

Edit: Now that I think about it, do we need more than one example of an assignment? I'd imagine the idea of assignment should be pretty familiar to even the newest of Rust programmers. The following code may be enough:

static mut SOME_NOT_CONST : i32 = 12;

fn main() {
    SOME_NOT_CONST = 14;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

I just wanted to give multiple example cases, I think it's always better. People could think that only const variables could be concerned by this error, I want to avoid that.

@Manishearth
Copy link
Member

cc @michaelsproul

@bors
Copy link
Contributor

bors commented May 18, 2015

☔ The latest upstream changes (presumably #25501) made this pull request unmergeable. Please resolve the merge conflicts.

@michaelsproul
Copy link
Contributor

@nham is as much leading the charge as me now 😄

(I've been a bit sick, and busy doing other things)

enum variant, one of the fields was not provided. Each field should be specified
exactly once.
enum variant, one of the fields was not provided. Each field should be
specified exactly once.
Copy link
Contributor

Choose a reason for hiding this comment

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

I suspect your text editor has done the wrapping here, but these lines of 80 chars are actually fine.

Copy link
Member Author

Choose a reason for hiding this comment

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

I didn't even see that. I must have failed my wrapping somewhere... Well, if it is needed, I can undo this. ^^

@GuillaumeGomez
Copy link
Member Author

@michaelsproul @nham @pnkfelix: Do you see anything else which would need to be improved/changed ?

@pnkfelix
Copy link
Member

I cannot tell from reading the diff how E0070 differs from E0067. That to me may be a hint that either we have redundant error codes or that something is missing from their explanatory text.

@GuillaumeGomez
Copy link
Member Author

E0067 is about "+=" while E0070 is about "=". That's the only difference. @nham told me to take a look at it to help me writing this one, which I did.

@pnkfelix
Copy link
Member

@GuillaumeGomez ah, I see now.

In that case, the main changes I would suggest are:

  • In E0067, it should say at the beginning "The left-hand side of a compound assignment expression ..."
    • (or "compound assignment operator", if you prefer. The important thing is that its not just a normal assignment operator.)
  • The "good" examples in E0067 and E0070 should both be revised.
    • The "Good" example in E0067 is not a compound assignment. It should use some example involving e.g. +=, the same way that the "bad" example uses a compound assignment.

    • It would be better if the "Good" example in E0070 also included cases that illustrate the other kinds of l-values like dereferences *x = ...; and field accesses x.foo = ...;

    • Finally, I would argue that all of the "Good" examples in both E0067 and E0070 should avoid using a let x = ... form as the example of a well-formed assignment expression.

      The use of a let-binding is very confusing, since the text here is about the left-hand side of an assignment operator. The rules for let-bindings are incomparable with the rules for assignments.

      And I mean they are incomparable in a formal sense: Neither one is a super-set of the other. Some examples of how the rules for binding versus assignment are incomparable:

      (x, y) = (1, 2); // you cannot do this (at least not today; there may be a postponed RFC asking for it)
      let (x, y) = (1, 2); // but you can do this
      
      let x.foo = 3; // you cannot do this (and almost certainly never will be able to)
      x.foo = 3; // but you can do this

@GuillaumeGomez
Copy link
Member Author

@pnkfelix: Wo thanks a lot ! I didn't write E0067 so I'll create a second commit (not PR) to add the changes you proposed.
You find the let very confusing ? It seems pretty accurate for me... Let's take your examples:

(x, y) = (1, 2); // you cannot do this (at least not today; there may be a postponed RFC asking for it)
// -> it seems logical since you have to declare it before
let (x, y) = (1, 2); // but you can do this
// -> which is done here

let x.foo = 3; // you cannot do this (and almost certainly never will be able to)
// -> you can't allocate just a sub element of a struct without allocating the struct
x.foo = 3; // but you can do this
// -> it's just assigning a value to a sub element of an allocated struct

So that's where I don't follow you. let seems quite simple to understand for me.

@pnkfelix
Copy link
Member

FYI: When I wrote:

(x, y) = (1, 2);

it was meant to be in the context of either

let mut x = ...; let mut y = ...;

or

let x; let y;

Anyway, we worked this out over IRC, but the summary is:

The rules for let LET_LHS = LET_RHS; are different from (incomparable with) the rules for ASSIGN_LHS = ASSIGN_RHS; and therefore, when discussing what is legal for ASSIGN_LHS, it is bogus to provide examples for LET_LHS.

@GuillaumeGomez
Copy link
Member Author

I'll remove the concerned examples and replace them by others.

@pnkfelix
Copy link
Member

I didn't write E0067 so I'll create a second commit (not PR) to add the changes you proposed.

If you feel like including the "fix" to E0067 in this PR, i'll probably approve it (i.e. no need to file an entirely separate PR). The improvements are sort of coupled, after all (since it is clarifying that one message is about assignments and the other is about compound assignments).

@GuillaumeGomez
Copy link
Member Author

Yes, since it's nearly the same error, it wouldn't make sense to create another PR just for a fix. Thanks for your help ! :-)

@GuillaumeGomez
Copy link
Member Author

@pnkfelix: I updated the examples. Does that seem good to you ?

The left-hand side of an assignment operator must be an lvalue expression. An
lvalue expression represents a memory location and includes item paths (ie,
namespaced variables), dereferences, indexing expressions, and field references.
The left-hand side of a compound assignment expression (or compound assignment
Copy link
Member

Choose a reason for hiding this comment

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

i didn't mean for you to write "expression (or operator)". Just pick one, please.

(Because I think its confusing in this text to have it be open ended...)

Copy link
Member Author

Choose a reason for hiding this comment

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

I couldn't decide... Well, I'll go for the first one then !

@pnkfelix
Copy link
Member

the examples look good to me. I'll be happy with the above nit addressed.

@GuillaumeGomez
Copy link
Member Author

@pnkfelix: Fixed !

@pnkfelix
Copy link
Member

@bors r+ db9b435 rollup

@bors
Copy link
Contributor

bors commented May 21, 2015

⌛ Testing commit db9b435 with merge 7bd3bbd...

bors added a commit that referenced this pull request May 21, 2015
@bors bors merged commit db9b435 into rust-lang:master May 21, 2015
@GuillaumeGomez GuillaumeGomez deleted the left-hand-error branch May 21, 2015 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants