-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Apply noundef attribute to all scalar types which do not permit raw init #94157
Conversation
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit fa8c9719d2749752db1d388d043c177f9b6eb62a with merge f71dbc524c99e197ea8d54be1a5801bdab7c37aa... |
☀️ Try build successful - checks-actions |
Queued f71dbc524c99e197ea8d54be1a5801bdab7c37aa with parent 8c9640e, future comparison URL. |
Finished benchmarking commit (f71dbc524c99e197ea8d54be1a5801bdab7c37aa): comparison url. Summary: This benchmark run did not return any relevant results. 6 results were found to be statistically significant but too small to be relevant. If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf. @bors rollup=never |
Beyond `&`/`&mut`/`Box`, this covers `char`, discriminants, `NonZero*`, etc. All such types currently cause a Miri error if left uninitialized, and an `invalid_value` lint in cases like `mem::uninitialized::<char>()` Note that this _does not_ change whether or not it is UB for `u64` (or other integer types with no invalid values) to be undef.
fa8c971
to
5979b68
Compare
@bors r+ |
📌 Commit 5979b68 has been approved by |
⌛ Testing commit 5979b68 with merge d77ce1b08ed049da00de734d8928cf3166b77210... |
💔 Test failed - checks-actions |
This comment has been minimized.
This comment has been minimized.
@bors r+ |
📌 Commit 45ee3fc has been approved by |
☀️ Test successful - checks-actions |
Finished benchmarking commit (9fbff89): comparison url. Summary: This benchmark run shows 5 relevant improvements 🎉 to instruction counts.
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression |
@@ -3053,6 +3053,11 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { | |||
return; | |||
} | |||
|
|||
// Scalars which have invalid values cannot be undef. | |||
if !scalar.is_always_valid(self) { | |||
attrs.set(ArgAttribute::NoUndef); |
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.
With this logic, can't we remove some of the logic from #93670 since those types also are "not always valid"?
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 initially thought the same, but then we don't put noundef
on Option<&T/&mut T/Box<T>>>
, since they have no invalid values.
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.
Oh, I didn't realize those would get the attribute.
OTOH that still means we are missing Option<NonZero*>
, so maybe there's a more general way to handle this by special-casing enums? Like, if the scalar has Multiple
layout, then that one scalar contains its discriminant and hence we can definitely set NoUndef
? (This might miss newtypes around such enums, not sure if that's a problem.)
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.
You're right.
I'm a bit hesistant to add more complex logic here. I think the missing cases are fairly rare, just Option<NonZero*/NonNull>
(and equivalent types), and enums with exactly 256 (or 65536, etc.) variants. In the long run we can switch to the uninit
tracking added by #94527 and handle these cases without having to inspect the shape of the layout at all.
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.
Sure. :) I just hope we won't forget to clean up that duplication of logic in two different places ;)
Beyond
&
/&mut
/Box
, this coverschar
, enum discriminants,NonZero*
, etc.All such types currently cause a Miri error if left uninitialized,
and an
invalid_value
lint in cases likemem::uninitialized::<char>()
.Note that this does not change whether or not it is UB for
u64
(orother integer types with no invalid values) to be undef.
Fixes (partially) #74378.
r? @ghost (blocked on #94127)
@rustbot label S-blocked