-
Couldn't load subscription status.
- Fork 13.9k
allow deref patterns to move out of boxes #140022
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
Conversation
|
Some changes occurred in match lowering cc @Nadrieril Some changes occurred in match checking cc @Nadrieril |
`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.
`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.
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.
|
☔ The latest upstream changes (presumably #140239) made this pull request unmergeable. Please resolve the merge conflicts. |
Since deref patterns on boxes will be lowered differently, I'll be making a separate test file for them. This makes sure we're still testing the generic `Deref(Mut)::deref(_mut)`-based lowering.
This allows deref patterns to move out of boxes. Implementation-wise, I've opted to put the information of whether a deref pattern uses a built-in deref or a method call in the THIR. It'd be a bit less code to check `.is_box()` everywhere, but I think this way feels more robust (and we don't have a `mutability` field in the THIR that we ignore when the smart pointer's a box). I'm not sure about the naming (or using `ByRef`), though.
|
Rebased to merge the unstable book updates from this PR and #140028. |
This comment has been minimized.
This comment has been minimized.
2396af7 to
4e555fa
Compare
|
Exciting feature! @bors r+ |
allow deref patterns to move out of boxes This adds a case to lower deref patterns on boxes using a built-in deref instead of a `Deref::deref` or `DerefMut::deref_mut` call: if `deref!(inner): Box<T>` is matching on place `place`, the inner pattern `inner` now matches on `*place` rather than a temporary. No longer needing to call a method also means it won't borrow the scrutinee in match arms. This allows for bindings in `inner` to move out of `*place`. For comparison with box patterns, this uses the same MIR lowering but different THIR. Consequently, deref patterns on boxes are treated the same as any other deref patterns in match exhaustiveness analysis. Box patterns can't quite be implemented in terms of deref patterns until exhaustiveness checking for deref patterns is implemented (I'll open a PR for exhaustiveness soon!). Tracking issue: rust-lang#87121 r? `@Nadrieril`
…enton Rollup of 10 pull requests Successful merges: - rust-lang#139308 (add autodiff inline) - rust-lang#139656 (Stabilize `slice_as_chunks` library feature) - rust-lang#140022 (allow deref patterns to move out of boxes) - rust-lang#140276 (Do not compute type_of for impl item if impl where clauses are unsatisfied) - rust-lang#140302 (Move inline asm check to typeck, properly handle aliases) - rust-lang#140323 (Implement the internal feature `cfg_target_has_reliable_f16_f128`) - rust-lang#140391 (Rename sub_ptr to offset_from_unsigned in docs) - rust-lang#140394 (Make bootstrap git tests more self-contained) - rust-lang#140396 (Workaround for windows-gnu rust-lld test failure) - rust-lang#140402 (only return nested goals for `Certainty::Yes`) Failed merges: - rust-lang#139765 ([beta] Delay `hash_extract_if` stabilization from 1.87 to 1.88) r? `@ghost` `@rustbot` modify labels: rollup
…enton Rollup of 10 pull requests Successful merges: - rust-lang#139308 (add autodiff inline) - rust-lang#139656 (Stabilize `slice_as_chunks` library feature) - rust-lang#140022 (allow deref patterns to move out of boxes) - rust-lang#140276 (Do not compute type_of for impl item if impl where clauses are unsatisfied) - rust-lang#140302 (Move inline asm check to typeck, properly handle aliases) - rust-lang#140323 (Implement the internal feature `cfg_target_has_reliable_f16_f128`) - rust-lang#140391 (Rename sub_ptr to offset_from_unsigned in docs) - rust-lang#140394 (Make bootstrap git tests more self-contained) - rust-lang#140396 (Workaround for windows-gnu rust-lld test failure) - rust-lang#140402 (only return nested goals for `Certainty::Yes`) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#140022 - dianne:box-deref-pats, r=Nadrieril allow deref patterns to move out of boxes This adds a case to lower deref patterns on boxes using a built-in deref instead of a `Deref::deref` or `DerefMut::deref_mut` call: if `deref!(inner): Box<T>` is matching on place `place`, the inner pattern `inner` now matches on `*place` rather than a temporary. No longer needing to call a method also means it won't borrow the scrutinee in match arms. This allows for bindings in `inner` to move out of `*place`. For comparison with box patterns, this uses the same MIR lowering but different THIR. Consequently, deref patterns on boxes are treated the same as any other deref patterns in match exhaustiveness analysis. Box patterns can't quite be implemented in terms of deref patterns until exhaustiveness checking for deref patterns is implemented (I'll open a PR for exhaustiveness soon!). Tracking issue: rust-lang#87121 r? ``@Nadrieril``
This adds a case to lower deref patterns on boxes using a built-in deref instead of a
Deref::dereforDerefMut::deref_mutcall: ifderef!(inner): Box<T>is matching on placeplace, the inner patterninnernow matches on*placerather than a temporary. No longer needing to call a method also means it won't borrow the scrutinee in match arms. This allows for bindings ininnerto move out of*place.For comparison with box patterns, this uses the same MIR lowering but different THIR. Consequently, deref patterns on boxes are treated the same as any other deref patterns in match exhaustiveness analysis. Box patterns can't quite be implemented in terms of deref patterns until exhaustiveness checking for deref patterns is implemented (I'll open a PR for exhaustiveness soon!).
Tracking issue: #87121
r? @Nadrieril