Skip to content

Commit fe7da3b

Browse files
committed
Add usize cast to clippy::manual_bits suggestion
1 parent 190f0de commit fe7da3b

File tree

4 files changed

+91
-58
lines changed

4 files changed

+91
-58
lines changed

clippy_lints/src/manual_bits.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2-
use clippy_utils::source::snippet_opt;
3-
use clippy_utils::{meets_msrv, msrvs};
2+
use clippy_utils::source::snippet_with_applicability;
3+
use clippy_utils::{get_parent_expr, meets_msrv, msrvs};
44
use rustc_ast::ast::LitKind;
55
use rustc_errors::Applicability;
66
use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath};
@@ -59,16 +59,25 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits {
5959
if matches!(resolved_ty.kind(), ty::Int(_) | ty::Uint(_));
6060
if let ExprKind::Lit(lit) = &other_expr.kind;
6161
if let LitKind::Int(8, _) = lit.node;
62-
6362
then {
63+
let mut app = Applicability::MachineApplicable;
64+
let ty_snip = snippet_with_applicability(cx, real_ty.span, "..", &mut app);
65+
let base_sugg = format!("{ty_snip}::BITS");
66+
67+
let sugg = if is_parent_ty_conversion(cx, expr) {
68+
base_sugg
69+
} else {
70+
format!("{base_sugg} as usize")
71+
};
72+
6473
span_lint_and_sugg(
6574
cx,
6675
MANUAL_BITS,
6776
expr.span,
6877
"usage of `mem::size_of::<T>()` to obtain the size of `T` in bits",
6978
"consider using",
70-
format!("{}::BITS", snippet_opt(cx, real_ty.span).unwrap()),
71-
Applicability::MachineApplicable,
79+
sugg,
80+
app,
7281
);
7382
}
7483
}
@@ -108,3 +117,19 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<
108117
}
109118
}
110119
}
120+
121+
fn is_parent_ty_conversion(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
122+
if let Some(parent_expr) = get_parent_expr(cx, expr) {
123+
if let ExprKind::Cast(..) = parent_expr.kind {
124+
return true;
125+
} else if let ExprKind::MethodCall(path, [_], _) = parent_expr.kind
126+
&& path.ident.name == sym!(try_into)
127+
{
128+
// This is only called for `usize` which implements `TryInto`. Therefore,
129+
// we don't have to check here if `self` implements the `TryInto` trait.
130+
return true;
131+
}
132+
}
133+
134+
false
135+
}

tests/ui/manual_bits.fixed

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,33 @@
66
use std::mem::{size_of, size_of_val};
77

