Skip to content

Commit ed33453

Browse files
committed
Auto merge of #67524 - LukasKalbertodt:improve-into-iter-lint, r=matthewjasper
Generalize `array_into_iter` lint to also lint for boxed arrays `Box` is special in that a method call on a box can move the value out of the box. Thus, the same backwards-compatibility problem can arise for boxed arrays as for simple arrays. --- CC #66145 r? @matthewjasper (as you reviewed the first PR)
2 parents 7bc1665 + f934b83 commit ed33453

File tree

4 files changed

+140
-6
lines changed

4 files changed

+140
-6
lines changed

src/librustc_lint/array_into_iter.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,26 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIntoIter {
4444
// argument.
4545
let receiver_arg = &args[0];
4646

47-
// Test if the original `self` type is an array type.
48-
match cx.tables.expr_ty(receiver_arg).kind {
49-
ty::Array(..) => {}
50-
_ => return,
47+
// Peel all `Box<_>` layers. We have to special case `Box` here as
48+
// `Box` is the only thing that values can be moved out of via
49+
// method call. `Box::new([1]).into_iter()` should trigger this
50+
// lint.
51+
let mut recv_ty = cx.tables.expr_ty(receiver_arg);
52+
let mut num_box_derefs = 0;
53+
while recv_ty.is_box() {
54+
num_box_derefs += 1;
55+
recv_ty = recv_ty.boxed_ty();
56+
}
57+
58+
// Make sure we found an array after peeling the boxes.
59+
if !matches!(recv_ty.kind, ty::Array(..)) {
60+
return;
5161
}
5262

53-
// Make sure that the first adjustment is an autoref coercion.
54-
match cx.tables.expr_adjustments(receiver_arg).get(0) {
63+
// Make sure that there is an autoref coercion at the expected
64+
// position. The first `num_box_derefs` adjustments are the derefs
65+
// of the box.
66+
match cx.tables.expr_adjustments(receiver_arg).get(num_box_derefs) {
5567
Some(Adjustment { kind: Adjust::Borrow(_), .. }) => {}
5668
_ => return,
5769
}

src/test/ui/iterators/into-iter-on-arrays-lint.fixed

+25
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,31 @@ fn main() {
1919
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
2020
//~| WARNING this was previously accepted by the compiler but is being phased out
2121

22+
Box::new(small).iter();
23+
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
24+
//~| WARNING this was previously accepted by the compiler but is being phased out
25+
Box::new([1, 2]).iter();
26+
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
27+
//~| WARNING this was previously accepted by the compiler but is being phased out
28+
Box::new(big).iter();
29+
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
30+
//~| WARNING this was previously accepted by the compiler but is being phased out
31+
Box::new([0u8; 33]).iter();
32+
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
33+
//~| WARNING this was previously accepted by the compiler but is being phased out
34+
35+
Box::new(Box::new(small)).iter();
36+
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
37+
//~| WARNING this was previously accepted by the compiler but is being phased out
38+
Box::new(Box::new([1, 2])).iter();
39+
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
40+
//~| WARNING this was previously accepted by the compiler but is being phased out
41+
Box::new(Box::new(big)).iter();
42+
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
43+
//~| WARNING this was previously accepted by the compiler but is being phased out
44+
Box::new(Box::new([0u8; 33])).iter();
45+
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
46+
//~| WARNING this was previously accepted by the compiler but is being phased out
2247

2348
// Expressions that should not
2449
(&[1, 2]).into_iter();

src/test/ui/iterators/into-iter-on-arrays-lint.rs

+25
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,31 @@ fn main() {
1919
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
2020
//~| WARNING this was previously accepted by the compiler but is being phased out
2121

22+
Box::new(small).into_iter();
23+
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
24+
//~| WARNING this was previously accepted by the compiler but is being phased out
25+
Box::new([1, 2]).into_iter();
26+
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
27+
//~| WARNING this was previously accepted by the compiler but is being phased out
28+
Box::new(big).into_iter();
29+
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
30+
//~| WARNING this was previously accepted by the compiler but is being phased out
31+
Box::new([0u8; 33]).into_iter();
32+
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
33+
//~| WARNING this was previously accepted by the compiler but is being phased out
34+
35+
Box::new(Box::new(small)).into_iter();
36+
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
37+
//~| WARNING this was previously accepted by the compiler but is being phased out
38+
Box::new(Box::new([1, 2])).into_iter();
39+
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
40+
//~| WARNING this was previously accepted by the compiler but is being phased out
41+
Box::new(Box::new(big)).into_iter();
42+
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
43+
//~| WARNING this was previously accepted by the compiler but is being phased out
44+
Box::new(Box::new([0u8; 33])).into_iter();
45+
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
46+
//~| WARNING this was previously accepted by the compiler but is being phased out
2247

2348
// Expressions that should not
2449
(&[1, 2]).into_iter();

src/test/ui/iterators/into-iter-on-arrays-lint.stderr

+72
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,75 @@ LL | [0u8; 33].into_iter();
3535
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3636
= note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
3737

38+
warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
39+
--> $DIR/into-iter-on-arrays-lint.rs:22:21
40+
|
41+
LL | Box::new(small).into_iter();
42+
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
43+
|
44+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
45+
= note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
46+
47+
warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
48+
--> $DIR/into-iter-on-arrays-lint.rs:25:22
49+
|
50+
LL | Box::new([1, 2]).into_iter();
51+
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
52+
|
53+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
54+
= note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
55+
56+
warning: this method call currently resolves to `<&[T] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
57+
--> $DIR/into-iter-on-arrays-lint.rs:28:19
58+
|
59+
LL | Box::new(big).into_iter();
60+
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
61+
|
62+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
63+
= note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
64+
65+
warning: this method call currently resolves to `<&[T] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
66+
--> $DIR/into-iter-on-arrays-lint.rs:31:25
67+
|
68+
LL | Box::new([0u8; 33]).into_iter();
69+
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
70+
|
71+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
72+
= note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
73+
74+
warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
75+
--> $DIR/into-iter-on-arrays-lint.rs:35:31
76+
|
77+
LL | Box::new(Box::new(small)).into_iter();
78+
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
79+
|
80+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
81+
= note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
82+
83+
warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
84+
--> $DIR/into-iter-on-arrays-lint.rs:38:32
85+
|
86+
LL | Box::new(Box::new([1, 2])).into_iter();
87+
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
88+
|
89+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
90+
= note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
91+
92+
warning: this method call currently resolves to `<&[T] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
93+
--> $DIR/into-iter-on-arrays-lint.rs:41:29
94+
|
95+
LL | Box::new(Box::new(big)).into_iter();
96+
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
97+
|
98+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99+
= note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
100+
101+
warning: this method call currently resolves to `<&[T] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
102+
--> $DIR/into-iter-on-arrays-lint.rs:44:35
103+
|
104+
LL | Box::new(Box::new([0u8; 33])).into_iter();
105+
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
106+
|
107+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
108+
= note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
109+

0 commit comments

Comments
 (0)