@@ -527,24 +527,44 @@ declare_clippy_lint! {
527
527
/// Checks if transmute calls have all generics specified.
528
528
///
529
529
/// ### Why is this bad?
530
- /// If not set, some unexpected output type could be retrieved instead of the expected one,
531
- /// potentially leading to invalid code .
530
+ /// If not, one or more unexpected types could be used during `transmute()`, potentially leading
531
+ /// to Undefined Behavior or other problems .
532
532
///
533
- /// This is particularly dangerous in case a seemingly innocent/unrelated change can cause type
534
- /// inference to start inferring a different type. E.g. the transmute is the tail expression of
535
- /// an `if` branch, and a different branches type changes, causing the transmute to silently
536
- /// have a different type, instead of a proper error.
533
+ /// This is particularly dangerous in case a seemingly innocent/unrelated change causes type
534
+ /// inference to result in a different type. For example, if `transmute()` is the tail
535
+ /// expression of an `if`-branch, and the `else`-branch type changes, the compiler may silently
536
+ /// infer a different type to be returned by `transmute()`. That is because the compiler is
537
+ /// free to change the inference of a type as long as that inference is technically correct,
538
+ /// regardless of the programmer's unknown expectation.
539
+ ///
540
+ /// Both type-parameters, the input- and the output-type, to any `transmute()` should
541
+ /// be given explicitly: Setting the input-type explicitly avoids confusion about what the
542
+ /// argument's type actually is. Setting the output-type explicitly avoids type-inference
543
+ /// to infer a technically correct yet unexpected type.
537
544
///
538
545
/// ### Example
539
546
/// ```no_run
540
547
/// # unsafe {
548
+ /// // Avoid "naked" calls to `transmute()`!
541
549
/// let x: i32 = std::mem::transmute([1u16, 2u16]);
550
+ ///
551
+ /// // `first_answers` is intended to transmute a slice of bool to a slice of u8.
552
+ /// // But the programmer forgot to index the first element of the outer slice,
553
+ /// // so we are actually transmuting from "pointers to slices" instead of
554
+ /// // transmuting from "a slice of bool", causing a nonsensical result.
555
+ /// let the_answers: &[&[bool]] = &[&[true, false, true]];
556
+ /// let first_answers: &[u8] = std::mem::transmute(the_answers);
542
557
/// # }
543
558
/// ```
544
559
/// Use instead:
545
560
/// ```no_run
546
561
/// # unsafe {
547
562
/// let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
563
+ ///
564
+ /// // The explicit type parameters on `transmute()` makes the intention clear,
565
+ /// // and cause a type-error if the actual types don't match our expectation.
566
+ /// let the_answers: &[&[bool]] = &[&[true, false, true]];
567
+ /// let first_answers: &[u8] = std::mem::transmute::<&[bool], &[u8]>(the_answers[0]);
548
568
/// # }
549
569
/// ```
550
570
#[ clippy:: version = "1.79.0" ]
0 commit comments