Skip to content

Grammar ambiguity with left shifts and fully qualified (UFCS) paths #45144

Open
@petrochenkov

Description

@petrochenkov

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=35f2e9b9c6d48c33199bc878363a15df

trait Trait {
    const CONST: u8;
}
impl Trait for *const u8 {
    const CONST: u8 = 1;
}

fn main() {
    0<<*const u8 as Trait>::CONST;
}

0<<*const u8 as Trait>::CONST here unambiguously means 0 < (<*const u8 as Trait>::CONST) because it can't be parsed as a shift, but rustc tries to parse it as a shift and report an error:

error: expected expression, found keyword `const`
 --> src/main.rs:9:9
  |
9 |     0<<*const u8 as Trait>::CONST;
  |         ^^^^^

Note that you can't detect this situation using limited lookahead in general case, for example

0<<Trait1 + Trait2 + ... + 'static as Trait>::CONST

is unambiguously a type too, but we don't know it until we see 'static.

This syntax allows to construct fully ambiguous examples as well, e.g.

x<<y as z>::a

can be interpreted as both ((x << y) as z) > (::a) and x < (<y as z>::a).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-grammarArea: The grammar of RustA-parserArea: The lexing & parsing of Rust source code to an ASTC-enhancementCategory: An issue proposing an enhancement or a PR with one.P-lowLow priorityT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions