Skip to content

Commit 733bdd0

Browse files
committed
fix(rustc): suggest items be borrowed in for i in items[x..]
Fixes #87994
1 parent e3c71f1 commit 733bdd0

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
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 {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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: aborting due to 2 previous errors
36+
37+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)