@@ -16,40 +16,53 @@ pub(super) fn check<'tcx>(
1616 to_ty: Ty<'tcx>,
1717 arg: &'tcx Expr<'_>,
1818) -> bool {
19- let (ty::Int(_) | ty::Uint(_), Some(to_ty_adt)) = (&from_ty.kind(), to_ty.ty_adt_def()) else {
19+ let tcx = cx.tcx;
20+
21+ let (ty::Int(_) | ty::Uint(_), ty::Adt(adt, substs)) = (&from_ty.kind(), to_ty.kind()) else {
2022 return false;
2123 };
22- let Some(to_type_sym) = cx.tcx.get_diagnostic_name(to_ty_adt.did()) else {
24+
25+ if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
2326 return false;
2427 };
2528
26- if !matches!(
27- to_type_sym,
28- sym::NonZeroU8
29- | sym::NonZeroU16
30- | sym::NonZeroU32
31- | sym::NonZeroU64
32- | sym::NonZeroU128
33- | sym::NonZeroI8
34- | sym::NonZeroI16
35- | sym::NonZeroI32
36- | sym::NonZeroI64
37- | sym::NonZeroI128
38- ) {
39- return false;
40- }
29+ let coercable_types = [
30+ ("NonZeroU8", tcx.types.u8),
31+ ("NonZeroU16", tcx.types.u16),
32+ ("NonZeroU32", tcx.types.u32),
33+ ("NonZeroU64", tcx.types.u64),
34+ ("NonZeroU128", tcx.types.u128),
35+ ("NonZeroI8", tcx.types.i8),
36+ ("NonZeroI16", tcx.types.i16),
37+ ("NonZeroI32", tcx.types.i32),
38+ ("NonZeroI64", tcx.types.i64),
39+ ("NonZeroI128", tcx.types.i128),
40+ ];
41+
42+ let int_type = substs.type_at(0);
43+
44+ let Some(nonzero_alias) = coercable_types
45+ .iter()
46+ .find_map(|(nonzero_alias, t)| {
47+ if *t == int_type && *t == from_ty {
48+ Some(nonzero_alias)
49+ } else {
50+ None
51+ }
52+ })
53+ else { return false; };
4154
4255 span_lint_and_then(
4356 cx,
4457 TRANSMUTE_INT_TO_NON_ZERO,
4558 e.span,
46- &format!("transmute from a `{from_ty}` to a `{to_type_sym }`"),
59+ &format!("transmute from a `{from_ty}` to a `{nonzero_alias }`"),
4760 |diag| {
4861 let arg = sugg::Sugg::hir(cx, arg, "..");
4962 diag.span_suggestion(
5063 e.span,
5164 "consider using",
52- format!("{to_type_sym }::{}({arg})", sym::new_unchecked),
65+ format!("{nonzero_alias }::{}({arg})", sym::new_unchecked),
5366 Applicability::Unspecified,
5467 );
5568 },
0 commit comments