@@ -527,24 +527,44 @@ declare_clippy_lint! {
527527 /// Checks if transmute calls have all generics specified.
528528 ///
529529 /// ### 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 .
532532 ///
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.
537544 ///
538545 /// ### Example
539546 /// ```no_run
540547 /// # unsafe {
548+ /// // Avoid "naked" calls to `transmute()`!
541549 /// 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);
542557 /// # }
543558 /// ```
544559 /// Use instead:
545560 /// ```no_run
546561 /// # unsafe {
547562 /// 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]);
548568 /// # }
549569 /// ```
550570 #[ clippy:: version = "1.79.0" ]
0 commit comments