Skip to content

Parse lets as if they were items for diagnostics. #159044

Open
kpreid wants to merge 3 commits into
rust-lang:mainfrom
kpreid:pub-let
Open

Parse lets as if they were items for diagnostics. #159044
kpreid wants to merge 3 commits into
rust-lang:mainfrom
kpreid:pub-let

Conversation

@kpreid

@kpreid kpreid commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Partially addresses #92615.
Fixes #101622.

This change provides a precise diagnostic in all cases of let appearing in a context where items but not statements are permitted, and let appearing after an item modifier keyword (pub or final).

It provides a suggestion for replacing let with const (which should be usable interactively in rust-analyzer). It provides advice when the user might have thought final meant what it means in Java (immutable variable declaration).

It also consolidates two existing, less powerful let diagnostics into the new code: one for module bodies, and one for trait/impl bodies.

In order to be able to determine whether a let would parse if written properly, it adds a new parameter to the parsing functions, StmtWouldBeAllowed. This is a bit intrusive and not ideal, but I couldn’t think of a better solution, other than extending FnContext to mean more than it currently does, which seems not necessarily wise.

@rustbot

rustbot commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

rustfmt is developed in its own repository. If possible, consider making this change to rust-lang/rustfmt instead.

cc @rust-lang/rustfmt

The parser was modified, potentially altering the grammar of (stable) Rust
which would be a breaking change.

cc @fmease

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 9, 2026
@rustbot rustbot added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue. labels Jul 9, 2026
@rustbot

rustbot commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

r? @fee1-dead

rustbot has assigned @fee1-dead.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler, parser
  • compiler, parser expanded to 75 candidates
  • Random selection from 20 candidates

@rust-log-analyzer

This comment has been minimized.

.parse_item(
ForceCollect::Yes,
AllowConstBlockItems::Yes,
StmtWouldBeAllowed::NoOrUnknown,

@kpreid kpreid Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t like that I had to add a new parameter to parse_item everywhere, but I don’t know what would be better. Probably a new distinct entry point function.

View changes since the review

@kpreid kpreid Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tidy doesn’t like how long this file is now. Should I split it in this PR? Put up a separate PR? Ignore?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the absence of outside advice, I have split a new file parser/function.rs out of parser/item.rs to satisfy tidy. I will be happy to make that change in a separate PR if that is preferred.

let error = match allow_suggest_stmt {
StmtWouldBeAllowed::Yes => {
// We are in a function, `const` block, or other context in which a `let`
// *would* be allowed, except that we must have parsed some item-modifier

@kpreid kpreid Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an established term for these keywords like pub and final that appear before the item-kind keyword? I picked “modifier” arbitrarily.

View changes since the review

}
};

// FIXME: Ideally, we would have a `ItemKind::Err` that optionally defines a name but

@kpreid kpreid Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could try to add this new item kind to this PR if desired.

View changes since the review

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

kpreid added 3 commits July 16, 2026 17:18
This is needed to keep `item.rs` under the length limit.
This change provides a precise diagnostic in all cases of `let` appearing
in a context where items but not statements are permitted, and `let`
appearing after an item modifier keyword (`pub` or `final`).

It provides a suggestion for replacing `let` with `const` (which should
be usable interactively in rust-analyzer). It provides advice when the
user might have thought `final` meant what it means in Java (immutable
variable declaration).

It also consolidates two existing, less powerful `let` diagnostics into
the new code: one for module bodies, and one for `trait`/`impl` bodies.

In order to be able to determine whether a `let` *would* parse if
written properly, it adds a new parameter, `StmtWouldBeAllowed`. This
is a bit intrusive and not ideal, but I couldn’t think of a better
solution, other than extending `FnContext` to mean more than it
currently does, which seems not necessarily wise.
@rustbot

rustbot commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@fee1-dead

Copy link
Copy Markdown
Member

Sorry to be doing this but I am too swamped IRL to review a diff with this size.

@rustbot reroll

@rustbot rustbot assigned tiif and unassigned fee1-dead Jul 22, 2026
@kpreid

kpreid commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

Note that this PR would be much smaller if:

  • the move of function parsing was in a different PR, or
  • StmtWouldBeAllowed was not added to many callers, and the needed information was obtained some other way.

I would welcome any guidance as to whether and how to do those things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Poor recovery from pub let x = ...

5 participants