From 3a9403e5d043342b5a3e72130afab6a5e38bcd9b Mon Sep 17 00:00:00 2001 From: GTimothy <22472919+GTimothy@users.noreply.github.com> Date: Fri, 21 Aug 2026 21:58:17 +0200 Subject: [PATCH 1/2] transmute_missing_annotation incorrect when a parameter is a pattern_type --- tests/ui/transmute_pattern_type.rs | 23 +++++++++++++++++++++++ tests/ui/transmute_pattern_type.stderr | 11 +++++++++++ 2 files changed, 34 insertions(+) create mode 100644 tests/ui/transmute_pattern_type.rs create mode 100644 tests/ui/transmute_pattern_type.stderr diff --git a/tests/ui/transmute_pattern_type.rs b/tests/ui/transmute_pattern_type.rs new file mode 100644 index 000000000000..e10ac64c75c9 --- /dev/null +++ b/tests/ui/transmute_pattern_type.rs @@ -0,0 +1,23 @@ +//@no-rustfix +#![feature(pattern_types, pattern_type_macro)] +use std::pat::pattern_type; + +// rust-lang/rust's `niche_types.rs`-style pattern: transmuting into/out of a +// pattern type was producing incorrect clippy suggestion to add a `() is ` instead +// of ` is )` argument which is not valid rust syntax. +// +// Now produces the correct syntax when suggesting. +// +// Only suggest if the pattern_type feature is active. +fn pattern_type_transmute(val: u32) -> Option { + if let 1.. = val { + Some(unsafe { std::mem::transmute(val) }) + //~^ missing_transmute_annotations + } else { + None + } +} + +fn pattern_type_transmute_back(val: pattern_type!(u32 is 1..)) -> u32 { + unsafe { std::mem::transmute(val) } +} diff --git a/tests/ui/transmute_pattern_type.stderr b/tests/ui/transmute_pattern_type.stderr new file mode 100644 index 000000000000..786dcad17fb6 --- /dev/null +++ b/tests/ui/transmute_pattern_type.stderr @@ -0,0 +1,11 @@ +error: transmute used without annotations + --> tests/ui/transmute_pattern_type.rs:10:33 + | +LL | Some(unsafe { std::mem::transmute(val) }) + | ^^^^^^^^^ help: consider adding missing annotations: `transmute::` + | + = note: `-D clippy::missing-transmute-annotations` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotations)]` + +error: aborting due to 1 previous error + From 4350a948e69f8e74a171f5a707a840c0e5aec892 Mon Sep 17 00:00:00 2001 From: GTimothy <22472919+GTimothy@users.noreply.github.com> Date: Sat, 22 Aug 2026 00:20:27 +0200 Subject: [PATCH 2/2] missing_transmute_annotations: adding range_pattern! handling --- .../missing_transmute_annotations.rs | 25 ++++++++++++++++++- tests/ui/transmute_pattern_type.fixed | 22 ++++++++++++++++ tests/ui/transmute_pattern_type.rs | 1 - tests/ui/transmute_pattern_type.stderr | 4 +-- 4 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 tests/ui/transmute_pattern_type.fixed diff --git a/clippy_lints/src/transmute/missing_transmute_annotations.rs b/clippy_lints/src/transmute/missing_transmute_annotations.rs index ddcc577cbd19..5f48b3085011 100644 --- a/clippy_lints/src/transmute/missing_transmute_annotations.rs +++ b/clippy_lints/src/transmute/missing_transmute_annotations.rs @@ -83,6 +83,20 @@ pub(super) fn check<'tcx>( let from_ty_no_name = ty_cannot_be_named(from_ty); let to_ty_no_name = ty_cannot_be_named(to_ty); if from_ty_no_name || to_ty_no_name { + if cx.tcx.features().pattern_types() + && let (Some(from_str), Some(to_str)) = ( + try_format_pat_ty(from_ty).or_else(|| (!from_ty_no_name).then_some(from_ty.to_string())), + try_format_pat_ty(to_ty).or_else(|| (!to_ty_no_name).then_some(to_ty.to_string())), + ) + { + diag.span_suggestion( + span, + "consider adding missing annotations", + format!("{}::<{from_str}, {to_str}>", last.ident), + Applicability::MaybeIncorrect, + ); + return; + } let to_name = match (from_ty_no_name, to_ty_no_name) { (true, false) => maybe_name_by_expr(cx, arg.span, "the origin type"), (false, true) => "the destination type".into(), @@ -113,7 +127,7 @@ fn ty_cannot_be_named(ty: Ty<'_>) -> bool { kind: ty::Opaque { .. } | ty::Inherent { .. }, .. } - ) + ) | ty::Pat(..) ) } @@ -124,3 +138,12 @@ fn maybe_name_by_expr<'a>(cx: &LateContext<'_>, span: Span, default: &'a str) -> .flatten() .unwrap_or(default.into()) } + +/// Tries to render a `ty::Pat` type as a valid `pattern_type!(...)` macro invocation, +fn try_format_pat_ty(ty: Ty<'_>) -> Option { + let ty::Pat(base, pat) = ty.kind() else { return None }; + if matches!(base.kind(), ty::Pat(..)) { + unreachable!("base of a ty::Pat cannot be a ty::Pat"); + } + Some(format!("pattern_type!({base} is {pat:?})")) +} diff --git a/tests/ui/transmute_pattern_type.fixed b/tests/ui/transmute_pattern_type.fixed new file mode 100644 index 000000000000..7a062b5b1786 --- /dev/null +++ b/tests/ui/transmute_pattern_type.fixed @@ -0,0 +1,22 @@ +#![feature(pattern_types, pattern_type_macro)] +use std::pat::pattern_type; + +// rust-lang/rust's `niche_types.rs`-style pattern: transmuting into/out of a +// pattern type was producing incorrect clippy suggestion to add a `() is ` instead +// of ` is )` argument which is not valid rust syntax. +// +// Now produces the correct syntax when suggesting. +// +// Only suggest if the pattern_type feature is active. +fn pattern_type_transmute(val: u32) -> Option { + if let 1.. = val { + Some(unsafe { std::mem::transmute::(val) }) + //~^ missing_transmute_annotations + } else { + None + } +} + +fn pattern_type_transmute_back(val: pattern_type!(u32 is 1..)) -> u32 { + unsafe { std::mem::transmute(val) } +} diff --git a/tests/ui/transmute_pattern_type.rs b/tests/ui/transmute_pattern_type.rs index e10ac64c75c9..3c8537b2a31b 100644 --- a/tests/ui/transmute_pattern_type.rs +++ b/tests/ui/transmute_pattern_type.rs @@ -1,4 +1,3 @@ -//@no-rustfix #![feature(pattern_types, pattern_type_macro)] use std::pat::pattern_type; diff --git a/tests/ui/transmute_pattern_type.stderr b/tests/ui/transmute_pattern_type.stderr index 786dcad17fb6..b72e801005fc 100644 --- a/tests/ui/transmute_pattern_type.stderr +++ b/tests/ui/transmute_pattern_type.stderr @@ -1,8 +1,8 @@ error: transmute used without annotations - --> tests/ui/transmute_pattern_type.rs:10:33 + --> tests/ui/transmute_pattern_type.rs:13:33 | LL | Some(unsafe { std::mem::transmute(val) }) - | ^^^^^^^^^ help: consider adding missing annotations: `transmute::` + | ^^^^^^^^^ help: consider adding missing annotations: `transmute::` | = note: `-D clippy::missing-transmute-annotations` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotations)]`