Skip to content

add scope! and extend! temporary scoping operators - #160297

Draft
dianne wants to merge 7 commits into
rust-lang:mainfrom
dianne:scope-extend-new
Draft

dianne wants to merge 7 commits into
rust-lang:mainfrom
dianne:scope-extend-new

Conversation

@dianne

@dianne dianne commented Jul 31, 2026 •

Copy link
Copy Markdown
Member

This is my initial take on the scope! and extend! operators proposed by @traviscross. I've done a bit of interpretation; the exact semantics will need to be discussed. Part of rust-lang/goals#648, "Redesigning super let".

Diagnostics, tests, documentation, comments, self-review, code cleanup, splitting this PR up, the PR descriptions, and probably other things are all very much unfinished. There's TODOs so tidy will fail. The operators themselves seem to work just fine though, so far. I've included a non-comprehensive demo in the form of a UI test: scope-extend.rs.

This is implemented on top of the (non-semantics-changing) refactor of temporary scoping I did as part of #146098. The first three commits are the tests and the refactor from that PR.

Since this experiment is meant to potentially replace super let statements, I'm piggy-backing off of the super_let feature gate for now. I figure if this works out and we migrate off of super let, we can rename the feature gate, but I could create a separate gate and merge them later if that'd make more sense.

Tracking issue for super let: #139076.

