-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Fully destructure slice and array constants into patterns #77390
Conversation
r? @varkor (rust_highfive has picked a reviewer for you, use r? to override) |
@bors try @rust-timer queue |
Awaiting bors try build completion |
⌛ Trying commit 14a0b10 with merge 6f61447b8e9a5d5b75684be6181567232aced705... |
☀️ Try build successful - checks-actions, checks-azure |
Queued 6f61447b8e9a5d5b75684be6181567232aced705 with parent 00730fd, future comparison URL. |
Finished benchmarking try commit (6f61447b8e9a5d5b75684be6181567232aced705): comparison url. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up. @bors rollup=never |
ok, this is a perf improvement across the board. Unless people start putting ready for review @varkor |
// (ty::ConstKind::Value(ConstValue::ByRef { .. }), ty::Slice(_)) => { ... } | ||
_ => Some(ConstantValue(value)), | ||
} | ||
Some(ConstantValue(value)) |
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.
Is this related to exhaustiveness checking? Shouldn't opaque consts be treated as matching nothing for that as they might not be structural-match?
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.
it is, very good catch. We still need a variant for string slices here, as string slices are not opaque, but ConstantValue
is gone now and the replacement Str
only handles &str
constants. There are further improvements we can do here now that everything is explicit, but I'd rather not touch compare_const_vals
in this PR.
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.
I should note that I understand basically nothing of this code, if I caught anything that was an accident.^^
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.
Also if the last 2 comments are bugfixes, is it possible to add a test?
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.
There was no bugfix, no behaviour was changed, all I did was to move the bail-out (that was guaranteed to happen later) to an earlier site so the rest of the code that I was able to remove became dead code. This PR generally is mostly just removing dead code that became obsolete after destructuring all structural-eq constants into (non-const) patterns. This means except for &str
, all PatKind::Const
are now opaque.
Edit: they were behaving opaquely before already, but there was lots of code making sure we didn't run into ICEs around them by bailing out as "not contributing to exhaustiveness".
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.
I see. Maybe add some doc comments to PatKind
explaining this. :)
@bors try @rust-timer queue |
Awaiting bors try build completion |
⌛ Trying commit 638a29f7e10dae8d154fc4c7624ed8b0ea33df8a with merge be5d6894699da44f42b10af9e2afd5a423ca67d0... |
/// Literal values. | ||
ConstantValue(&'tcx ty::Const<'tcx>), | ||
/// String literals | ||
Str(&'tcx ty::Const<'tcx>), |
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.
Okay so this type is indeed only used for exhaustiveness checking, that's why we do not need consts in here? Maybe add that to the type doccomment.
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.
Why are strings special here?
☀️ Try build successful - checks-actions, checks-azure |
Queued be5d6894699da44f42b10af9e2afd5a423ca67d0 with parent 154f1f5, future comparison URL. |
… just treat them as nonexhaustive
Finished benchmarking try commit (be5d6894699da44f42b10af9e2afd5a423ca67d0): comparison url. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up. @bors rollup=never |
Once there's a comment explaining why strings are special, this should be good. |
I hope Oli can also add a comment clarifying this. :) |
Omg yes you removed |
ty::Bool => { | ||
[true, false].iter().map(|&b| ConstantValue(ty::Const::from_bool(cx.tcx, b))).collect() | ||
} | ||
ty::Bool => vec![make_range(0, 1)], | ||
ty::Array(ref sub_ty, len) if len.try_eval_usize(cx.tcx, cx.param_env).is_some() => { |
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.
Doesn't this affect diagnostics? I'd expect this would display "pattern 0
not covered" instead of "pattern false
not covered", but that would clearly be caught by the tests. I don't understand what piece of code makes it so it doesn't.
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.
I had also wondered this, but assumed this would be caught by tests, so it must have been okay. But you're right that it would be better to understand this (and add a comment).
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.
This is because while decisions are made on Constructor
s, they do not directly flow into diagnostics. Instead diagnostics are reported on Pat
s in https://github.com/rust-lang/rust/blob/6553d38bcb0c9193808ae93db8bd95bcf4c4824a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Well, I also made a small change here ( |
I'm concerned by #77390 (comment). I think we should delay merging this until @Nadrieril's concerns have been addressed. @bors r- |
Wait, integer and float ranges are still |
hmm yes, oops, forgot about those. Booleans and chars, too. |
@@ -158,6 +158,9 @@ crate enum PatKind<'tcx> { | |||
subpattern: Pat<'tcx>, | |||
}, | |||
|
|||
/// Opaque constant. This will be treated as a single, but unknown value. | |||
/// Except for `&str`, which will be handled as a string pattern and thus exhaustiveness | |||
/// checking will detect if you use the same string twice in different patterns. | |||
Constant { |
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.
This comment should also mention int ranges etc then
CI is already running, so you also need to |
@Nadrieril can you help me with the latest commit? I have absolutely no clue how to create a |
So, your example ICEs in stable (playground link), so that's probably unrelated to the current PR. |
I'm pretty sure I found how to fix one of the bugs: see #78057 . I'm not familiar enough with |
I was struggling to realize why I couldn't make rust/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs Lines 337 to 348 in 6af9846
I don't like these wildcards. Wrt _match.rs , I'd like to emit PatKind::Constant instead. Would that break anything? Who else uses the output of const_to_pat ?The alternative is that I ignore those cases since they are errors anyways. EDIT: this breaks things. This is not very important, I'll leave further discussion for #78057 |
closing in favour of #78072 Thanks so much! |
…, r=varkor Cleanup constant matching in exhaustiveness checking This supercedes rust-lang#77390. I made the `Opaque` constructor work. I have opened two issues rust-lang#78071 and rust-lang#78057 from the discussion we had on the previous PR. They are not regressions nor directly related to the current PR so I thought we'd deal with them separately. I left a FIXME somewhere because I didn't know how to compare string constants for equality. There might even be some unicode things that need to happen there. In the meantime I preserved previous behavior. EDIT: I accidentally fixed rust-lang#78071
…, r=varkor Cleanup constant matching in exhaustiveness checking This supercedes rust-lang#77390. I made the `Opaque` constructor work. I have opened two issues rust-lang#78071 and rust-lang#78057 from the discussion we had on the previous PR. They are not regressions nor directly related to the current PR so I thought we'd deal with them separately. I left a FIXME somewhere because I didn't know how to compare string constants for equality. There might even be some unicode things that need to happen there. In the meantime I preserved previous behavior. EDIT: I accidentally fixed rust-lang#78071
There were a lot of workarounds for making such constants not opaque, now we expand all constants into patterns unless they are not structural match