Skip to content

Potential issues with Rust's grammar I might upstream to r-l/r at some point #7

@fmease

Description

@fmease
  • S { 0 } is legal as a pattern but not as an expression
  • tuple field access $expr.0usize is illegal (since very recently) but $expr.0x0, $expr.0e1 (but not $expr.0e+1 thankfully) etc. is still legal
    • however $expr.1 != $expr.01 and $expr.0 != $expr.0_, so it all doesn't really matter (X)
    • the same thing applies to builtin # offset_of(…) / core::mem::offset_of!(…)
    • similarly for $extpath { 0x1: … } which is legal (however $extpath { 0e1: … } is illegal thankfully unlike $expr.0e1)
    • (X): actually, we should just reject _ and leading 0s in all numeric fields (w/ exception of number 0 ofc)
    • opened Drastically restrict the grammar of tuple indices rust-lang/rust#154492
  • match () { X } is accepted but not match () { X, } (under feature never_patterns)
  • const block items permit visibility
    • this is mentioned in the tracking issue: Tracking Issue for item-level const blocks rust-lang/rust#149226
    • however, it's under Unresolved Questions while it's clearly undesirable
    • we literally have a lint for pub const _: … = …; now
    • moreover, I doubt that this could be useful for macro DSLs
    • finally, rustc rejects fn f() { pub const {} } already anyway
    • I'm going to open an issue or a PR if this doesn't get fixed within the next 6 months (today is 2026-02-08)
  • we consider impl F() -> impl X + Y, impl F() -> dyn X + Y etc. ambiguous but not impl Fn() -> for<> X + Y
    • super minor, maybe not even a bug? my head is spinning
    • (obviously impl Fn() -> X + Y is intentionally not considered ambiguous)
    • similarly, dyn F() -> fn() -> X + Y is not considered ambiguous
    • in conclusion, it's quite an artificial & specialized restriction
    • more weirdly even, we're allowing fn f<T: F() -> 'a + Copy>(){} and counting the Copy as a sibling of F, not of 'a; so it gets parsed as (Fn() -> 'a+) + Copy, not Fn() -> ('a + Copy)
    • that happens because we check for the presence of + when encountering 'a in type position without checking whether "+ is allowed" in this context (it isn't)
  • we accept (use<>)+ even though you're not allowed to parenthesize use<…> in "normal" bounds
  • renames in delegation items can't be _ (discarded) contrary to use items
    • e.g., the following snippets get rejected: reuse x as _;, reuse f::{x as _};
  • 'r#static is legal but 'r#_ isn't (2021+); that doesn't make any sense
    • that would imply 'k#static being invalid and 'k#_ being valid
    • both static and _ denote "special" lifetimes, don't they?
    • or is static less special? just a normal lifetime that's predefined?
      • that argument doesn't hold because users can't rebind 'static (e.g., type X<'static> = (); is invalid)
    • contrary to _ that's a stand-in for other lifetimes

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-lowTechnical complexity: LowC-socialComplexity: Social in natureK-tracking-issueKind: Tracking issueP-lowPriority: LowS-actionableStatus: Actionable

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions