Skip to content

Commit a0d6213

Browse files
authored
Rollup merge of rust-lang#76894 - ecstatic-morse:lint-unused-borrows, r=lcnr
Lint for unused borrows as part of `UNUSED_MUST_USE` Resolves rust-lang#76264. This means an `unused_must_use` warning for statements like `&expr;` and `&mut expr;`. `unused_must_use` was chosen because it already lints for logical operators (`&&` and `||`) whose result is unused. Unused borrows actually appear fairly often in `rustc`'s test suite, since we have tests that rely on side-effects of the index operator (panicking). These cannot be written as `expr[..];`, since the result is unsized, but they can be written as `let _ = &expr[..];`, which is what this PR does. See the linked issue for the motivating example. This lint also found a benign mistake in the derived impl of `HashStable`.
2 parents ec7f8d9 + 3b5105c commit a0d6213

File tree

18 files changed

+115
-35
lines changed

18 files changed

+115
-35
lines changed

compiler/rustc_lint/src/unused.rs

+3
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
154154
| hir::BinOpKind::Shl
155155
| hir::BinOpKind::Shr => Some("bitwise operation"),
156156
},
157+
158+
hir::ExprKind::AddrOf(..) => Some("borrow"),
159+
157160
hir::ExprKind::Unary(..) => Some("unary operation"),
158161
_ => None,
159162
};

compiler/rustc_macros/src/hash_stable.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_ma
5454
quote! {}
5555
} else if let Some(project) = attrs.project {
5656
quote! {
57-
&#bi.#project.hash_stable(__hcx, __hasher);
57+
(&#bi.#project).hash_stable(__hcx, __hasher);
5858
}
5959
} else {
6060
quote! {
@@ -95,7 +95,7 @@ pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::To
9595
quote! {}
9696
} else if let Some(project) = attrs.project {
9797
quote! {
98-
&#bi.#project.hash_stable(__hcx, __hasher);
98+
(&#bi.#project).hash_stable(__hcx, __hasher);
9999
}
100100
} else {
101101
quote! {

library/alloc/tests/str.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ mod slice_index {
504504
#[test]
505505
#[should_panic]
506506
fn test_slice_fail() {
507-
&"中华Việt Nam"[0..2];
507+
let _ = &"中华Việt Nam"[0..2];
508508
}
509509

510510
panic_cases! {
@@ -684,13 +684,13 @@ mod slice_index {
684684
#[test]
685685
#[should_panic(expected = "byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
686686
fn test_slice_fail_truncated_1() {
687-
&LOREM_PARAGRAPH[..1024];
687+
let _ = &LOREM_PARAGRAPH[..1024];
688688
}
689689
// check the truncation in the panic message
690690
#[test]
691691
#[should_panic(expected = "luctus, im`[...]")]
692692
fn test_slice_fail_truncated_2() {
693-
&LOREM_PARAGRAPH[..1024];
693+
let _ = &LOREM_PARAGRAPH[..1024];
694694
}
695695
}
696696

@@ -705,7 +705,7 @@ fn test_str_slice_rangetoinclusive_ok() {
705705
#[should_panic]
706706
fn test_str_slice_rangetoinclusive_notok() {
707707
let s = "abcαβγ";
708-
&s[..=3];
708+
let _ = &s[..=3];
709709
}
710710

711711
#[test]
@@ -721,7 +721,7 @@ fn test_str_slicemut_rangetoinclusive_ok() {
721721
fn test_str_slicemut_rangetoinclusive_notok() {
722722
let mut s = "abcαβγ".to_owned();
723723
let s: &mut str = &mut s;
724-
&mut s[..=3];
724+
let _ = &mut s[..=3];
725725
}
726726

727727
#[test]

library/alloc/tests/vec.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -541,35 +541,35 @@ fn test_index_out_of_bounds() {
541541
#[should_panic]
542542
fn test_slice_out_of_bounds_1() {
543543
let x = vec![1, 2, 3, 4, 5];
544-
&x[!0..];
544+
let _ = &x[!0..];
545545
}
546546

547547
#[test]
548548
#[should_panic]
549549
fn test_slice_out_of_bounds_2() {
550550
let x = vec![1, 2, 3, 4, 5];
551-
&x[..6];
551+
let _ = &x[..6];
552552
}
553553

554554
#[test]
555555
#[should_panic]
556556
fn test_slice_out_of_bounds_3() {
557557
let x = vec![1, 2, 3, 4, 5];
558-
&x[!0..4];
558+
let _ = &x[!0..4];
559559
}
560560

561561
#[test]
562562
#[should_panic]
563563
fn test_slice_out_of_bounds_4() {
564564
let x = vec![1, 2, 3, 4, 5];
565-
&x[1..6];
565+
let _ = &x[1..6];
566566
}
567567

568568
#[test]
569569
#[should_panic]
570570
fn test_slice_out_of_bounds_5() {
571571
let x = vec![1, 2, 3, 4, 5];
572-
&x[3..2];
572+
let _ = &x[3..2];
573573
}
574574

575575
#[test]

library/std/src/sys_common/wtf8/tests.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ fn wtf8_slice() {
301301
#[test]
302302
#[should_panic]
303303
fn wtf8_slice_not_code_point_boundary() {
304-
&Wtf8::from_str("aé 💩")[2..4];
304+
let _ = &Wtf8::from_str("aé 💩")[2..4];
305305
}
306306

307307
#[test]
@@ -312,18 +312,18 @@ fn wtf8_slice_from() {
312312
#[test]
313313
#[should_panic]
314314
fn wtf8_slice_from_not_code_point_boundary() {
315-
&Wtf8::from_str("aé 💩")[2..];
315+
let _ = &Wtf8::from_str("aé 💩")[2..];
316316
}
317317

318318
#[test]
319319
fn wtf8_slice_to() {
320-
assert_eq!(&Wtf8::from_str("aé 💩")[..4].bytes, b"a\xC3\xA9 ");
320+
let _ = assert_eq!(&Wtf8::from_str("aé 💩")[..4].bytes, b"a\xC3\xA9 ");
321321
}
322322

323323
#[test]
324324
#[should_panic]
325325
fn wtf8_slice_to_not_code_point_boundary() {
326-
&Wtf8::from_str("aé 💩")[5..];
326+
let _ = &Wtf8::from_str("aé 💩")[5..];
327327
}
328328

329329
#[test]

src/test/ui/array-slice-vec/slice-panic-1.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ impl Drop for Foo {
1717

1818
fn foo() {
1919
let x: &[_] = &[Foo, Foo];
20-
&x[3..4];
20+
let _ = &x[3..4];
2121
}
2222

2323
fn main() {

src/test/ui/array-slice-vec/slice-panic-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn bar() -> usize {
2121

2222
fn foo() {
2323
let x: &[_] = &[Foo, Foo];
24-
&x[3..bar()];
24+
let _ = &x[3..bar()];
2525
}
2626

2727
fn main() {

src/test/ui/array-slice-vec/slice.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,14 @@ impl IndexMut<RangeFull> for Foo {
6767

6868
fn main() {
6969
let mut x = Foo;
70-
&x[..];
71-
&x[Foo..];
72-
&x[..Foo];
73-
&x[Foo..Foo];
74-
&mut x[..];
75-
&mut x[Foo..];
76-
&mut x[..Foo];
77-
&mut x[Foo..Foo];
70+
let _ = &x[..];
71+
let _ = &x[Foo..];
72+
let _ = &x[..Foo];
73+
let _ = &x[Foo..Foo];
74+
let _ = &mut x[..];
75+
let _ = &mut x[Foo..];
76+
let _ = &mut x[..Foo];
77+
let _ = &mut x[Foo..Foo];
7878
unsafe {
7979
assert_eq!(COUNT, 8);
8080
}

src/test/ui/const-generics/issues/issue-61432.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn promote<const N: i32>() {
88
// let n = N;
99
// &n;
1010

11-
&N;
11+
let _ = &N;
1212
}
1313

1414
fn main() {

src/test/ui/dynamically-sized-types/dst-index.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ impl Index<usize> for T {
2929

3030
fn main() {
3131
assert_eq!(&S[0], "hello");
32-
&T[0];
32+
let _ = &T[0];
3333
// let x = &x as &Debug;
3434
}

src/test/ui/generator/too-live-local-in-immovable-gen.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fn main() {
1515
yield ();
1616
4i32
1717
};
18-
&a;
18+
let _ = &a;
1919
};
2020
}
2121
}

src/test/ui/generator/too-live-local-in-immovable-gen.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ LL | | // Tests that the generator transformation finds out that `a`
66
LL | | // during the yield expression. Type checking will also compute liveness
77
LL | | // and it should also find out that `a` is not live.
88
... |
9-
LL | | &a;
9+
LL | | let _ = &a;
1010
LL | | };
1111
| |__________^
1212
|

src/test/ui/generator/yield-in-initializer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn main() {
1111
yield;
1212
true
1313
};
14-
&opt;
14+
let _ = &opt;
1515
}
1616
};
1717
}

src/test/ui/issues/issue-43205.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// run-pass
22
fn main() {
3-
&&[()][0];
3+
let _ = &&[()][0];
44
println!("{:?}", &[(),()][1]);
55
}

src/test/ui/issues/issue-5280.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ trait FontTableTagConversions {
99

1010
impl FontTableTagConversions for FontTableTag {
1111
fn tag_to_string(self) {
12-
&self;
12+
let _ = &self;
1313
}
1414
}
1515

src/test/ui/issues/issue-54696.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
fn main() {
44
// We shouldn't promote this
5-
&(main as fn() == main as fn());
5+
let _ = &(main as fn() == main as fn());
66
// Also check nested case
7-
&(&(main as fn()) == &(main as fn()));
7+
let _ = &(&(main as fn()) == &(main as fn()));
88
}

src/test/ui/lint/unused-borrows.rs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#![deny(unused_must_use)]
2+
3+
fn foo(_: i32) -> bool { todo!() }
4+
5+
fn bar() -> &'static i32 {
6+
&42;
7+
//~^ unused
8+
9+
&mut foo(42);
10+
//~^ unused
11+
12+
&&42;
13+
//~^ unused
14+
15+
&&mut 42;
16+
//~^ unused
17+
18+
&mut &42;
19+
//~^ unused
20+
21+
let _result = foo(4)
22+
&& foo(2); // Misplaced semi-colon (perhaps due to reordering of lines)
23+
&& foo(42);
24+
//~^ unused
25+
26+
let _ = &42; // ok
27+
28+
&42 // ok
29+
}
30+
31+
fn main() {
32+
let _ = bar();
33+
}
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
error: unused borrow that must be used
2+
--> $DIR/unused-borrows.rs:6:5
3+
|
4+
LL | &42;
5+
| ^^^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/unused-borrows.rs:1:9
9+
|
10+
LL | #![deny(unused_must_use)]
11+
| ^^^^^^^^^^^^^^^
12+
13+
error: unused borrow that must be used
14+
--> $DIR/unused-borrows.rs:9:5
15+
|
16+
LL | &mut foo(42);
17+
| ^^^^^^^^^^^^
18+
19+
error: unused borrow that must be used
20+
--> $DIR/unused-borrows.rs:12:5
21+
|
22+
LL | &&42;
23+
| ^^^^
24+
25+
error: unused borrow that must be used
26+
--> $DIR/unused-borrows.rs:15:5
27+
|
28+
LL | &&mut 42;
29+
| ^^^^^^^^
30+
31+
error: unused borrow that must be used
32+
--> $DIR/unused-borrows.rs:18:5
33+
|
34+
LL | &mut &42;
35+
| ^^^^^^^^
36+
37+
error: unused borrow that must be used
38+
--> $DIR/unused-borrows.rs:23:9
39+
|
40+
LL | && foo(42);
41+
| ^^^^^^^^^^
42+
43+
error: aborting due to 6 previous errors
44+

0 commit comments

Comments
 (0)