-
Notifications
You must be signed in to change notification settings - Fork 13.3k
literal pattern lowering: use the pattern's type instead of the literal's in const_to_pat
#138992
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
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+ |
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