Skip to content

deref_patterns: let string and byte string literal patterns peel references and smart pointers before matching #140658

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
May 6, 2025

Conversation

dianne
Copy link
Contributor

@dianne dianne commented May 5, 2025

This follows up on #140028. Together, they allow using string and byte string literal patterns to match on smart pointers when deref_patterns is enabled. In particular, string literals can now match on String, subsuming the functionality of the string_deref_patterns feature.

More generally, this works by letting literals peel references (and smart pointers) before matching, similar to most other patterns, providing an answer to #44849. Though it's only partially implemented at this point: this doesn't yet let named const patterns peel before matching. The peeling logic is general enough to support named consts, but the typing rules for named const patterns would need adjustments to feel consistent (e.g. arrays would need rules to be usable as slices, and const STR: &'static str wouldn't be able to match on a String unless a rule was added to let it be used where a str is expected, similar to what #140028 did for literals).

This also allows string and byte string patterns to match on mutable references, following up on #140028 (comment). Rather than forward the mutability of the scrutinee to literal patterns, I've opted to peel &muts from the scrutinee. From a design point of view, this makes the behavior consistent with what would be expected from deref coercions using the methodology in the next paragraph. From a diagnostics point of view, this avoids labeling string and byte string patterns as "mutable references", which I think could be confusing. See byte-string-type-errors.rs for how the diagnostics look.

At a high level, the peeling logic implemented here tries to mimic how deref coercions work for expressions: we peel references (and smart pointers) from the scrutinee until the pattern can match against it, and no more. This is primarily tested by const-pats-do-not-mislead-inference.rs. To illustrate the connection, I wasn't sure if this made sense to include in the test file, but I've translated those tests to make sure they give the same inference results as deref coercions: (playground). In each case, a reference to the scrutinee is coerced to have the type of the pattern (under a reference).

Tracking issue for deref patterns: #87121

r? @oli-obk
cc @Nadrieril

@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 May 5, 2025
@oli-obk
Copy link
Contributor

oli-obk commented May 6, 2025

@bors r+

@bors
Copy link
Collaborator

bors commented May 6, 2025

📌 Commit 7e4f6d3 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 May 6, 2025
bors added a commit to rust-lang-ci/rust that referenced this pull request May 6, 2025
…llaumeGomez

Rollup of 4 pull requests

Successful merges:

 - rust-lang#140135 (Unify sidebar buttons to use the same image)
 - rust-lang#140632 (add a test for issue rust-lang#81317)
 - rust-lang#140658 (`deref_patterns`: let string and byte string literal patterns peel references and smart pointers before matching)
 - rust-lang#140681 (Don't ignore compiler stderr in `lib-defaults.rs`)

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

`deref_patterns`: let string and byte string literal patterns peel references and smart pointers before matching

This follows up on rust-lang#140028. Together, they allow using string and byte string literal patterns to match on smart pointers when `deref_patterns` is enabled. In particular, string literals can now match on `String`, subsuming the functionality of the `string_deref_patterns` feature.

More generally, this works by letting literals peel references (and smart pointers) before matching, similar to most other patterns, providing an answer to rust-lang#44849. Though it's only partially implemented at this point: this doesn't yet let named const patterns peel before matching. The peeling logic is general enough to support named consts, but the typing rules for named const patterns would need adjustments to feel consistent (e.g. arrays would need rules to be usable as slices, and `const STR: &'static str` wouldn't be able to match on a `String` unless a rule was added to let it be used where a `str` is expected, similar to what rust-lang#140028 did for literals).

This also allows string and byte string patterns to match on mutable references, following up on rust-lang#140028 (comment). Rather than forward the mutability of the scrutinee to literal patterns, I've opted to peel `&mut`s from the scrutinee. From a design point of view, this makes the behavior consistent with what would be expected from deref coercions using the methodology in the next paragraph. From a diagnostics point of view, this avoids labeling string and byte string patterns as "mutable references", which I think could be confusing. See [`byte-string-type-errors.rs`](https://github.com/rust-lang/rust/compare/master...dianne:rust:lit-deref-pats-p2?expand=1#diff-4a0dd9b164b67c706751f3c0b5762ddab08bcef05a91972beb0190c6c1cd3706) for how the diagnostics look.

At a high level, the peeling logic implemented here tries to mimic how deref coercions work for expressions: we peel references (and smart pointers) from the scrutinee until the pattern can match against it, and no more. This is primarily tested by [`const-pats-do-not-mislead-inference.rs`](https://github.com/rust-lang/rust/compare/master...dianne:rust:lit-deref-pats-p2?expand=1#diff-19afc05b8aae9a30fe4a3a8c0bc2ab2c56b58755a45cdf5c12be0d5e83c4739d). To illustrate the connection, I wasn't sure if this made sense to include in the test file, but I've translated those tests to make sure they give the same inference results as deref coercions: [(playground)](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=1869744cb9cdfed71a686990aadf9fe1). In each case, a reference to the scrutinee is coerced to have the type of the pattern (under a reference).

Tracking issue for deref patterns: rust-lang#87121

r? `@oli-obk`
cc `@Nadrieril`
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