Skip to content

Parsing inconsistencies (lambda, proc, return) #28784

Closed
@rprichard

Description

@rprichard

I found more inconsistencies between rustc and parser-lalr.

I also noticed that Rust allows return expressions and lambda expressions to end with a struct literal, even when they're in a nostruct context. This seems inconsistent to me.

Lambdas (the two parsers disagree):

struct A { a: i32 }
fn lambda_expr_nostruct() -> A {
    // rustc accepts this, but parser-lalr does not.
    match || A { a: 123 } {
        f => f()
    }
}

Return expressions (the two parsers agree):

struct A { a: i32 }
fn return_ambiguity_1() -> A {
    match A { a: 1 } { x => x } // rejected by rustc and parser-lalr
}
fn return_ambiguity_2() -> A {
    match return A { a: 1 } { _ => A { a: 1 } } // accepted by rustc and parser-lalr
}

The rustc and parser-lalr parsers disagree about whether a bare return expression can be cast:

fn cast_of_return() {
    // rustc rejects, parser-lalr accepts
    // error: expected identifier, found keyword `as`
    return as ();
    (return as ());

    return == (); // rustc accepts, parser-lalr accepts
    loop {
        continue as (); // rustc accepts, parser-lalr accepts
        continue == (); // rustc accepts, parser-lalr accepts
        break as ();    // rustc accepts, parser-lalr accepts
        break == ();    // rustc accepts, parser-lalr accepts
    };
}

Finally, I also noticed these two differences, which seem much less interesting to me. The grammar is probably just out-of-date or buggy:

lambda sometimes requires braces:

fn lambda_braces() {
    // parser-lalr accepts this, but rustc does not.  I think this is an
    // obvious bug in the parser-lalr.y grammar.  If there is a return type,
    // then curly braces are required.
    let _x = || -> i32 10;
}

proc is obsolete:

fn proc_syntax() {
    // parser-lalr also accepts this.  I think the proc syntax is obsolete, and
    // the {proc_expr, proc_expr_nostruct} non-terminals could be removed from
    // parser-lalr.y.
    let _x = proc() {};
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-parserArea: The lexing & parsing of Rust source code to an ASTC-bugCategory: This is a bug.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.P-lowLow priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions