Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 40a45a4

Browse files
Update and add ui tests for core/std suggestions
1 parent 1bcaf29 commit 40a45a4

22 files changed

+614
-66
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#![warn(clippy::default_instead_of_iter_empty)]
2+
#![allow(dead_code)]
3+
#![feature(lang_items)]
4+
#![no_std]
5+
6+
use core::panic::PanicInfo;
7+
8+
#[lang = "eh_personality"]
9+
extern "C" fn eh_personality() {}
10+
11+
#[panic_handler]
12+
fn panic(info: &PanicInfo) -> ! {
13+
loop {}
14+
}
15+
16+
#[derive(Default)]
17+
struct Iter {
18+
iter: core::iter::Empty<usize>,
19+
}
20+
21+
fn main() {
22+
// Do lint.
23+
let _ = core::iter::empty::<usize>();
24+
let _foo: core::iter::Empty<usize> = core::iter::empty();
25+
26+
// Do not lint.
27+
let _ = Iter::default();
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#![warn(clippy::default_instead_of_iter_empty)]
2+
#![allow(dead_code)]
3+
#![feature(lang_items)]
4+
#![no_std]
5+
6+
use core::panic::PanicInfo;
7+
8+
#[lang = "eh_personality"]
9+
extern "C" fn eh_personality() {}
10+
11+
#[panic_handler]
12+
fn panic(info: &PanicInfo) -> ! {
13+
loop {}
14+
}
15+
16+
#[derive(Default)]
17+
struct Iter {
18+
iter: core::iter::Empty<usize>,
19+
}
20+
21+
fn main() {
22+
// Do lint.
23+
let _ = core::iter::Empty::<usize>::default();
24+
let _foo: core::iter::Empty<usize> = core::iter::Empty::default();
25+
26+
// Do not lint.
27+
let _ = Iter::default();
28+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: `core::iter::empty()` is the more idiomatic way
2+
--> $DIR/default_instead_of_iter_empty_no_std.rs:23:13
3+
|
4+
LL | let _ = core::iter::Empty::<usize>::default();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::iter::empty::<usize>()`
6+
|
7+
= note: `-D clippy::default-instead-of-iter-empty` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::default_instead_of_iter_empty)]`
9+
10+
error: `core::iter::empty()` is the more idiomatic way
11+
--> $DIR/default_instead_of_iter_empty_no_std.rs:24:42
12+
|
13+
LL | let _foo: core::iter::Empty<usize> = core::iter::Empty::default();
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::iter::empty()`
15+
16+
error: aborting due to 2 previous errors
17+

tests/ui/mem_replace_no_std.fixed

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#![allow(unused)]
2+
#![warn(
3+
clippy::all,
4+
clippy::style,
5+
clippy::mem_replace_option_with_none,
6+
clippy::mem_replace_with_default
7+
)]
8+
#![feature(lang_items)]
9+
#![no_std]
10+
11+
use core::mem;
12+
use core::panic::PanicInfo;
13+
14+
#[lang = "eh_personality"]
15+
extern "C" fn eh_personality() {}
16+
17+
#[panic_handler]
18+
fn panic(info: &PanicInfo) -> ! {
19+
loop {}
20+
}
21+
22+
fn replace_option_with_none() {
23+
let mut an_option = Some(1);
24+
let _ = an_option.take();
25+
let an_option = &mut Some(1);
26+
let _ = an_option.take();
27+
}
28+
29+
fn replace_with_default() {
30+
let mut refstr = "hello";
31+
let _ = core::mem::take(&mut refstr);
32+
33+
let mut slice: &[i32] = &[1, 2, 3];
34+
let _ = core::mem::take(&mut slice);
35+
}
36+
37+
// lint is disabled for primitives because in this case `take`
38+
// has no clear benefit over `replace` and sometimes is harder to read
39+
fn dont_lint_primitive() {
40+
let mut pbool = true;
41+
let _ = mem::replace(&mut pbool, false);
42+
43+
let mut pint = 5;
44+
let _ = mem::replace(&mut pint, 0);
45+
}
46+
47+
fn main() {
48+
replace_option_with_none();
49+
replace_with_default();
50+
dont_lint_primitive();
51+
}
52+
53+
fn issue9824() {
54+
struct Foo<'a>(Option<&'a str>);
55+
impl<'a> core::ops::Deref for Foo<'a> {
56+
type Target = Option<&'a str>;
57+
58+
fn deref(&self) -> &Self::Target {
59+
&self.0
60+
}
61+
}
62+
impl<'a> core::ops::DerefMut for Foo<'a> {
63+
fn deref_mut(&mut self) -> &mut Self::Target {
64+
&mut self.0
65+
}
66+
}
67+
68+
struct Bar {
69+
opt: Option<u8>,
70+
val: u8,
71+
}
72+
73+
let mut f = Foo(Some("foo"));
74+
let mut b = Bar { opt: Some(1), val: 12 };
75+
76+
// replace option with none
77+
let _ = f.0.take();
78+
let _ = (*f).take();
79+
let _ = b.opt.take();
80+
// replace with default
81+
let _ = mem::replace(&mut b.val, u8::default());
82+
}

tests/ui/mem_replace_no_std.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#![allow(unused)]
2+
#![warn(
3+
clippy::all,
4+
clippy::style,
5+
clippy::mem_replace_option_with_none,
6+
clippy::mem_replace_with_default
7+
)]
8+
#![feature(lang_items)]
9+
#![no_std]
10+
11+
use core::mem;
12+
use core::panic::PanicInfo;
13+
14+
#[lang = "eh_personality"]
15+
extern "C" fn eh_personality() {}
16+
17+
#[panic_handler]
18+
fn panic(info: &PanicInfo) -> ! {
19+
loop {}
20+
}
21+
22+
fn replace_option_with_none() {
23+
let mut an_option = Some(1);
24+
let _ = mem::replace(&mut an_option, None);
25+
let an_option = &mut Some(1);
26+
let _ = mem::replace(an_option, None);
27+
}
28+
29+
fn replace_with_default() {
30+
let mut refstr = "hello";
31+
let _ = mem::replace(&mut refstr, "");
32+
33+
let mut slice: &[i32] = &[1, 2, 3];
34+
let _ = mem::replace(&mut slice, &[]);
35+
}
36+
37+
// lint is disabled for primitives because in this case `take`
38+
// has no clear benefit over `replace` and sometimes is harder to read
39+
fn dont_lint_primitive() {
40+
let mut pbool = true;
41+
let _ = mem::replace(&mut pbool, false);
42+
43+
let mut pint = 5;
44+
let _ = mem::replace(&mut pint, 0);
45+
}
46+
47+
fn main() {
48+
replace_option_with_none();
49+
replace_with_default();
50+
dont_lint_primitive();
51+
}
52+
53+
fn issue9824() {
54+
struct Foo<'a>(Option<&'a str>);
55+
impl<'a> core::ops::Deref for Foo<'a> {
56+
type Target = Option<&'a str>;
57+
58+
fn deref(&self) -> &Self::Target {
59+
&self.0
60+
}
61+
}
62+
impl<'a> core::ops::DerefMut for Foo<'a> {
63+
fn deref_mut(&mut self) -> &mut Self::Target {
64+
&mut self.0
65+
}
66+
}
67+
68+
struct Bar {
69+
opt: Option<u8>,
70+
val: u8,
71+
}
72+
73+
let mut f = Foo(Some("foo"));
74+
let mut b = Bar { opt: Some(1), val: 12 };
75+
76+
// replace option with none
77+
let _ = mem::replace(&mut f.0, None);
78+
let _ = mem::replace(&mut *f, None);
79+
let _ = mem::replace(&mut b.opt, None);
80+
// replace with default
81+
let _ = mem::replace(&mut b.val, u8::default());
82+
}

tests/ui/mem_replace_no_std.stderr

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
error: replacing an `Option` with `None`
2+
--> $DIR/mem_replace_no_std.rs:24:13
3+
|
4+
LL | let _ = mem::replace(&mut an_option, None);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
6+
|
7+
= note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]`
9+
10+
error: replacing an `Option` with `None`
11+
--> $DIR/mem_replace_no_std.rs:26:13
12+
|
13+
LL | let _ = mem::replace(an_option, None);
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
15+
16+
error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`
17+
--> $DIR/mem_replace_no_std.rs:31:13
18+
|
19+
LL | let _ = mem::replace(&mut refstr, "");
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut refstr)`
21+
|
22+
= note: `-D clippy::mem-replace-with-default` implied by `-D warnings`
23+
= help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`
24+
25+
error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`
26+
--> $DIR/mem_replace_no_std.rs:34:13
27+
|
28+
LL | let _ = mem::replace(&mut slice, &[]);
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut slice)`
30+
31+
error: replacing an `Option` with `None`
32+
--> $DIR/mem_replace_no_std.rs:77:13
33+
|
34+
LL | let _ = mem::replace(&mut f.0, None);
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()`
36+
37+
error: replacing an `Option` with `None`
38+
--> $DIR/mem_replace_no_std.rs:78:13
39+
|
40+
LL | let _ = mem::replace(&mut *f, None);
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()`
42+
43+
error: replacing an `Option` with `None`
44+
--> $DIR/mem_replace_no_std.rs:79:13
45+
|
46+
LL | let _ = mem::replace(&mut b.opt, None);
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()`
48+
49+
error: aborting due to 7 previous errors
50+

tests/ui/ptr_eq_no_std.fixed

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#![warn(clippy::ptr_eq)]
2+
#![no_std]
3+
#![feature(lang_items)]
4+
5+
use core::panic::PanicInfo;
6+
7+
#[lang = "eh_personality"]
8+
extern "C" fn eh_personality() {}
9+
10+
#[panic_handler]
11+
fn panic(info: &PanicInfo) -> ! {
12+
loop {}
13+
}
14+
15+
macro_rules! mac {
16+
($a:expr, $b:expr) => {
17+
$a as *const _ as usize == $b as *const _ as usize
18+
};
19+
}
20+
21+
macro_rules! another_mac {
22+
($a:expr, $b:expr) => {
23+
$a as *const _ == $b as *const _
24+
};
25+
}
26+
27+
fn main() {
28+
let a = &[1, 2, 3];
29+
let b = &[1, 2, 3];
30+
31+
let _ = core::ptr::eq(a, b);
32+
let _ = core::ptr::eq(a, b);
33+
let _ = a.as_ptr() == b as *const _;
34+
let _ = a.as_ptr() == b.as_ptr();
35+
36+
// Do not lint
37+
38+
let _ = mac!(a, b);
39+
let _ = another_mac!(a, b);
40+
41+
let a = &mut [1, 2, 3];
42+
let b = &mut [1, 2, 3];
43+
44+
let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
45+
let _ = a.as_mut_ptr() == b.as_mut_ptr();
46+
47+
let _ = a == b;
48+
let _ = core::ptr::eq(a, b);
49+
}

tests/ui/ptr_eq_no_std.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#![warn(clippy::ptr_eq)]
2+
#![no_std]
3+
#![feature(lang_items)]
4+
5+
use core::panic::PanicInfo;
6+
7+
#[lang = "eh_personality"]
8+
extern "C" fn eh_personality() {}
9+
10+
#[panic_handler]
11+
fn panic(info: &PanicInfo) -> ! {
12+
loop {}
13+
}
14+
15+
macro_rules! mac {
16+
($a:expr, $b:expr) => {
17+
$a as *const _ as usize == $b as *const _ as usize
18+
};
19+
}
20+
21+
macro_rules! another_mac {
22+
($a:expr, $b:expr) => {
23+
$a as *const _ == $b as *const _
24+
};
25+
}
26+
27+
fn main() {
28+
let a = &[1, 2, 3];
29+
let b = &[1, 2, 3];
30+
31+
let _ = a as *const _ as usize == b as *const _ as usize;
32+
let _ = a as *const _ == b as *const _;
33+
let _ = a.as_ptr() == b as *const _;
34+
let _ = a.as_ptr() == b.as_ptr();
35+
36+
// Do not lint
37+
38+
let _ = mac!(a, b);
39+
let _ = another_mac!(a, b);
40+
41+
let a = &mut [1, 2, 3];
42+
let b = &mut [1, 2, 3];
43+
44+
let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
45+
let _ = a.as_mut_ptr() == b.as_mut_ptr();
46+
47+
let _ = a == b;
48+
let _ = core::ptr::eq(a, b);
49+
}

0 commit comments

Comments
 (0)