88
fn main() {
9-
i8::BITS;
10-
i16::BITS;
11-
i32::BITS;
12-
i64::BITS;
13-
i128::BITS;
14-
isize::BITS;
15-
16-
u8::BITS;
17-
u16::BITS;
18-
u32::BITS;
19-
u64::BITS;
20-
u128::BITS;
21-
usize::BITS;
22-
23-
i8::BITS;
24-
i16::BITS;
25-
i32::BITS;
26-
i64::BITS;
27-
i128::BITS;
28-
isize::BITS;
29-
30-
u8::BITS;
31-
u16::BITS;
32-
u32::BITS;
33-
u64::BITS;
34-
u128::BITS;
35-
usize::BITS;
9+
i8::BITS as usize;
10+
i16::BITS as usize;
11+
i32::BITS as usize;
12+
i64::BITS as usize;
13+
i128::BITS as usize;
14+
isize::BITS as usize;
15+
16+
u8::BITS as usize;
17+
u16::BITS as usize;
18+
u32::BITS as usize;
19+
u64::BITS as usize;
20+
u128::BITS as usize;
21+
usize::BITS as usize;
22+
23+
i8::BITS as usize;
24+
i16::BITS as usize;
25+
i32::BITS as usize;
26+
i64::BITS as usize;
27+
i128::BITS as usize;
28+
isize::BITS as usize;
29+
30+
u8::BITS as usize;
31+
u16::BITS as usize;
32+
u32::BITS as usize;
33+
u64::BITS as usize;
34+
u128::BITS as usize;
35+
usize::BITS as usize;
3636

3737
size_of::<usize>() * 4;
3838
4 * size_of::<usize>();
@@ -42,7 +42,11 @@ fn main() {
4242
size_of_val(&0u32) * 8;
4343

4444
type Word = u32;
45-
Word::BITS;
45+
Word::BITS as usize;
4646
type Bool = bool;
4747
size_of::<Bool>() * 8;
48+
49+
let _: u32 = (size_of::<bool>() * 8) as u32;
50+
let _: u32 = (size_of::<bool>() * 8).try_into().unwrap();
51+
let _ = (size_of::<bool>() * 8).pow(5);
4852
}

tests/ui/manual_bits.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,8 @@ fn main() {
4545
size_of::<Word>() * 8;
4646
type Bool = bool;
4747
size_of::<Bool>() * 8;
48+
49+
let _: u32 = (size_of::<bool>() * 8) as u32;
50+
let _: u32 = (size_of::<bool>() * 8).try_into().unwrap();
51+
let _ = (size_of::<bool>() * 8).pow(5);
4852
}

tests/ui/manual_bits.stderr

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,153 +2,153 @@ error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
22
--> $DIR/manual_bits.rs:9:5
33
|
44
LL | size_of::<i8>() * 8;
5-
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS`
5+
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`
66
|
77
= note: `-D clippy::manual-bits` implied by `-D warnings`
88

99
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
1010
--> $DIR/manual_bits.rs:10:5
1111
|
1212
LL | size_of::<i16>() * 8;
13-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS`
13+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
1414

1515
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
1616
--> $DIR/manual_bits.rs:11:5
1717
|
1818
LL | size_of::<i32>() * 8;
19-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS`
19+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
2020

2121
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
2222
--> $DIR/manual_bits.rs:12:5
2323
|
2424
LL | size_of::<i64>() * 8;
25-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS`
25+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
2626

2727
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
2828
--> $DIR/manual_bits.rs:13:5
2929
|
3030
LL | size_of::<i128>() * 8;
31-
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS`
31+
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
3232

3333
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
3434
--> $DIR/manual_bits.rs:14:5
3535
|
3636
LL | size_of::<isize>() * 8;
37-
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS`
37+
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
3838

3939
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
4040
--> $DIR/manual_bits.rs:16:5
4141
|
4242
LL | size_of::<u8>() * 8;
43-
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS`
43+
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
4444

4545
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
4646
--> $DIR/manual_bits.rs:17:5
4747
|
4848
LL | size_of::<u16>() * 8;
49-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS`
49+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
5050

5151
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
5252
--> $DIR/manual_bits.rs:18:5
5353
|
5454
LL | size_of::<u32>() * 8;
55-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS`
55+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
5656

5757
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
5858
--> $DIR/manual_bits.rs:19:5
5959
|
6060
LL | size_of::<u64>() * 8;
61-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS`
61+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
6262

6363
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
6464
--> $DIR/manual_bits.rs:20:5
6565
|
6666
LL | size_of::<u128>() * 8;
67-
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
67+
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
6868

6969
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
7070
--> $DIR/manual_bits.rs:21:5
7171
|
7272
LL | size_of::<usize>() * 8;
73-
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS`
73+
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
7474

7575
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
7676
--> $DIR/manual_bits.rs:23:5
7777
|
7878
LL | 8 * size_of::<i8>();
79-
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS`
79+
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`
8080

8181
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
8282
--> $DIR/manual_bits.rs:24:5
8383
|
8484
LL | 8 * size_of::<i16>();
85-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS`
85+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
8686

8787
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
8888
--> $DIR/manual_bits.rs:25:5
8989
|
9090
LL | 8 * size_of::<i32>();
91-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS`
91+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
9292

9393
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
9494
--> $DIR/manual_bits.rs:26:5
9595
|
9696
LL | 8 * size_of::<i64>();
97-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS`
97+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
9898

9999
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
100100
--> $DIR/manual_bits.rs:27:5
101101
|
102102
LL | 8 * size_of::<i128>();
103-
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS`
103+
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
104104

105105
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
106106
--> $DIR/manual_bits.rs:28:5
107107
|
108108
LL | 8 * size_of::<isize>();
109-
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS`
109+
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
110110

111111
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
112112
--> $DIR/manual_bits.rs:30:5
113113
|
114114
LL | 8 * size_of::<u8>();
115-
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS`
115+
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
116116

117117
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
118118
--> $DIR/manual_bits.rs:31:5
119119
|
120120
LL | 8 * size_of::<u16>();
121-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS`
121+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
122122

123123
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
124124
--> $DIR/manual_bits.rs:32:5
125125
|
126126
LL | 8 * size_of::<u32>();
127-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS`
127+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
128128

129129
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
130130
--> $DIR/manual_bits.rs:33:5
131131
|
132132
LL | 8 * size_of::<u64>();
133-
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS`
133+
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
134134

135135
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
136136
--> $DIR/manual_bits.rs:34:5
137137
|
138138
LL | 8 * size_of::<u128>();
139-
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
139+
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
140140

141141
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
142142
--> $DIR/manual_bits.rs:35:5
143143
|
144144
LL | 8 * size_of::<usize>();
145-
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS`
145+
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
146146

147147
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
148148
--> $DIR/manual_bits.rs:45:5
149149
|
150150
LL | size_of::<Word>() * 8;
151-
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Word::BITS`
151+
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Word::BITS as usize`
152152

153153
error: aborting due to 25 previous errors
154154

0 commit comments

Comments
 (0)