Change:
When compiling the following code: I get the error: Compiled with:
I also just hit this today. An even simpler test case:
Reproduced with (both cases). Interestingly, rustc warns that X0 and X1 don't need to be mutable on the first case.
Similar ICE with structs:
The simplest case I think:
It's because assumes only one of will come but it met . So seems easy to fix, but what about tuples/structs? is also not allowed, right? I initially thought it is allowed because is. But previous discussions seem that it's not: , .
My impression is that isn't supposed to be allowed. That said, it would be kinda neat if it was. Right now I'm writing the same 3 lines over and over that look like and I'd love to be able to just say
I forgot to mention about mutability; currently is obsolete, and (heard from irc) it may be because it's confusing that immutable tuples are with . I don't know any previous discussion about it. anyone? If it is true, should be disallowed in the same manner, because is immutable while and are. Anyway, I agree with it's not cool to unpack manually.
Clearly something in the compiler is not checking that the LHS of an assignment is actually an lvalue. Kind of amusing. Rather surprising that this gets through borrowck, I'll have to look at that. It's probably assuming that an earlier pass would have caught such cases. Anyway, it'd be nice to permit , certainly, but it is not currently allowed. I think that'd be a post-Rust 1.0 sort of extension. I previously thought it would introduce horrible ambiguities into parsing, but I realize now that it would not, so long as you only have two cases: , which assigns to a pattern, and which always declares new bindings, and , which always overwrites existing lvalues.

Discussion:
let result_t = fcx.expr_ty(expr); demand::suptype(fcx, expr.span, result_t, lhs_t); <ins> let tcx = fcx.tcx(); if !ty::expr_is_lval(tcx, fcx.ccx.method_map, lhs) { tcx.sess.span_err(lhs.span, "illegal left-hand side expression"); } </ins> // Overwrite result of check_binop...this preserves existing behavior // but seems quite dubious with regard to user-defined methods // and so forth. - Niko

} ast::ExprAssign(lhs, rhs) => { check_assignment(fcx, lhs, rhs, id); <ins> let tcx = fcx.tcx(); if !ty::expr_is_lval(tcx, fcx.ccx.method_map, lhs) { tcx.sess.span_err(lhs.span, "illegal left-hand side expression"); } </ins> let lhs_ty = fcx.expr_ty(lhs); let rhs_ty = fcx.expr_ty(rhs); if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) {

<ins> // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn main() { 1 = 2; //~ ERROR illegal left-hand side expression 1 += 2; //~ ERROR illegal left-hand side expression (1, 2) = (3, 4); //~ ERROR illegal left-hand side expression let (a, b) = (1, 2); (a, b) = (3, 4); //~ ERROR illegal left-hand side expression None = Some(3); //~ ERROR illegal left-hand side expression } </ins>

fn main() { // assigning to various global constants <del> None = Some(3); //~ ERROR cannot assign to immutable static item </del> foo = 6; //~ ERROR cannot assign to immutable static item }