Skip to content

deref_patterns: support string and byte string literals in explicit deref!("...") patterns #140028

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 24, 2025

Conversation

dianne
Copy link
Contributor

@dianne dianne commented Apr 19, 2025

When deref_patterns is enabled, this allows string literal patterns to be used where str is expected and byte string literal patterns to be used where [u8] or [u8; N] is expected. This lets them be used in explicit deref!("...") patterns to match on String, Box<str>, Vec<u8>, Box<[u8;N]>, etc. (as well as to match on slices and arrays obtained through other means). Implementation-wise, this follows up on #138992: similar to how byte string literals matching on &[u8] is implemented, this changes the type of the patterns as determined by HIR typeck, which informs const-to-pat on how to translate them to THIR (though strings needed a bit of extra work since we need references to call <str as PartialEq>::eq in the MIR lowering for string equality tests).

This PR does not add support for implicit deref pattern syntax (e.g. "..." matching on String, as string_deref_patterns allows). I have that implemented locally, but I'm saving it for a follow-up PR1.

This also does not add support for using named or associated constants of type &str where str is expected (nor likewise with named byte string constants). It'd be possible to add that if there's an appetite for it, but I figure it's simplest to start with literals.

This is gated by the deref_patterns feature since it's motivated by deref patterns. That said, its impact reaches outside of deref patterns; it may warrant a separate experiment and feature gate, particularly factoring in the follow-up1. Even without deref patterns, I think there's probably motivation for these changes.

The update to the unstable book added by this will conflict with #140022, so they shouldn't be merged at the same time.

Tracking issue for deref patterns: #87121

r? @oli-obk
cc @Nadrieril

