-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Forward-compatibly deny drops in constants if they *could* actually run. #43932
Conversation
// Deny *any* live drops anywhere other than functions. | ||
if self.mode != Mode::Fn { | ||
// HACK(eddyb) Emulate a bit of dataflow analysis, | ||
// conservatively, that drop elaboration will do. |
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 not really "drop elaboration" dataflow - drop elaboration does not know that None
has no destructor - but rather "const qual" dataflow.
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.
Right, it's a combination of the two.
@bors try (for cargobomb) |
Forward-compatibly deny drops in constants if they *could* actually run. This is part of #40036, specifically the checks for user-defined destructor invocations on locals which *may not* have been moved away, the motivating example being: ```rust const FOO: i32 = (HasDrop {...}, 0).1; ``` The evaluation of constant MIR will continue to create `'static` slots for more locals than is necessary (if `Storage{Live,Dead}` statements are ignored), but it shouldn't be misusable. r? @nikomatsakis
☀️ Test successful - status-travis |
cc @rust-lang/infra Cargobomb run requested. |
Cargobomb run started |
Any news from cargobomb run? |
~27 hours remaining. I was away for the weekend so didn't manage to kick off a phase of the run until yesterday. |
Great, only regression is Rocket (which I've seen on crater before). However, I've changed by mind about it - it only uses associated |
Switching to S-waiting-on-review as looks like cargobomb's been run, cc @nikomatsakis |
Also waiting on me to treat inherent associated |
52667d8
to
8697b80
Compare
Latest crater report confirms Rocket has been fixed. r? @nikomatsakis |
Could you add a test for the rocket case, so we can make sure it stays fixed? |
// HACK(eddyb) Emulate a bit of dataflow analysis, | ||
// conservatively, that drop elaboration will do. | ||
let needs_drop = if let Lvalue::Local(local) = *lvalue { | ||
self.local_needs_drop[local] |
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 presume that we will reject (for constants) things that mutate "MIR locals" once they are assigned?
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.
Yeah that is considered an assignment and disallowed as "statement-like".
fn drop(&mut self) {} | ||
} | ||
|
||
static FOO: Option<&'static WithDtor> = Some(&WithDtor); |
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.
maybe add a test with struct WithoutDtor
and Some(&WithoutDtor)
? Does that behave differently?
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 has worked since 1.0, but if you have something more advanced in mind that would actually stress the new code, I'm up for it.
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.
Seems reasonable. I left a few questions.
(To be clear, I want to revisit shortly once I see answers.) |
@eddyb would you mind adding a few more tests, just to have more "exhaustive" coverage of the various cases? otherwise, r=me I think. |
📌 Commit c76a024 has been approved by |
Forward-compatibly deny drops in constants if they *could* actually run. This is part of #40036, specifically the checks for user-defined destructor invocations on locals which *may not* have been moved away, the motivating example being: ```rust const FOO: i32 = (HasDrop {...}, 0).1; ``` The evaluation of constant MIR will continue to create `'static` slots for more locals than is necessary (if `Storage{Live,Dead}` statements are ignored), but it shouldn't be misusable. r? @nikomatsakis
☀️ Test successful - status-appveyor, status-travis |
Better StorageLive / StorageDead placement for constants. Fixes problems in miri (see rust-lang/miri#324 (comment)) caused by the new scope rules in #43932. What I've tried to do here is always have a `StorageLive` but no `StorageDead` for `'static` slots. It might not work perfectly in all cases, but it should unblock miri. r? @nikomatsakis cc @oli-obk
This is part of #40036, specifically the checks for user-defined destructor invocations on locals which may not have been moved away, the motivating example being:
The evaluation of constant MIR will continue to create
'static
slots for more locals than is necessary (ifStorage{Live,Dead}
statements are ignored), but it shouldn't be misusable.r? @nikomatsakis