-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
literal pattern lowering: use the pattern's type instead of the literal's in const_to_pat
#138992
Conversation
This allows us to remove the field `treat_byte_string_as_slice` from `TypeckResults`, since the pattern's type contains everything necessary to get the correct lowering for byte string literal patterns. This leaves the implementation of `string_deref_patterns` broken, to be fixed in the next commit.
Some changes occurred in match checking cc @Nadrieril |
Actually, maybe it would make more sense for this to only use the pattern type for byte string literals. It's hacky either way, but for Edit:
On a technical level at least, this does seem to work; nothing's stopping a |
Since |
The one awkward thing I can see with that is that errors for trying to use non- Footnotes
|
Pretty sure valtree construction fails on String. Const to pat never sees it |
That's what I would have thought, since I'd expect it to have a pointer in it, but debug logging for Branch([Branch([Branch([Branch([Branch([Branch([Leaf(0x0000000000000001)]), Branch([])]), Branch([Leaf(0x0000000000000000)]), Branch([])]), Branch([])]), Leaf(0x0000000000000000)])]) The check/error for structural equality is in Maybe there's a bug in valtree construction and it's not getting stopped where it should? |
Ah, I stand corrected. Thank you
Hmm... Funny wrt Vec being the non struct eq type. So yea, we should try moving the struct eq checks into valtree creation. Maybe not in this PR tho. I think we can land your PR as is, but I think we'll need some more tests. Consts of |
I've added some tests for those cases, as well as for consts of types
I'll see how easy it would be to move the structural equality checks to valtree creation in another PR. |
// See also `tests/ui/match/pattern-deref-miscompile.rs`, which tests that byte string literal | ||
// patterns check slices' length appropriately when matching on slices. | ||
match BSTR_UNSIZED { | ||
BSTR_SIZED => {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the difference in the repr between this and mentioning the pattern inline that causes this error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be these lines in the literal pattern checking rules. Byte string literal patterns are assigned a slice reference type if the current scrutinee is known to be a slice reference, and otherwise default to the type of the literal (an array reference). Since that link's from the master
branch, that's also where treat_byte_string_as_slice
was assigned. There's no array unsizing logic for named constant patterns (type-checking code here), so it fails to unify &[u8]
with &[u8;3]
. If, hypothetically, that was special-cased, and the pattern was assigned the type &[u8]
rather than the constant's type, then that example would work too (though without the change this PR makes, it'd also have to set treat_byte_string_as_slice
or it'd be missing length checks).
Thanks, I'm convinced now there are no issues with this change @bors r+ |
…, r=oli-obk literal pattern lowering: use the pattern's type instead of the literal's in `const_to_pat` This has two purposes: - First, it enables removing the `treat_byte_string_as_slice` fields from `TypeckResults` and `ConstToPat`. A byte string pattern's type will be `&[u8]` when matching on a slice reference, so `const_to_pat` will lower it to a slice ref pattern. I believe this is tested by `tests/ui/match/pattern-deref-miscompile.rs`. - Second, it will simplify the implementation of byte string literals in deref patterns. If byte string patterns can be given the type `[u8; N]` or `[u8]` during HIR typeck, then nothing needs to be changed in `const_to_pat` in order to lower the patterns `deref!(b"..."): Vec<u8>` and `deref!(b"..."): Box<[u8; 3]>`. Implementation-wise, this uses `lit_to_const` to make a const with the pattern's type and the literal's valtree; that feels to me like the best way to make sure that the valtree representations of the pattern type and literal are the same. Though it may necessitate later changes to `lit_to_const` to accommodate giving byte string literal patterns non-reference types—would that be reasonable? This unfortunately doesn't work for the `string_deref_patterns` feature (since that gives string literal patterns the `String` type), so I added a workaround for that. However, once `deref_patterns` supports string literals, it may be able to replace `string_deref_patterns`; the special case for `String` can removed at that point. r? `@oli-obk`
…iaskrgr Rollup of 6 pull requests Successful merges: - rust-lang#138992 (literal pattern lowering: use the pattern's type instead of the literal's in `const_to_pat`) - rust-lang#139211 (interpret: add a version of run_for_validation for &self) - rust-lang#139235 (`AstValidator` tweaks) - rust-lang#139237 (Add a dep kind for use of the anon node with zero dependencies) - rust-lang#139260 (Add dianqk to codegen reviewers) - rust-lang#139264 (Fix two incorrect turbofish suggestions) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#138992 - dianne:simplify-byte-string-to-pat, r=oli-obk literal pattern lowering: use the pattern's type instead of the literal's in `const_to_pat` This has two purposes: - First, it enables removing the `treat_byte_string_as_slice` fields from `TypeckResults` and `ConstToPat`. A byte string pattern's type will be `&[u8]` when matching on a slice reference, so `const_to_pat` will lower it to a slice ref pattern. I believe this is tested by `tests/ui/match/pattern-deref-miscompile.rs`. - Second, it will simplify the implementation of byte string literals in deref patterns. If byte string patterns can be given the type `[u8; N]` or `[u8]` during HIR typeck, then nothing needs to be changed in `const_to_pat` in order to lower the patterns `deref!(b"..."): Vec<u8>` and `deref!(b"..."): Box<[u8; 3]>`. Implementation-wise, this uses `lit_to_const` to make a const with the pattern's type and the literal's valtree; that feels to me like the best way to make sure that the valtree representations of the pattern type and literal are the same. Though it may necessitate later changes to `lit_to_const` to accommodate giving byte string literal patterns non-reference types—would that be reasonable? This unfortunately doesn't work for the `string_deref_patterns` feature (since that gives string literal patterns the `String` type), so I added a workaround for that. However, once `deref_patterns` supports string literals, it may be able to replace `string_deref_patterns`; the special case for `String` can removed at that point. r? ``@oli-obk``
This has two purposes:
treat_byte_string_as_slice
fields fromTypeckResults
andConstToPat
. A byte string pattern's type will be&[u8]
when matching on a slice reference, soconst_to_pat
will lower it to a slice ref pattern. I believe this is tested bytests/ui/match/pattern-deref-miscompile.rs
.[u8; N]
or[u8]
during HIR typeck, then nothing needs to be changed inconst_to_pat
in order to lower the patternsderef!(b"..."): Vec<u8>
andderef!(b"..."): Box<[u8; 3]>
.Implementation-wise, this uses
lit_to_const
to make a const with the pattern's type and the literal's valtree; that feels to me like the best way to make sure that the valtree representations of the pattern type and literal are the same. Though it may necessitate later changes tolit_to_const
to accommodate giving byte string literal patterns non-reference types—would that be reasonable?This unfortunately doesn't work for the
string_deref_patterns
feature (since that gives string literal patterns theString
type), so I added a workaround for that. However, oncederef_patterns
supports string literals, it may be able to replacestring_deref_patterns
; the special case forString
can removed at that point.r? @oli-obk