This PR is currently being split apart:

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 31, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job test-pr-check-2 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
note: `extend` could refer to the constant imported here
   --> src/tools/clippy/clippy_utils/src/sym.rs:41:17
    |
 15 | / macro_rules! generate {
 16 | |     ($($name:ident $(: $value:literal)? ,)*) => {
 17 | |         /// To be supplied to `rustc_interface::Config`
 18 | |         pub const EXTRA_SYMBOLS: &[&str] = &[
...   |
 41 | |             use clippy_symbols::*; // Then, glob import all of clippy's symbols
    | |                 ^^^^^^^^^^^^^^^^^
...   |
 44 | |     };
 45 | | }
    | |_- in this expansion of `generate!`
---
note: `extend` could also refer to the constant imported here
   --> src/tools/clippy/clippy_utils/src/sym.rs:40:17
    |
 15 | / macro_rules! generate {
 16 | |     ($($name:ident $(: $value:literal)? ,)*) => {
 17 | |         /// To be supplied to `rustc_interface::Config`
 18 | |         pub const EXTRA_SYMBOLS: &[&str] = &[
...   |
 40 | |             use rustc_span::sym::*; // First, glob import all of rustc's symbols
    | |                 ^^^^^^^^^^^^^^^^^^
...   |
 44 | |     };
---
    Checking tracing-error v0.2.1
[RUSTC-TIMING] tracing_error test:false 0.075
[RUSTC-TIMING] winnow test:false 0.897
    Checking object v0.40.0
error[E0004]: non-exhaustive patterns: `rustc_hir::ExprKind::Rescope(_, _, _)` not covered
    --> src/tools/clippy/clippy_utils/src/eager_or_lazy.rs:276:15
     |
 276 |         match e.kind {
     |               ^^^^^^ pattern `rustc_hir::ExprKind::Rescope(_, _, _)` not covered
     |
note: `rustc_hir::ExprKind<'_>` defined here
    --> compiler/rustc_hir/src/hir.rs:2580:1
     |
2580 | pub enum ExprKind<'hir> {
     | ^^^^^^^^^^^^^^^^^^^^^^^
...
2715 |     Rescope(RescopeKind, RescopeTarget, &'hir Expr<'hir>),
     |     ------- not covered
     = note: the matched value is of type `rustc_hir::ExprKind<'_>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
     |
 387 ~             ExprKind::Assign(..) | ExprKind::AssignOp(..) | ExprKind::Block(..) => self.eagerness |= NoChange,
 388 ~             rustc_hir::ExprKind::Rescope(_, _, _) => todo!(),
     |

error[E0004]: non-exhaustive patterns: `(&rustc_hir::ExprKind::Rescope(_, _, _), _)` not covered
   --> src/tools/clippy/clippy_utils/src/hir_utils.rs:524:27
    |
524 |           let is_eq = match (
    |  ___________________________^
525 | |             reduce_exprkind(self.inner.cx, self.eval_ctxt, &left.kind),
526 | |             reduce_exprkind(self.inner.cx, self.eval_ctxt, &right.kind),
527 | |         ) {
    | |_________^ pattern `(&rustc_hir::ExprKind::Rescope(_, _, _), _)` not covered
    |
    = note: the matched value is of type `(&rustc_hir::ExprKind<'_>, &rustc_hir::ExprKind<'_>)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
677 ~             ) => false,
678 ~             (&rustc_hir::ExprKind::Rescope(_, _, _), _) => todo!(),
    |

[RUSTC-TIMING] nom test:false 1.286
[RUSTC-TIMING] rustc_hash test:false 0.040
    Checking utf8parse v0.2.2
error[E0004]: non-exhaustive patterns: `&rustc_hir::ExprKind::Rescope(_, _, _)` not covered
    --> src/tools/clippy/clippy_utils/src/hir_utils.rs:1195:15
     |
1195 |         match &e.kind {
     |               ^^^^^^^ pattern `&rustc_hir::ExprKind::Rescope(_, _, _)` not covered
     |
note: `rustc_hir::ExprKind<'_>` defined here
    --> compiler/rustc_hir/src/hir.rs:2580:1
     |
2580 | pub enum ExprKind<'hir> {
     | ^^^^^^^^^^^^^^^^^^^^^^^
...
2715 |     Rescope(RescopeKind, RescopeTarget, &'hir Expr<'hir>),
     |     ------- not covered
     = note: the matched value is of type `&rustc_hir::ExprKind<'_>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
     |
1409 ~             ExprKind::Err(_) => {},
1410 ~             &rustc_hir::ExprKind::Rescope(_, _, _) => todo!(),
     |

[RUSTC-TIMING] utf8parse test:false 0.033
   Compiling portable-atomic v1.13.1
error[E0004]: non-exhaustive patterns: `rustc_hir::ExprKind::Rescope(_, _, _)` not covered
    --> src/tools/clippy/clippy_utils/src/sugg.rs:143:15
     |
 143 |         match expr.kind {
     |               ^^^^^^^^^ pattern `rustc_hir::ExprKind::Rescope(_, _, _)` not covered
     |
note: `rustc_hir::ExprKind<'_>` defined here
    --> compiler/rustc_hir/src/hir.rs:2580:1
     |
2580 | pub enum ExprKind<'hir> {
     | ^^^^^^^^^^^^^^^^^^^^^^^
...
2715 |     Rescope(RescopeKind, RescopeTarget, &'hir Expr<'hir>),
     |     ------- not covered
     = note: the matched value is of type `rustc_hir::ExprKind<'_>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
     |
 192 ~             ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::Cast, get_snippet(lhs.span), get_snippet(ty.span)),
 193 ~             rustc_hir::ExprKind::Rescope(_, _, _) => todo!(),
     |

error[E0004]: non-exhaustive patterns: `rustc_ast::ExprKind::Rescope(_, _, _)` not covered
    --> src/tools/clippy/clippy_utils/src/sugg.rs:206:15
     |
 206 |         match expr.kind {
     |               ^^^^^^^^^ pattern `rustc_ast::ExprKind::Rescope(_, _, _)` not covered
     |
note: `rustc_ast::ExprKind` defined here
    --> compiler/rustc_ast/src/ast.rs:1757:1
     |
1757 | pub enum ExprKind {
     | ^^^^^^^^^^^^^^^^^
...
1935 |     Rescope(RescopeKind, Label, Box<Expr>),
     |     ------- not covered
     = note: the matched value is of type `rustc_ast::ExprKind`
     = note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
     |
 281 ~             ),
 282 ~             rustc_ast::ExprKind::Rescope(_, _, _) => todo!(),
     |

[RUSTC-TIMING] build_script_build test:false 0.250
    Checking unicode-width v0.2.2
[RUSTC-TIMING] unicode_width test:false 0.140
    Checking rustc-demangle v0.1.28
error[E0004]: non-exhaustive patterns: `rustc_hir::ExprKind::Rescope(_, _, _)` not covered
    --> src/tools/clippy/clippy_utils/src/visitors.rs:705:15
     |
 705 |         match e.kind {
     |               ^^^^^^ pattern `rustc_hir::ExprKind::Rescope(_, _, _)` not covered
     |
note: `rustc_hir::ExprKind<'_>` defined here
    --> compiler/rustc_hir/src/hir.rs:2580:1
     |
2580 | pub enum ExprKind<'hir> {
     | ^^^^^^^^^^^^^^^^^^^^^^^
...
2715 |     Rescope(RescopeKind, RescopeTarget, &'hir Expr<'hir>),
     |     ------- not covered
     = note: the matched value is of type `rustc_hir::ExprKind<'_>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
     |
 781 ~             | ExprKind::Err(_) => (),
 782 ~             rustc_hir::ExprKind::Rescope(_, _, _) => todo!(),
     |

Some errors have detailed explanations: E0004, E0659.
For more information about an error, try `rustc --explain E0004`.
[RUSTC-TIMING] clippy_utils test:false 2.016

@rust-bors

rust-bors Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

This branch has not been deployed

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

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants