You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Warns if a trait is manually implemented on a union type, if it's not safe to do so.
For example
#[repr(C)]pubunionFoo{bar:u32,baz:u64}implPartialEq on Foo{fnpartial_eq(&self,&other:Self) -> bool{// Unsound! The baz field may be uninitialized data, if either argument was initialized like// let x = Foo{bar: 42}self.baz == other.baz}}
A common pattern for using unions is to initialize only the fields one intends to use. But there's no way for most trait impls to know which fields those are. Accessing an uninitialized field is undefined behavior. Even if the entire object was zero-initialized like let mut x: Foo = mem::zeroed(); x.bar =42, it's still not possible to correctly implement PartialEq, because the implementation doesn't know which fields "matter". For example:
letmut x = Foo{baz:0x1111111111111111};letmut y = Foo{baz:0x2222222222222222};
x.bar = 42;
y.bar = 42;assert_eq!(x, y);
In this example, logically x should equal y. But any PartialEq implementation would disagree, if it checks all of the struct's bits.
Similar arguments could be made for Hash, PartialOrd, and even Debug.
Lint Name
unsound_trait_impl_on_union
Category
correctness
Advantage
It will prevent undefined behavior, and prevent incorrect behavior of basic operations like ==. Such a lint could've caught bugs like rust-lang/libc#2816 .
Drawbacks
Occasionally it may actually be ok to implement these traits on a union, for example when every member has the same size.
Example
#[repr(C)]pubunionFoo{bar:u32,baz:u64}implPartialEq on Foo{fnpartial_eq(&self,&other:Self) -> bool{// Unsound! The baz field may be uninitialized data, if either argument was initialized like// let x = Foo{bar: 42}self.baz == other.baz}}
The PartialEq implementation should be omitted. There's simply no way to do it correctly.
The text was updated successfully, but these errors were encountered:
What it does
Warns if a trait is manually implemented on a union type, if it's not safe to do so.
For example
A common pattern for using unions is to initialize only the fields one intends to use. But there's no way for most trait impls to know which fields those are. Accessing an uninitialized field is undefined behavior. Even if the entire object was zero-initialized like
let mut x: Foo = mem::zeroed(); x.bar =42
, it's still not possible to correctly implementPartialEq
, because the implementation doesn't know which fields "matter". For example:In this example, logically
x
should equaly
. But anyPartialEq
implementation would disagree, if it checks all of the struct's bits.Similar arguments could be made for
Hash
,PartialOrd
, and evenDebug
.Lint Name
unsound_trait_impl_on_union
Category
correctness
Advantage
It will prevent undefined behavior, and prevent incorrect behavior of basic operations like
==
. Such a lint could've caught bugs like rust-lang/libc#2816 .Drawbacks
Occasionally it may actually be ok to implement these traits on a union, for example when every member has the same size.
Example
The
PartialEq
implementation should be omitted. There's simply no way to do it correctly.The text was updated successfully, but these errors were encountered: