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

Invalid Left-hand Assignment Provides Incorrect Syntax as Solution #93486

Closed
KSBilodeau opened this issue Jan 30, 2022 · 3 comments · Fixed by #93574
Closed

Invalid Left-hand Assignment Provides Incorrect Syntax as Solution #93486

KSBilodeau opened this issue Jan 30, 2022 · 3 comments · Fixed by #93574
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@KSBilodeau
Copy link
Contributor

KSBilodeau commented Jan 30, 2022

I was attempting to assign directly to the result of a vector's last_mut(), which caused this error to fire. That is when I discovered that the help section was telling me to do add an extra let to my while statement, which is not syntactically correct.

I tried this code:

#[allow(dead_code)]
use logos::Logos;

#[derive(Logos, Debug, PartialEq, Clone)]
enum LexToken<'a> {
    #[regex(r#"\p{L}[\p{L}|_|\\p{N}]+"#, |lex| lex.slice())]
    Text(&'a str),
    #[regex("-?[0-9]+", |lex| lex.slice().parse())]
    Integer(i64),
    #[regex(r#"-?[0-9]+\.[0-9]+"#, |lex| lex.slice().parse())]
    Float(f64),
    #[token("=")]
    Assignment,
    #[token(".")]
    Period,
    #[token("{")]
    OpenBlock,
    #[token("}")]
    CloseBlock,
    #[token(";")]
    LineTerminator,
    #[regex(r"[ \t\n\f]+", logos::skip, priority = 2)]
    #[error]
    Error,
}

#[derive(Debug, PartialEq, Clone)]
enum ParseToken {
    Keyword(String),
    Identifier(String),
    Integer(i64),
    Float(f64),
    Assignment,
    Period,
    Block(Vec<Statement>),
}

#[derive(Debug, PartialEq, Clone)]
struct Statement {
    tokens: Vec<ParseToken>,
}

fn main() {
    let mut lex = LexToken::lexer("let 1apple = 4.0;").peekable();

    let mut current_statement = vec![];

    while let Some(current_token) = lex.next() {
        match current_token {
            LexToken::Integer(num) => {
                if let Some(LexToken::Text(_)) = lex.peek() {
                    panic!("");
                }

                if let Some(ParseToken::Identifier(ident)) = current_statement.last() {
                   current_statement.last_mut().unwrap() = ParseToken::Identifier(format!("{}{}", ident, num));
                }
            },
            LexToken::Error => panic!(""),
            _ => {},
        }
    }
}

I expected to see this happen:
The code would fail to compile and the help message would tell me to dereference the left side, or at the least give me code that was syntactically correct.

Instead, this happened:
The could failed to compile, and the help message gave syntactically incorrect code as seen in the backtrace section.

Meta

rustc --version --verbose:

rustc 1.60.0-nightly (6abb6385b 2022-01-26)
binary: rustc
commit-hash: 6abb6385b2cb7249f67b9b3ce7522527767dd907
commit-date: 2022-01-26
host: x86_64-apple-darwin
release: 1.60.0-nightly
LLVM version: 13.0.0
Backtrace

ksbilodeau@keegans-mbp monch % RUST_BACKTRACE=1 cargo build
   Compiling monch v0.1.0 (/Users/ksbilodeau/Documents/Programming Projects/Rust Projects/monch)
error[E0070]: invalid left-hand side of assignment
  --> src/main.rs:56:58
   |
56 |                    current_statement.last_mut().unwrap() = ParseToken::Identifier(format!("{}{}", ident, num));
   |                    ------------------------------------- ^
   |                    |
   |                    cannot assign to this expression
   |
help: you might have meant to use pattern destructuring
   |
48 |     while let let Some(current_token) = lex.next() {
   |           +++

For more information about this error, try `rustc --explain E0070`.
error: could not compile `monch` due to previous error

@KSBilodeau KSBilodeau added the C-bug Category: This is a bug. label Jan 30, 2022
@JakobDegen
Copy link
Contributor

JakobDegen commented Jan 30, 2022

This minifies to

fn main() {
    let mut iter = vec![1, 2, 3_u8].into_iter();

    let mut v: Vec<u8> = vec![];

    while let Some(_) = iter.next() {
        v.last_mut().unwrap() = 3_u8;
    }
}

which reports

error[E0070]: invalid left-hand side of assignment
 --> src/main.rs:7:31
  |
7 |         v.last_mut().unwrap() = 3_u8;
  |         --------------------- ^
  |         |
  |         cannot assign to this expression
  |
help: you might have meant to use pattern destructuring
  |
6 |     while let let Some(_) = iter.next() {
  |           +++

For more information about this error, try `rustc --explain E0070`.

#93002 and #92979 are related I think, since this example produces the ICE mentioned there on stable

@JakobDegen
Copy link
Contributor

@rustbot label +A-diagnostics +D-invalid-suggestion +T-compiler

@rustbot rustbot added A-diagnostics Area: Messages for errors, warnings, and lints D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 30, 2022
@compiler-errors
Copy link
Member

@rustbot claim

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 C-bug Category: This is a bug. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants