Skip to content

Commit 6d0d072

Browse files
committed
made transmute_adt_argument more resilant to transmutes of different adts with different arities
1 parent 46ab2b6 commit 6d0d072

File tree

2 files changed

+59
-31
lines changed

2 files changed

+59
-31
lines changed

clippy_lints/src/transmute/transmute_adt_argument.rs

Lines changed: 54 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,59 @@ use rustc_lint::LateContext;
55
use rustc_middle::ty::{self, GenericArgKind, Ty};
66

77
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
8-
from_ty
9-
.walk()
10-
.zip(to_ty.walk())
11-
.filter_map(|(from_ty, to_ty)| {
12-
if let (GenericArgKind::Type(from_ty), GenericArgKind::Type(to_ty)) = (from_ty.kind(), to_ty.kind()) {
13-
Some((from_ty, to_ty))
14-
} else {
15-
None
8+
// assumes walk will return all types in the same order
9+
let mut from_ty_walker = from_ty.walk();
10+
let mut to_ty_walker = to_ty.walk();
11+
let mut found = true;
12+
while let Some((from_ty, to_ty)) = from_ty_walker.next().zip(to_ty_walker.next()) {
13+
if let (GenericArgKind::Type(from_ty), GenericArgKind::Type(to_ty)) = (from_ty.kind(), to_ty.kind()) {
14+
match (from_ty.kind(), to_ty.kind()) {
15+
(ty::Bool, ty::Bool)
16+
| (ty::Char, ty::Char)
17+
| (ty::Int(_), ty::Int(_))
18+
| (ty::Uint(_), ty::Uint(_))
19+
| (ty::Float(_), ty::Float(_))
20+
| (ty::Foreign(_), ty::Foreign(_))
21+
| (ty::Str, ty::Str)
22+
| (ty::Array(_, _), ty::Array(_, _))
23+
| (ty::Pat(_, _), ty::Pat(_, _))
24+
| (ty::Slice(_), ty::Slice(_))
25+
| (ty::RawPtr(_, _), ty::RawPtr(_, _))
26+
| (ty::FnDef(_, _), ty::FnDef(_, _))
27+
| (ty::FnPtr(_, _), ty::FnPtr(_, _))
28+
| (ty::UnsafeBinder(_), ty::UnsafeBinder(_))
29+
| (ty::Dynamic(_, _), ty::Dynamic(_, _))
30+
| (ty::Closure(_, _), ty::Closure(_, _))
31+
| (ty::CoroutineClosure(_, _), ty::CoroutineClosure(_, _))
32+
| (ty::Coroutine(_, _), ty::Coroutine(_, _))
33+
| (ty::CoroutineWitness(_, _), ty::CoroutineWitness(_, _))
34+
| (ty::Never, ty::Never)
35+
| (ty::Tuple(_), ty::Tuple(_))
36+
| (ty::Alias(_, _), ty::Alias(_, _))
37+
| (ty::Param(_), ty::Param(_))
38+
| (ty::Bound(_, _), ty::Bound(_, _))
39+
| (ty::Placeholder(_), ty::Placeholder(_))
40+
| (ty::Infer(_), ty::Infer(_))
41+
| (ty::Error(_), ty::Error(_)) => {},
42+
(ty::Ref(_, _, from_mut), ty::Ref(_, _, to_mut)) => {
43+
if from_mut < to_mut {
44+
span_lint(
45+
cx,
46+
MUTABLE_ADT_ARGUMENT_TRANSMUTE,
47+
e.span,
48+
format!("transmute of type argument {from_ty} to {to_ty}"),
49+
);
50+
found = true;
51+
}
52+
},
53+
(ty::Adt(adt1, _), ty::Adt(adt2, _)) if adt1 == adt2 => {},
54+
_ => {
55+
from_ty_walker.skip_current_subtree();
56+
to_ty_walker.skip_current_subtree();
57+
continue;
58+
},
1659
}
17-
})
18-
.filter(|(from_ty_inner, to_ty_inner)| {
19-
if let (ty::Ref(_, _, from_mut), ty::Ref(_, _, to_mut)) = (from_ty_inner.kind(), to_ty_inner.kind())
20-
&& from_mut < to_mut
21-
{
22-
span_lint(
23-
cx,
24-
MUTABLE_ADT_ARGUMENT_TRANSMUTE,
25-
e.span,
26-
format!("transmute of type argument {from_ty_inner} to {from_ty_inner}"),
27-
);
28-
true
29-
} else {
30-
false
31-
}
32-
})
33-
.count()
34-
> 0
60+
}
61+
}
62+
return found;
3563
}

tests/ui/mutable_adt_argument_transmute.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: transmute of type argument &i32 to &i32
1+
error: transmute of type argument &i32 to &mut i32
22
--> tests/ui/mutable_adt_argument_transmute.rs:5:35
33
|
44
LL | let _: Option<&mut i32> = std::mem::transmute(Some(&5i32));
@@ -7,25 +7,25 @@ LL | let _: Option<&mut i32> = std::mem::transmute(Some(&5i32));
77
= note: `-D clippy::mutable-adt-argument-transmute` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::mutable_adt_argument_transmute)]`
99

10-
error: transmute of type argument &i32 to &i32
10+
error: transmute of type argument &i32 to &mut i32
1111
--> tests/ui/mutable_adt_argument_transmute.rs:7:39
1212
|
1313
LL | let _: Result<&mut i32, ()> = std::mem::transmute(Result::<&i32, ()>::Ok(&5i32));
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1515

16-
error: transmute of type argument &std::string::String to &std::string::String
16+
error: transmute of type argument &std::string::String to &mut std::string::String
1717
--> tests/ui/mutable_adt_argument_transmute.rs:10:13
1818
|
1919
LL | std::mem::transmute(Result::<Option<&String>, ()>::Ok(Some(&"foo".to_string())));
2020
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2121

22-
error: transmute of type argument &f32 to &f32
22+
error: transmute of type argument &f32 to &mut f32
2323
--> tests/ui/mutable_adt_argument_transmute.rs:12:43
2424
|
2525
LL | let _: Result<&mut f32, &usize> = std::mem::transmute(Result::<&f32, &usize>::Ok(&2f32));
2626
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2727

28-
error: transmute of type argument &usize to &usize
28+
error: transmute of type argument &usize to &mut usize
2929
--> tests/ui/mutable_adt_argument_transmute.rs:14:41
3030
|
3131
LL | let _: Result<(), &mut usize> = std::mem::transmute(Result::<(), &usize>::Ok(()));

0 commit comments

Comments
 (0)