Skip to content

Commit 3ab6aee

Browse files
committed
to_xx_bytes implemented, from_xx_bytes todo
Mentioned in rust-lang#10765
1 parent 652b4c7 commit 3ab6aee

File tree

6 files changed

+1461
-0
lines changed

6 files changed

+1461
-0
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -4641,6 +4641,7 @@ Released 2018-09-13
46414641
[`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock
46424642
[`await_holding_refcell_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_refcell_ref
46434643
[`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask
4644+
[`big_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#big_endian_bytes
46444645
[`bind_instead_of_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#bind_instead_of_map
46454646
[`blacklisted_name`]: https://rust-lang.github.io/rust-clippy/master/index.html#blacklisted_name
46464647
[`blanket_clippy_restriction_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#blanket_clippy_restriction_lints
@@ -4811,6 +4812,7 @@ Released 2018-09-13
48114812
[`get_first`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_first
48124813
[`get_last_with_len`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_last_with_len
48134814
[`get_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_unwrap
4815+
[`host_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#host_endian_bytes
48144816
[`identity_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#identity_conversion
48154817
[`identity_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#identity_op
48164818
[`if_let_mutex`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_mutex
@@ -4892,6 +4894,7 @@ Released 2018-09-13
48924894
[`let_with_type_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_with_type_underscore
48934895
[`lines_filter_map_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok
48944896
[`linkedlist`]: https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist
4897+
[`little_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#little_endian_bytes
48954898
[`logic_bug`]: https://rust-lang.github.io/rust-clippy/master/index.html#logic_bug
48964899
[`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal
48974900
[`macro_use_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_use_imports

clippy_lints/src/declared_lints.rs

+3
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
143143
crate::empty_drop::EMPTY_DROP_INFO,
144144
crate::empty_enum::EMPTY_ENUM_INFO,
145145
crate::empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS_INFO,
146+
crate::endian_bytes::BIG_ENDIAN_BYTES_INFO,
147+
crate::endian_bytes::HOST_ENDIAN_BYTES_INFO,
148+
crate::endian_bytes::LITTLE_ENDIAN_BYTES_INFO,
146149
crate::entry::MAP_ENTRY_INFO,
147150
crate::enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT_INFO,
148151
crate::enum_variants::ENUM_VARIANT_NAMES_INFO,

clippy_lints/src/endian_bytes.rs

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
use clippy_utils::{
2+
diagnostics::{span_lint_and_help, span_lint_and_then},
3+
is_lint_allowed, match_def_path, path_def_id,
4+
};
5+
use rustc_hir::{Expr, ExprKind};
6+
use rustc_lint::{LateContext, LateLintPass};
7+
use rustc_session::{declare_lint_pass, declare_tool_lint};
8+
9+
declare_clippy_lint! {
10+
/// ### What it does
11+
///
12+
/// ### Why is this bad?
13+
///
14+
/// ### Example
15+
/// ```rust
16+
/// // example code where clippy issues a warning
17+
/// ```
18+
/// Use instead:
19+
/// ```rust
20+
/// // example code which does not raise clippy warning
21+
/// ```
22+
#[clippy::version = "1.71.0"]
23+
pub HOST_ENDIAN_BYTES,
24+
restriction,
25+
"disallows usage of the `to_ne_bytes` method"
26+
}
27+
28+
declare_clippy_lint! {
29+
/// ### What it does
30+
/// Checks for the usage of the `to_ne_bytes` method.
31+
///
32+
/// ### Why is this bad?
33+
/// It's not, but some may prefer to specify the target endianness explicitly.
34+
///
35+
/// ### Example
36+
/// ```rust,ignore
37+
/// let _x = 2i32.to_ne_bytes();
38+
/// let _y = 2i64.to_ne_bytes();
39+
/// ```
40+
#[clippy::version = "1.71.0"]
41+
pub LITTLE_ENDIAN_BYTES,
42+
restriction,
43+
"disallows usage of the `to_le_bytes` method"
44+
}
45+
46+
declare_clippy_lint! {
47+
/// ### What it does
48+
/// Checks for the usage of the `to_le_bytes` method.
49+
///
50+
/// ### Why is this bad?
51+
///
52+
/// ### Example
53+
/// ```rust,ignore
54+
/// // example code where clippy issues a warning
55+
/// ```
56+
#[clippy::version = "1.71.0"]
57+
pub BIG_ENDIAN_BYTES,
58+
restriction,
59+
"disallows usage of the `to_be_bytes` method"
60+
}
61+
62+
declare_lint_pass!(EndianBytes => [HOST_ENDIAN_BYTES, LITTLE_ENDIAN_BYTES, BIG_ENDIAN_BYTES]);
63+
64+
impl LateLintPass<'_> for EndianBytes {
65+
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
66+
if_chain! {
67+
if let ExprKind::MethodCall(method_name, receiver, args, ..) = expr.kind;
68+
if let ExprKind::Lit(..) = receiver.kind;
69+
if args.is_empty();
70+
then {
71+
if method_name.ident.name == sym!(to_ne_bytes) {
72+
span_lint_and_help(
73+
cx,
74+
HOST_ENDIAN_BYTES,
75+
expr.span,
76+
"use of the method `to_ne_bytes`",
77+
None,
78+
"consider specifying the desired endianness",
79+
);
80+
} else if method_name.ident.name == sym!(to_le_bytes) {
81+
span_lint_and_then(cx, LITTLE_ENDIAN_BYTES, expr.span, "use of the method `to_le_bytes`", |diag| {
82+
if is_lint_allowed(cx, BIG_ENDIAN_BYTES, expr.hir_id) {
83+
diag.help("use `to_be_bytes` instead");
84+
}
85+
});
86+
} else if method_name.ident.name == sym!(to_be_bytes) {
87+
span_lint_and_then(cx, BIG_ENDIAN_BYTES, expr.span, "use of the method `to_be_bytes`", |diag| {
88+
if is_lint_allowed(cx, LITTLE_ENDIAN_BYTES, expr.hir_id) {
89+
diag.help("use `to_le_bytes` instead");
90+
}
91+
});
92+
}
93+
94+
// don't waste time also checking from_**_bytes
95+
return;
96+
}
97+
}
98+
99+
span_lint_and_help(
100+
cx,
101+
HOST_ENDIAN_BYTES,
102+
expr.span,
103+
"use of the method `from_ne_bytes`",
104+
None,
105+
&format!("consider specifying the desired endianness: {expr:?}"),
106+
);
107+
108+
if_chain! {
109+
if let ExprKind::Call(function, args) = expr.kind;
110+
if let Some(function_def_id) = path_def_id(cx, function);
111+
if args.len() == 1;
112+
then {
113+
if match_def_path(cx, function_def_id, &["from_ne_bytes"]) {
114+
span_lint_and_help(
115+
cx,
116+
HOST_ENDIAN_BYTES,
117+
expr.span,
118+
"use of the method `from_ne_bytes`",
119+
None,
120+
"consider specifying the desired endianness",
121+
);
122+
} else if match_def_path(cx, function_def_id, &["from_le_bytes"]) {
123+
span_lint_and_then(cx, LITTLE_ENDIAN_BYTES, expr.span, "use of the method `from_le_bytes`", |diag| {
124+
if is_lint_allowed(cx, BIG_ENDIAN_BYTES, expr.hir_id) {
125+
diag.help("use `from_be_bytes` instead");
126+
}
127+
});
128+
} else if match_def_path(cx, function_def_id, &["from_be_bytes"]) {
129+
span_lint_and_then(cx, BIG_ENDIAN_BYTES, expr.span, "use of the method `from_be_bytes`", |diag| {
130+
if is_lint_allowed(cx, LITTLE_ENDIAN_BYTES, expr.hir_id) {
131+
diag.help("use `from_le_bytes` instead");
132+
}
133+
});
134+
}
135+
}
136+
}
137+
}
138+
}

clippy_lints/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ mod else_if_without_else;
114114
mod empty_drop;
115115
mod empty_enum;
116116
mod empty_structs_with_brackets;
117+
mod endian_bytes;
117118
mod entry;
118119
mod enum_clike;
119120
mod enum_variants;
@@ -996,6 +997,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
996997
store.register_late_pass(|_| Box::new(default_constructed_unit_structs::DefaultConstructedUnitStructs));
997998
store.register_early_pass(|| Box::new(needless_else::NeedlessElse));
998999
store.register_late_pass(|_| Box::new(missing_fields_in_debug::MissingFieldsInDebug));
1000+
store.register_late_pass(|_| Box::new(endian_bytes::EndianBytes));
9991001
// add lints here, do not remove this comment, it's used in `new_lint`
10001002
}
10011003

tests/ui/endian_bytes.rs

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#![allow(unused)]
2+
#![allow(clippy::diverging_sub_expression)]
3+
#![no_main]
4+
5+
#[warn(clippy::host_endian_bytes)]
6+
fn host() {
7+
2u8.to_ne_bytes();
8+
2i8.to_ne_bytes();
9+
2u16.to_ne_bytes();
10+
2i16.to_ne_bytes();
11+
2u32.to_ne_bytes();
12+
2i32.to_ne_bytes();
13+
2u64.to_ne_bytes();
14+
2i64.to_ne_bytes();
15+
2u128.to_ne_bytes();
16+
2i128.to_ne_bytes();
17+
2usize.to_ne_bytes();
18+
2isize.to_ne_bytes();
19+
2.0f32.to_ne_bytes();
20+
2.0f64.to_ne_bytes();
21+
u8::from_ne_bytes(todo!());
22+
i8::from_ne_bytes(todo!());
23+
u16::from_ne_bytes(todo!());
24+
i16::from_ne_bytes(todo!());
25+
u32::from_ne_bytes(todo!());
26+
i32::from_ne_bytes(todo!());
27+
u64::from_ne_bytes(todo!());
28+
i64::from_ne_bytes(todo!());
29+
u128::from_ne_bytes(todo!());
30+
i128::from_ne_bytes(todo!());
31+
f32::from_ne_bytes(todo!());
32+
f64::from_ne_bytes(todo!());
33+
}
34+
35+
#[warn(clippy::little_endian_bytes)]
36+
fn little() {
37+
2u8.to_le_bytes();
38+
2i8.to_le_bytes();
39+
2u16.to_le_bytes();
40+
2i16.to_le_bytes();
41+
2u32.to_le_bytes();
42+
2i32.to_le_bytes();
43+
2u64.to_le_bytes();
44+
2i64.to_le_bytes();
45+
2u128.to_le_bytes();
46+
2i128.to_le_bytes();
47+
2usize.to_le_bytes();
48+
2isize.to_le_bytes();
49+
2.0f32.to_le_bytes();
50+
2.0f64.to_le_bytes();
51+
u8::from_le_bytes(todo!());
52+
i8::from_le_bytes(todo!());
53+
u16::from_le_bytes(todo!());
54+
i16::from_le_bytes(todo!());
55+
u32::from_le_bytes(todo!());
56+
i32::from_le_bytes(todo!());
57+
u64::from_le_bytes(todo!());
58+
i64::from_le_bytes(todo!());
59+
u128::from_le_bytes(todo!());
60+
i128::from_le_bytes(todo!());
61+
usize::from_le_bytes(todo!());
62+
isize::from_le_bytes(todo!());
63+
f32::from_le_bytes(todo!());
64+
f64::from_le_bytes(todo!());
65+
}
66+
67+
#[warn(clippy::big_endian_bytes)]
68+
fn big() {
69+
2u8.to_be_bytes();
70+
2i8.to_be_bytes();
71+
2u16.to_be_bytes();
72+
2i16.to_be_bytes();
73+
2u32.to_be_bytes();
74+
2i32.to_be_bytes();
75+
2u64.to_be_bytes();
76+
2i64.to_be_bytes();
77+
2u128.to_be_bytes();
78+
2i128.to_be_bytes();
79+
2.0f32.to_be_bytes();
80+
2.0f64.to_be_bytes();
81+
2usize.to_be_bytes();
82+
2isize.to_be_bytes();
83+
u8::from_be_bytes(todo!());
84+
i8::from_be_bytes(todo!());
85+
u16::from_be_bytes(todo!());
86+
i16::from_be_bytes(todo!());
87+
u32::from_be_bytes(todo!());
88+
i32::from_be_bytes(todo!());
89+
u64::from_be_bytes(todo!());
90+
i64::from_be_bytes(todo!());
91+
u128::from_be_bytes(todo!());
92+
i128::from_be_bytes(todo!());
93+
usize::from_be_bytes(todo!());
94+
isize::from_be_bytes(todo!());
95+
f32::from_be_bytes(todo!());
96+
f64::from_be_bytes(todo!());
97+
}
98+
99+
#[warn(clippy::little_endian_bytes)]
100+
#[warn(clippy::big_endian_bytes)]
101+
fn little_no_help() {
102+
2u8.to_le_bytes();
103+
2i8.to_le_bytes();
104+
2u16.to_le_bytes();
105+
2i16.to_le_bytes();
106+
2u32.to_le_bytes();
107+
2i32.to_le_bytes();
108+
2u64.to_le_bytes();
109+
2i64.to_le_bytes();
110+
2u128.to_le_bytes();
111+
2i128.to_le_bytes();
112+
2usize.to_le_bytes();
113+
2isize.to_le_bytes();
114+
2.0f32.to_le_bytes();
115+
2.0f64.to_le_bytes();
116+
u8::from_le_bytes(todo!());
117+
i8::from_le_bytes(todo!());
118+
u16::from_le_bytes(todo!());
119+
i16::from_le_bytes(todo!());
120+
u32::from_le_bytes(todo!());
121+
i32::from_le_bytes(todo!());
122+
u64::from_le_bytes(todo!());
123+
i64::from_le_bytes(todo!());
124+
u128::from_le_bytes(todo!());
125+
i128::from_le_bytes(todo!());
126+
usize::from_le_bytes(todo!());
127+
isize::from_le_bytes(todo!());
128+
f32::from_le_bytes(todo!());
129+
f64::from_le_bytes(todo!());
130+
}
131+
132+
#[warn(clippy::big_endian_bytes)]
133+
#[warn(clippy::little_endian_bytes)]
134+
fn big_no_help() {
135+
2u8.to_be_bytes();
136+
2i8.to_be_bytes();
137+
2u16.to_be_bytes();
138+
2i16.to_be_bytes();
139+
2u32.to_be_bytes();
140+
2i32.to_be_bytes();
141+
2u64.to_be_bytes();
142+
2i64.to_be_bytes();
143+
2u128.to_be_bytes();
144+
2i128.to_be_bytes();
145+
2usize.to_be_bytes();
146+
2isize.to_be_bytes();
147+
2.0f32.to_be_bytes();
148+
2.0f64.to_be_bytes();
149+
u8::from_be_bytes(todo!());
150+
i8::from_be_bytes(todo!());
151+
u16::from_be_bytes(todo!());
152+
i16::from_be_bytes(todo!());
153+
u32::from_be_bytes(todo!());
154+
i32::from_be_bytes(todo!());
155+
u64::from_be_bytes(todo!());
156+
i64::from_be_bytes(todo!());
157+
u128::from_be_bytes(todo!());
158+
i128::from_be_bytes(todo!());
159+
usize::from_be_bytes(todo!());
160+
isize::from_be_bytes(todo!());
161+
f32::from_be_bytes(todo!());
162+
f64::from_be_bytes(todo!());
163+
}

tests/ui/endian_bytes.stderr

+1,152
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)