-
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
static FOO:Foo=FOO;
doesn't cause cycle error for zero-sized-type with no public constructor.
#71078
Comments
cc @rust-lang/wg-const-eval |
Possibly #62982? |
Weaponized soundness hole (using https://docs.rs/refl/0.2.1/refl/ as a foundation): pub static FOO: refl::Id<usize, Box<u8>> = FOO;
fn main() {
let x: Box<_> = FOO.cast(42usize);
drop(x);
}
mod refl {
pub struct Id<S: ?Sized, T: ?Sized>(core::marker::PhantomData<(fn(S) -> S, fn(T) -> T)>);
impl<S: ?Sized, T: ?Sized> Copy for Id<S, T> {}
impl<S: ?Sized, T: ?Sized> Clone for Id<S, T> { fn clone(&self) -> Self { *self } }
impl<S: ?Sized, T: ?Sized> Id<S, T> {
/// Casts a value of type `S` to `T`.
///
/// This is safe because the `Id` type is always guaranteed to
/// only be inhabited by `Id<T, T>` types by construction.
pub fn cast(self, value: S) -> T where S: Sized, T: Sized {
unsafe {
// Transmute the value;
// This is safe since we know by construction that
// S == T (including lifetime invariance) always holds.
let cast_value = core::mem::transmute_copy(&value);
// Forget the value;
// otherwise the destructor of S would be run.
core::mem::forget(value);
cast_value
}
}
}
} ==>
|
oopsie yeah... #62982 is probably where this started. But that is crucial to fix #62189. The problem is that "reading from a ZST" isn't actually doing anything. Here's the MIR for
So there actually is a |
Assigning |
[breaking change] Disallow statics initializing themselves fixes rust-lang#71078 Self-initialization is unsound because it breaks privacy assumptions that unsafe code can make. In ```rust pub mod foo { #[derive(Debug, Copy, Clone)] pub struct Foo { x: (), } } pub static FOO: foo::Foo = FOO; ``` unsafe could could expect that ony functions inside the `foo` module were able to create a value of type `Foo`.
I tried this code:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b8f15edf4886c9c8bb753636feb70ec2
I expected the code to fail to compile with a cycle error.
Instead, it compiled and ran,printing the value of
FOO
.Meta
I was able to verify that this bug happens for the 1.42.0 stable, 1.43-beta.5, and 1.44.0-nightly(2020-04-11 e82734e) versions.
Trying this code in rust.godbolt.org it errors up to 1.36.0,and doesn't error anymore from 1.37.0 onwards.
The text was updated successfully, but these errors were encountered: