Rust

Rust

Made by DeepSource
Extending string with another using chars RS-W1095
Bug risk
Minor

Extending one String with another is possible through .extend(s.chars()). However, this is better expressed using push_str(s).

Found comparison with NaN RS-E1012
Bug risk
Major
Autofix

Comparing a floating point with NaN using == or != is redundant. NaN cannot be compared to anything, not even itself. Use .is_nan() instead.

Comparing function pointer to null RS-W1115
Bug risk
Major

In 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.

Found redundant use of mem::replace RS-W1114
Bug risk
Major

Using 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.

Syntax Error RS-E1000
Bug risk
Critical

Encountered a syntax error.

Called mem::forget or mem::drop on a reference RS-E1010
Bug risk
Major

Calling 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.

Called mem::forget or mem::drop on a Copy type RS-E1011
Bug risk
Major

For 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.

Called mem::forget or mem::drop on a non-Drop type RS-E1021
Bug risk
Major

Calling std::mem::forget (or std::mem::drop) on types that do not implement the Drop trait is a no-op.

Found implementation of default() outside Default trait RS-E1022
Bug risk
Minor

Implementing 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().

Found I/O operation with unhandled return value RS-E1023
Bug risk
Major

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.

Cast from function pointer to non-pointer type RS-W1124
Bug risk
Major

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.

Found transmute between a type T and *T or &T RS-E1024
Bug risk
Major

Using 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.

Audit required: Function call in default() that returns Self RS-A1008
Bug risk
Major

The 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.

Found explicitly ignored future value RS-E1035
Bug risk
Major

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.

Audit required: Calling extend() on HashMap RS-A1009
Bug risk
Major

Using 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 HashMaps.

Found transmute between an integer and a bool RS-E1025
Bug risk
Major

Transmuting 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.

Found transmute between an integer and NonZero type RS-E1026
Bug risk
Major

Transmutes 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.

Found transmute between integer literal and fn ptr RS-E1027
Bug risk
Major

Creating a null function pointer is undefined behavior. Certain Rust types are defined to never be null. This includes references (&T, &mut T), boxes (Box), and function pointers (extern "abi" fn()).

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.

Found transmute between a literal and a *T ptr RS-E1028
Bug risk
Major

Transmuting 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.

Transmute from float or char to reference or pointer RS-E1029
Bug risk
Major

In 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.