-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Add tests (and a bit of cleanup) for interior mut handling in promotion and const-checking #121893
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//@build-pass | ||
// Some code that looks like it might be relying on promotion, but actually this is using the | ||
// enclosing-scope rule, meaning the reference is "extended" to outlive its block and live as long | ||
// as the surrounding block (which in this case is the entire program). There are multiple | ||
// allocations being interned at once. | ||
|
||
struct Gen<T>(T); | ||
impl<'a, T> Gen<&'a T> { | ||
// Can't be promoted because `T` might not be `'static`. | ||
const C: &'a [T] = &[]; | ||
} | ||
|
||
// Can't be promoted because of `Drop`. | ||
const V: &Vec<i32> = &Vec::new(); | ||
|
||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,4 +15,27 @@ static RAW_SYNC_S: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) }; | |
const RAW_SYNC_C: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) }; | ||
//~^ ERROR: cannot refer to interior mutable data | ||
|
||
// This one does not get promoted because of `Drop`, and then enters interesting codepaths because | ||
// as a value it has no interior mutability, but as a type it does. See | ||
// <https://github.com/rust-lang/rust/issues/121610>. Value-based reasoning for interior mutability | ||
// is questionable (https://github.com/rust-lang/unsafe-code-guidelines/issues/493) so for now we | ||
// reject this, though not with a great error message. | ||
pub enum JsValue { | ||
Undefined, | ||
Object(Cell<bool>), | ||
} | ||
impl Drop for JsValue { | ||
fn drop(&mut self) {} | ||
} | ||
const UNDEFINED: &JsValue = &JsValue::Undefined; | ||
//~^ERROR: mutable pointer in final value of constant | ||
|
||
// In contrast, this one works since it is being promoted. | ||
const NONE: &'static Option<Cell<i32>> = &None; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe show off the promotion somewhere other than the trailing expression? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, I didn't even realize that's possible -- I will add // Making it clear that this is promotion, not "outer scope".
const NONE_EXPLICIT_PROMOTED: &'static Option<Cell<i32>> = {
let x = &None;
x
}; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interestingly, the behavior of this example changed between stable and nightly. On nightly it just says "can't drop |
||
// Making it clear that this is promotion, not "outer scope". | ||
const NONE_EXPLICIT_PROMOTED: &'static Option<Cell<i32>> = { | ||
let x = &None; | ||
x | ||
}; | ||
|
||
fn main() {} |
Uh oh!
There was an error while loading. Please reload this page.