Skip to content

Commit c87bb27

Browse files
committed
Adjust spans into the for loops context before creating the pattern and into_iter call spans.
1 parent f5711a5 commit c87bb27

File tree

5 files changed

+99
-5
lines changed

5 files changed

+99
-5
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,8 +1771,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
17711771
let pat = self.lower_pat(pat);
17721772
let for_span =
17731773
self.mark_span_with_reason(DesugaringKind::ForLoop, self.lower_span(e.span), None);
1774-
let head_span = self.mark_span_with_reason(DesugaringKind::ForLoop, head.span, None);
1775-
let pat_span = self.mark_span_with_reason(DesugaringKind::ForLoop, pat.span, None);
1774+
let for_ctxt = for_span.ctxt();
1775+
1776+
// Try to point both the head and pat spans to their position in the for loop
1777+
// rather than inside a macro.
1778+
let head_span =
1779+
// self.mark_span_with_reason(DesugaringKind::ForLoop, head.span.find_ancestor_in_same_ctxt(e.span).unwrap_or(head.span), None);
1780+
head.span.find_ancestor_in_same_ctxt(e.span).unwrap_or(head.span).with_ctxt(for_ctxt);
1781+
let pat_span =
1782+
pat.span.find_ancestor_in_same_ctxt(e.span).unwrap_or(pat.span).with_ctxt(for_ctxt);
17761783

17771784
let loop_hir_id = self.lower_node_id(e.id);
17781785
let label = self.lower_label(opt_label, e.id, loop_hir_id);

tests/ui/for/iter_from_mac_call.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
macro_rules! deref {
2+
($e:expr) => { *$e };
3+
}
4+
5+
fn f1<'a>(mut iter: Box<dyn Iterator<Item=&'a mut u8>>) {
6+
for item in deref!(iter) { *item = 0 }
7+
//~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
8+
}
9+
10+
fn f2(x: &mut i32) {
11+
for _item in deref!(x) {}
12+
//~^ ERROR `i32` is not an iterator
13+
}
14+
15+
struct Wrapped(i32);
16+
17+
macro_rules! borrow_deref {
18+
($e:expr) => { &mut *$e };
19+
}
20+
21+
fn f3<'a>(mut iter: Box<dyn Iterator<Item=&'a mut i32>>) {
22+
for Wrapped(item) in borrow_deref!(iter) { *item = 0 }
23+
//~^ ERROR mismatched types
24+
}
25+
26+
fn main() {}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator
2+
--> $DIR/iter_from_mac_call.rs:6:17
3+
|
4+
LL | for item in deref!(iter) { *item = 0 }
5+
| ^^^^^^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
6+
|
7+
= note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
8+
= note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`
9+
help: consider mutably borrowing here
10+
|
11+
LL | for item in &mut deref!(iter) { *item = 0 }
12+
| ++++
13+
14+
error[E0277]: `i32` is not an iterator
15+
--> $DIR/iter_from_mac_call.rs:11:18
16+
|
17+
LL | for _item in deref!(x) {}
18+
| ^^^^^^^^^ `i32` is not an iterator
19+
|
20+
= help: the trait `Iterator` is not implemented for `i32`
21+
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
22+
= note: required for `i32` to implement `IntoIterator`
23+
24+
error[E0308]: mismatched types
25+
--> $DIR/iter_from_mac_call.rs:22:9
26+
|
27+
LL | for Wrapped(item) in borrow_deref!(iter) { *item = 0 }
28+
| ^^^^^^^^^^^^^ ------------------- this is an iterator with items of type `&mut i32`
29+
| |
30+
| expected `i32`, found `Wrapped`
31+
32+
error: aborting due to 3 previous errors
33+
34+
Some errors have detailed explanations: E0277, E0308.
35+
For more information about an error, try `rustc --explain E0277`.

tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ fn main() {
66
for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
77
//~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
88
//~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
9+
//~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
910
eprintln!("{} {}", src, dest);
1011
}
1112

1213
// don't suggest add `variant.iter().clone().clone()`
1314
for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
1415
//~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
1516
//~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
17+
//~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
1618
eprintln!("{} {}", src, dest);
1719
}
1820
}

tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>`
3030
= note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info)
3131

3232
error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
33-
--> $DIR/invalid-suggest-deref-issue-127590.rs:13:54
33+
--> $DIR/invalid-suggest-deref-issue-127590.rs:14:54
3434
|
3535
LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
3636
| -------------- ^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
@@ -48,7 +48,7 @@ LL + for (src, dest) in std::iter::zip(fields.iter(), variant.iter().clone()
4848
|
4949

5050
error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
51-
--> $DIR/invalid-suggest-deref-issue-127590.rs:13:24
51+
--> $DIR/invalid-suggest-deref-issue-127590.rs:14:24
5252
|
5353
LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
5454
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
@@ -60,6 +60,30 @@ help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>`
6060
= note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
6161
= note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info)
6262

63-
error: aborting due to 4 previous errors
63+
error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
64+
--> $DIR/invalid-suggest-deref-issue-127590.rs:6:24
65+
|
66+
LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
67+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
68+
|
69+
= help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`
70+
help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>`
71+
--> $SRC_DIR/core/src/slice/iter.rs:LL:COL
72+
= note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator`
73+
= note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info)
74+
75+
error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
76+
--> $DIR/invalid-suggest-deref-issue-127590.rs:14:24
77+
|
78+
LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
79+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
80+
|
81+
= help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`
82+
help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>`
83+
--> $SRC_DIR/core/src/slice/iter.rs:LL:COL
84+
= note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator`
85+
= note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info)
86+
87+
error: aborting due to 6 previous errors
6488

6589
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)