Footnotes

  1. The piece missing from this PR to support implicit deref pattern syntax is to allow string literal patterns to implicitly dereference their scrutinees before matching (see resolve how to handle constants and default binding modes #44849). As a consequence, it also makes examples like the one in that issue work (though it's still gated by deref_patterns). I can provide more information on how I've implemented it or open a draft if it'd help in reviewing this PR. 2

@rustbot rustbot added 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. labels Apr 19, 2025
@rustbot
Copy link
Collaborator

rustbot commented Apr 19, 2025

Some changes occurred in match lowering

cc @Nadrieril

Some changes occurred in match checking

cc @Nadrieril

Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, Ty::new_slice(tcx, tcx.types.u8));
match *expected.kind() {
// Allow `b"...": &[u8]`
ty::Ref(_, inner_ty, _)
Copy link
Contributor

Choose a reason for hiding this comment

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

similarly, shouldn't we forward the mutability? Please add tests for this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added a test: (diff) (playground). Forwarding the mutability of the scrutinee would make sense, but since the current stable behavior is to use the literal's mutability, that would also need to be gated. And if we do forward ref mutability, we'd probably want to do it for array references too. Interestingly, it doesn't look like there were any other tests preventing this from changing; nice catch! I've made it the first commit since it was existing behavior and is unchanged by this PR.

dianne added 4 commits April 22, 2025 13:07
Specifically, this allows string literal patterns to be used where a
`str` is expected when `deref_patterns` is enabled.
Specifically, this allows byte string literal patterns to be used where
a `[u8]` or `[u8;N]` is expected when `deref_patterns` is enabled.
@dianne dianne force-pushed the lit-deref-pats-p1 branch from eaa8ab1 to 4c7e866 Compare April 22, 2025 20:21
@oli-obk
Copy link
Contributor

oli-obk commented Apr 23, 2025

@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Apr 23, 2025

📌 Commit 4c7e866 has been approved by oli-obk

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 23, 2025
Zalathar added a commit to Zalathar/rust that referenced this pull request Apr 24, 2025
`deref_patterns`: support string and byte string literals in explicit `deref!("...")` patterns

When `deref_patterns` is enabled, this allows string literal patterns to be used where `str` is expected and byte string literal patterns to be used where `[u8]` or `[u8; N]` is expected. This lets them be used in explicit `deref!("...")` patterns to match on `String`, `Box<str>`, `Vec<u8>`, `Box<[u8;N]>`, etc. (as well as to match on slices and arrays obtained through other means). Implementation-wise, this follows up on rust-lang#138992: similar to how byte string literals matching on `&[u8]` is implemented, this changes the type of the patterns as determined by HIR typeck, which informs const-to-pat on how to translate them to THIR (though strings needed a bit of extra work since we need references to call `<str as PartialEq>::eq` in the MIR lowering for string equality tests).

This PR does not add support for implicit deref pattern syntax (e.g. `"..."` matching on `String`, as `string_deref_patterns` allows). I have that implemented locally, but I'm saving it for a follow-up PR[^1].

This also does not add support for using named or associated constants of type `&str` where `str` is expected (nor likewise with named byte string constants). It'd be possible to add that if there's an appetite for it, but I figure it's simplest to start with literals.

This is gated by the `deref_patterns` feature since it's motivated by deref patterns. That said, its impact reaches outside of deref patterns; it may warrant a separate experiment and feature gate, particularly factoring in the follow-up[^1]. Even without deref patterns, I think there's probably motivation for these changes.

The update to the unstable book added by this will conflict with rust-lang#140022, so they shouldn't be merged at the same time.

Tracking issue for deref patterns: rust-lang#87121

r? `@oli-obk`
cc `@Nadrieril`

[^1]: The piece missing from this PR to support implicit deref pattern syntax is to allow string literal patterns to implicitly dereference their scrutinees before matching (see rust-lang#44849). As a consequence, it also makes examples like the one in that issue work (though it's still gated by `deref_patterns`). I can provide more information on how I've implemented it or open a draft if it'd help in reviewing this PR.
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 24, 2025
Rollup of 23 pull requests

Successful merges:

 - rust-lang#139261 (mitigate MSVC alignment issue on x86-32)
 - rust-lang#139307 (std: Add performance warnings to HashMap::get_disjoint_mut)
 - rust-lang#139700 (Autodiff flags)
 - rust-lang#139752 (set subsections_via_symbols for ld64 helper sections)
 - rust-lang#139809 (Don't warn about `v128` in wasm ABI transition)
 - rust-lang#139852 (StableMIR: Implement `CompilerInterface`)
 - rust-lang#139945 (Extend HIR to track the source and syntax of a lifetime)
 - rust-lang#140028 (`deref_patterns`: support string and byte string literals in explicit `deref!("...")` patterns)
 - rust-lang#140139 (rustc_target: Adjust RISC-V feature implication)
 - rust-lang#140143 (Move `sys::pal::os::Env` into `sys::env`)
 - rust-lang#140148 (CI: use aws codebuild for job dist-arm-linux)
 - rust-lang#140150 (fix MAX_EXP and MIN_EXP docs)
 - rust-lang#140172 (Make algebraic functions into `const fn` items.)
 - rust-lang#140177 ([compiletest] Parallelize test discovery)
 - rust-lang#140181 (Remove `synstructure::Structure::underscore_const` calls.)
 - rust-lang#140184 (Update doc of cygwin target)
 - rust-lang#140186 (Rename `compute_x` methods)
 - rust-lang#140187 ([AIX] Handle AIX dynamic library extensions within c-link-to-rust-dylib run-make test)
 - rust-lang#140191 (Remove git repository from git config)
 - rust-lang#140194 (minicore: Have `//@ add-core-stubs` also imply `-Cforce-unwind-tables=yes`)
 - rust-lang#140195 (triagebot: label minicore changes w/ `A-test-infra-minicore` and ping jieyouxu on changes)
 - rust-lang#140202 (Make #![feature(let_chains)] bootstrap conditional in compiler/)
 - rust-lang#140214 (Remove comment about handling non-global where bounds with corresponding projection)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 24, 2025
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#134446 (Stabilize the `cell_update` feature)
 - rust-lang#139307 (std: Add performance warnings to HashMap::get_disjoint_mut)
 - rust-lang#139450 (Impl new API `std::os::unix::fs::mkfifo` under feature `unix_fifo`)
 - rust-lang#139809 (Don't warn about `v128` in wasm ABI transition)
 - rust-lang#139852 (StableMIR: Implement `CompilerInterface`)
 - rust-lang#139945 (Extend HIR to track the source and syntax of a lifetime)
 - rust-lang#140028 (`deref_patterns`: support string and byte string literals in explicit `deref!("...")` patterns)
 - rust-lang#140181 (Remove `synstructure::Structure::underscore_const` calls.)
 - rust-lang#140232 (Remove unnecessary clones)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 5d52b37 into rust-lang:master Apr 24, 2025
6 checks passed
@rustbot rustbot added this to the 1.88.0 milestone Apr 24, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Apr 24, 2025
Rollup merge of rust-lang#140028 - dianne:lit-deref-pats-p1, r=oli-obk

`deref_patterns`: support string and byte string literals in explicit `deref!("...")` patterns

When `deref_patterns` is enabled, this allows string literal patterns to be used where `str` is expected and byte string literal patterns to be used where `[u8]` or `[u8; N]` is expected. This lets them be used in explicit `deref!("...")` patterns to match on `String`, `Box<str>`, `Vec<u8>`, `Box<[u8;N]>`, etc. (as well as to match on slices and arrays obtained through other means). Implementation-wise, this follows up on rust-lang#138992: similar to how byte string literals matching on `&[u8]` is implemented, this changes the type of the patterns as determined by HIR typeck, which informs const-to-pat on how to translate them to THIR (though strings needed a bit of extra work since we need references to call `<str as PartialEq>::eq` in the MIR lowering for string equality tests).

This PR does not add support for implicit deref pattern syntax (e.g. `"..."` matching on `String`, as `string_deref_patterns` allows). I have that implemented locally, but I'm saving it for a follow-up PR[^1].

This also does not add support for using named or associated constants of type `&str` where `str` is expected (nor likewise with named byte string constants). It'd be possible to add that if there's an appetite for it, but I figure it's simplest to start with literals.

This is gated by the `deref_patterns` feature since it's motivated by deref patterns. That said, its impact reaches outside of deref patterns; it may warrant a separate experiment and feature gate, particularly factoring in the follow-up[^1]. Even without deref patterns, I think there's probably motivation for these changes.

The update to the unstable book added by this will conflict with rust-lang#140022, so they shouldn't be merged at the same time.

Tracking issue for deref patterns: rust-lang#87121

r? ``@oli-obk``
cc ``@Nadrieril``

[^1]: The piece missing from this PR to support implicit deref pattern syntax is to allow string literal patterns to implicitly dereference their scrutinees before matching (see rust-lang#44849). As a consequence, it also makes examples like the one in that issue work (though it's still gated by `deref_patterns`). I can provide more information on how I've implemented it or open a draft if it'd help in reviewing this PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants