Skip to content

Commit 257f5ad

Browse files
authored
Rollup merge of #88578 - notriddle:notriddle/suggest-add-reference-to-for-loop-iter, r=nagisa
fix(rustc): suggest `items` be borrowed in `for i in items[x..]` Fixes #87994
2 parents dc003dd + d6ff916 commit 257f5ad

File tree

4 files changed

+105
-6
lines changed

4 files changed

+105
-6
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_middle::ty::{
2323
use rustc_middle::ty::{TypeAndMut, TypeckResults};
2424
use rustc_span::def_id::LOCAL_CRATE;
2525
use rustc_span::symbol::{kw, sym, Ident, Symbol};
26-
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
26+
use rustc_span::{BytePos, DesugaringKind, ExpnKind, ForLoopLoc, MultiSpan, Span, DUMMY_SP};
2727
use rustc_target::spec::abi;
2828
use std::fmt;
2929

@@ -680,7 +680,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
680680
points_at_arg: bool,
681681
has_custom_message: bool,
682682
) -> bool {
683-
if !points_at_arg {
683+
let span = obligation.cause.span;
684+
let points_at_for_iter = matches!(
685+
span.ctxt().outer_expn_data().kind,
686+
ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter))
687+
);
688+
689+
if !points_at_arg && !points_at_for_iter {
684690
return false;
685691
}
686692

@@ -695,7 +701,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
695701

696702
never_suggest_borrow.push(self.tcx.get_diagnostic_item(sym::send_trait).unwrap());
697703

698-
let span = obligation.cause.span;
699704
let param_env = obligation.param_env;
700705
let trait_ref = trait_ref.skip_binder();
701706

@@ -754,7 +759,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
754759
);
755760

756761
// This if is to prevent a special edge-case
757-
if !span.from_expansion() {
762+
if matches!(
763+
span.ctxt().outer_expn_data().kind,
764+
ExpnKind::Root
765+
| ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter))
766+
) {
758767
// We don't want a borrowing suggestion on the fields in structs,
759768
// ```
760769
// struct Foo {

src/test/ui/issues/issue-20605.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ error[E0277]: the size for values of type `dyn Iterator<Item = &'a mut u8>` cann
22
--> $DIR/issue-20605.rs:2:17
33
|
44
LL | for item in *things { *item = 0 }
5-
| ^^^^^^^ doesn't have a size known at compile-time
5+
| ^^^^^^^
6+
| |
7+
| expected an implementor of trait `IntoIterator`
8+
| help: consider mutably borrowing here: `&mut *things`
69
|
7-
= help: the trait `Sized` is not implemented for `dyn Iterator<Item = &'a mut u8>`
10+
= note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
811
= note: required because of the requirements on the impl of `IntoIterator` for `dyn Iterator<Item = &'a mut u8>`
912
note: required by `into_iter`
1013
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
fn main() {
2+
let v = vec![1i32, 2, 3];
3+
for _ in v[1..] {
4+
//~^ ERROR [i32]` is not an iterator [E0277]
5+
//~^^ ERROR known at compilation time
6+
}
7+
struct K {
8+
n: i32,
9+
}
10+
let mut v2 = vec![K { n: 1 }, K { n: 1 }, K { n: 1 }];
11+
for i2 in v2[1..] {
12+
//~^ ERROR [K]` is not an iterator [E0277]
13+
//~^^ ERROR known at compilation time
14+
i2.n = 2;
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
2+
--> $DIR/slice-issue-87994.rs:3:12
3+
|
4+
LL | for _ in v[1..] {
5+
| ^^^^^^
6+
| |
7+
| expected an implementor of trait `IntoIterator`
8+
| help: consider borrowing here: `&v[1..]`
9+
|
10+
= note: the trait bound `[i32]: IntoIterator` is not satisfied
11+
= note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
12+
note: required by `into_iter`
13+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
14+
|
15+
LL | fn into_iter(self) -> Self::IntoIter;
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
18+
error[E0277]: `[i32]` is not an iterator
19+
--> $DIR/slice-issue-87994.rs:3:12
20+
|
21+
LL | for _ in v[1..] {
22+
| ^^^^^^
23+
| |
24+
| expected an implementor of trait `IntoIterator`
25+
| help: consider borrowing here: `&v[1..]`
26+
|
27+
= note: the trait bound `[i32]: IntoIterator` is not satisfied
28+
= note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
29+
note: required by `into_iter`
30+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
31+
|
32+
LL | fn into_iter(self) -> Self::IntoIter;
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34+
35+
error[E0277]: the size for values of type `[K]` cannot be known at compilation time
36+
--> $DIR/slice-issue-87994.rs:11:13
37+
|
38+
LL | for i2 in v2[1..] {
39+
| ^^^^^^^
40+
| |
41+
| expected an implementor of trait `IntoIterator`
42+
| help: consider borrowing here: `&v2[1..]`
43+
|
44+
= note: the trait bound `[K]: IntoIterator` is not satisfied
45+
= note: required because of the requirements on the impl of `IntoIterator` for `[K]`
46+
note: required by `into_iter`
47+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
48+
|
49+
LL | fn into_iter(self) -> Self::IntoIter;
50+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
51+
52+
error[E0277]: `[K]` is not an iterator
53+
--> $DIR/slice-issue-87994.rs:11:13
54+
|
55+
LL | for i2 in v2[1..] {
56+
| ^^^^^^^
57+
| |
58+
| expected an implementor of trait `IntoIterator`
59+
| help: consider borrowing here: `&v2[1..]`
60+
|
61+
= note: the trait bound `[K]: IntoIterator` is not satisfied
62+
= note: required because of the requirements on the impl of `IntoIterator` for `[K]`
63+
note: required by `into_iter`
64+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
65+
|
66+
LL | fn into_iter(self) -> Self::IntoIter;
67+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
68+
69+
error: aborting due to 4 previous errors
70+
71+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)