chars
RS-W1095Extending one String with another is possible through .extend(s.chars())
. However, this is better expressed using push_str(s)
.
NaN
RS-E1012Comparing a floating point with NaN
using ==
or !=
is redundant. NaN
cannot be compared to anything, not even itself. Use .is_nan()
instead.
mem::replace
RS-W1114Using mem::replace(&mut _, mem::uninitialized())
or
mem::replace(&mut _, mem::zeroed())
may lead to
undefined behaviour even if the value is overwritten later,
as the uninitialized value may remain in case of panic recovery.
null
RS-W1115In Rust, function pointers are assumed to not be null. Just like references,
it is expected that nullable function pointers are implemented using Option
.
Hence, checking if they are null is invalid. Instead, the wrapped Option
can
be compared to None
using Option::is_none(..)
like <fn_ptr>.is_none()
to establish if the pointer is not present.
Encountered a syntax error.
mem::forget
or mem::drop
on a reference RS-E1010Calling std::mem::forget
(or std::mem::drop
) on a reference will forget (or
drop) the reference itself, which effectively does nothing. The underlying
reference value will remain unaffected.
mem::forget
or mem::drop
on a Copy type RS-E1011For types that implement the Copy
trait, std::mem::forget
(or
std::mem::drop
) effectively does nothing because the type is copied into the
function call, and the newly copied type is forgotten (or dropped).
Additionally, Copy
types do not have destructors; there is nothing for
std::mem::forget
or (or std::mem::drop
) to do.
mem::forget
or mem::drop
on a non-Drop type RS-E1021Calling std::mem::forget
(or std::mem::drop
) on
types that do not implement the Drop trait is a no-op.
default()
outside Default
trait RS-E1022Implementing the default()
method outside of the Default
trait is non-idiomatic.
It also makes deriving Default
on any subsequent types using this type impossible,
despite the presence of an implementation for default()
.
io::Write::write()
and io::Read::read()
are not guaranteed to process the entire buffer.
They return how many bytes were processed, which might be smaller than a given buffer’s length.
If you don’t need to deal with partial-write/read, use write_all()
/read_exact()
instead.
Casting function pointers or closures to integer types other than usize
may lead to truncation of the pointer address. If this is the intended
behaviour, prefer casting to usize and then casting to the integer type
with a comment explaining the reason for the truncation.
Casting function pointers or closures to types that are neither pointers nor integers results in invalid values, introduces bugs or even causing runtime errors in the program.
T
and *T
or &T
RS-E1024Using std::mem::transmute(..)
between a type T
and its *T
or &T
is not guaranteed to work
and is likely undefined behaviour.
That is, transmutes between a type T and *T is a common mistake and can lead to hard-to-track bugs.
default()
that returns Self
RS-A1008The default()
function in the Default
trait is used to create
a default instance of the type. While implementing this, if a function
call returns the same type, it could possibly create an infinite loop
by calling default()
itself.
A Future
is a suspended computation unit which must be driven to completion by polling it. Hence, when a Future
value is ignored, it is not polled to completion, leading to any errors that might occur at the time of Future
computation execution not being handled.
This can lead to unexpected behaviour if the program assumes that the code in Future
would run.
extend()
on HashMap
RS-A1009Using the extend()
method on a HashMap
overwrites the value associated
with an existing key if it is present in the hash map being used to extend
the original one. This may not be intentional, and can lead to unexpected
behaviour of overriding values associated with existing keys in both HashMap
s.
bool
RS-E1025Transmuting integers to booleans is not guaranteed to work properly, and is likely undefined behaviour.
That is, reinterpreting bytes of an integer as a boolean can result in an invalid in-memory
representation of a bool
, which can lead to hard-to-track bugs.
NonZero
type RS-E1026Transmutes from integers to NonZero
* types can be unsound.
Transmutes work on any type provided and might cause unsoundness
when those types change elsewhere. The new_unchecked
method
only works for the appropriate types instead, restricting the transmutes
to compatible integer conversions.
fn
ptr RS-E1027Creating a null function pointer is undefined behavior.
Certain Rust types are defined to never be null.
This includes references (&T, &mut T), boxes (Box
When interfacing with C, pointers that might be null
are often used, possibly requiring some convoluted
transmutes and/or unsafe code to handle conversions
to or from Rust types.
However, trying to construct or work with these invalid values is undefined behavior.
*T
ptr RS-E1028Transmuting a literal to pointer is undefined behavior.
For the cases where it is required to construct a null
ptr,
Rust provides the std::ptr::null()
and std::ptr::null_mut()
methods instead.
Note:
Not all cases can be detected at the moment of this writing. For example, variables which hold a null pointer and are then fed to a transmute call aren't detectable yet.
float
or char
to reference or pointer RS-E1029In Rust, the transmute function is used to reinterpret the bits of a value of one type as another type. Hence, both types must have the same size.
Compilation will fail if this is not guaranteed. Transmute is semantically equivalent to a bitwise move of one type into another. It copies the bits from the source value into the destination value.
Hence transmuting from float or char type to reference or pointers is considered bad in Rust because it can lead to undefined behavior. For example, transmuting a float to a pointer can lead to a null pointer exception.