Skip to content

Commit f90c445

Browse files
committed
Modify spans of expanded expression
Modify the spans used for `for`-loop expression expansion, instead of creating a new span during error creation.
1 parent 3a530ba commit f90c445

File tree

6 files changed

+38
-58
lines changed

6 files changed

+38
-58
lines changed

src/librustc/hir/lowering.rs

+23-23
Original file line numberDiff line numberDiff line change
@@ -3021,7 +3021,7 @@ impl<'a> LoweringContext<'a> {
30213021

30223022
// `match <sub_expr> { ... }`
30233023
let arms = hir_vec![pat_arm, break_arm];
3024-
let match_expr = self.expr(e.span,
3024+
let match_expr = self.expr(sub_expr.span,
30253025
hir::ExprMatch(sub_expr,
30263026
arms,
30273027
hir::MatchSource::WhileLetDesugar),
@@ -3059,24 +3059,25 @@ impl<'a> LoweringContext<'a> {
30593059

30603060
// expand <head>
30613061
let head = self.lower_expr(head);
3062+
let head_sp = head.span;
30623063

30633064
let iter = self.str_to_ident("iter");
30643065

30653066
let next_ident = self.str_to_ident("__next");
3066-
let next_pat = self.pat_ident_binding_mode(e.span,
3067+
let next_pat = self.pat_ident_binding_mode(pat.span,
30673068
next_ident,
30683069
hir::BindingAnnotation::Mutable);
30693070

30703071
// `::std::option::Option::Some(val) => next = val`
30713072
let pat_arm = {
30723073
let val_ident = self.str_to_ident("val");
3073-
let val_pat = self.pat_ident(e.span, val_ident);
3074-
let val_expr = P(self.expr_ident(e.span, val_ident, val_pat.id));
3075-
let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));
3076-
let assign = P(self.expr(e.span,
3074+
let val_pat = self.pat_ident(pat.span, val_ident);
3075+
let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat.id));
3076+
let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat.id));
3077+
let assign = P(self.expr(pat.span,
30773078
hir::ExprAssign(next_expr, val_expr),
30783079
ThinVec::new()));
3079-
let some_pat = self.pat_some(e.span, val_pat);
3080+
let some_pat = self.pat_some(pat.span, val_pat);
30803081
self.arm(hir_vec![some_pat], assign)
30813082
};
30823083

@@ -3089,46 +3090,45 @@ impl<'a> LoweringContext<'a> {
30893090
};
30903091

30913092
// `mut iter`
3092-
let iter_pat = self.pat_ident_binding_mode(e.span,
3093+
let iter_pat = self.pat_ident_binding_mode(head_sp,
30933094
iter,
30943095
hir::BindingAnnotation::Mutable);
30953096

30963097
// `match ::std::iter::Iterator::next(&mut iter) { ... }`
30973098
let match_expr = {
3098-
let iter = P(self.expr_ident(e.span, iter, iter_pat.id));
3099-
let ref_mut_iter = self.expr_mut_addr_of(e.span, iter);
3099+
let iter = P(self.expr_ident(head_sp, iter, iter_pat.id));
3100+
let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
31003101
let next_path = &["iter", "Iterator", "next"];
3101-
let next_path = P(self.expr_std_path(e.span, next_path, ThinVec::new()));
3102-
let next_expr = P(self.expr_call(e.span, next_path,
3102+
let next_path = P(self.expr_std_path(head_sp, next_path, ThinVec::new()));
3103+
let next_expr = P(self.expr_call(head_sp, next_path,
31033104
hir_vec![ref_mut_iter]));
31043105
let arms = hir_vec![pat_arm, break_arm];
31053106

3106-
P(self.expr(e.span,
3107+
P(self.expr(head_sp,
31073108
hir::ExprMatch(next_expr, arms,
31083109
hir::MatchSource::ForLoopDesugar),
31093110
ThinVec::new()))
31103111
};
3111-
let match_stmt = respan(e.span, hir::StmtExpr(match_expr, self.next_id().node_id));
3112+
let match_stmt = respan(head_sp, hir::StmtExpr(match_expr, self.next_id().node_id));
31123113

3113-
let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));
3114+
let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id));
31143115

31153116
// `let mut __next`
3116-
let next_let = self.stmt_let_pat(e.span,
3117+
let next_let = self.stmt_let_pat(head_sp,
31173118
None,
31183119
next_pat,
31193120
hir::LocalSource::ForLoopDesugar);
31203121

31213122
// `let <pat> = __next`
31223123
let pat = self.lower_pat(pat);
3123-
let pat_let = self.stmt_let_pat(e.span,
3124+
let pat_let = self.stmt_let_pat(head_sp,
31243125
Some(next_expr),
31253126
pat,
31263127
hir::LocalSource::ForLoopDesugar);
31273128

3128-
let body_block = self.with_loop_scope(e.id,
3129-
|this| this.lower_block(body, false));
3129+
let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
31303130
let body_expr = P(self.expr_block(body_block, ThinVec::new()));
3131-
let body_stmt = respan(e.span, hir::StmtExpr(body_expr, self.next_id().node_id));
3131+
let body_stmt = respan(body.span, hir::StmtExpr(body_expr, self.next_id().node_id));
31323132

31333133
let loop_block = P(self.block_all(e.span,
31343134
hir_vec![next_let,
@@ -3155,12 +3155,12 @@ impl<'a> LoweringContext<'a> {
31553155
// `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
31563156
let into_iter_expr = {
31573157
let into_iter_path = &["iter", "IntoIterator", "into_iter"];
3158-
let into_iter = P(self.expr_std_path(e.span, into_iter_path,
3158+
let into_iter = P(self.expr_std_path(head_sp, into_iter_path,
31593159
ThinVec::new()));
3160-
P(self.expr_call(e.span, into_iter, hir_vec![head]))
3160+
P(self.expr_call(head_sp, into_iter, hir_vec![head]))
31613161
};
31623162

3163-
let match_expr = P(self.expr_match(e.span,
3163+
let match_expr = P(self.expr_match(head_sp,
31643164
into_iter_expr,
31653165
hir_vec![iter_arm],
31663166
hir::MatchSource::ForLoopDesugar));

src/librustc/traits/error_reporting.rs

-18
Original file line numberDiff line numberDiff line change
@@ -551,24 +551,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
551551
let OnUnimplementedNote { message, label }
552552
= self.on_unimplemented_note(trait_ref, obligation);
553553
let have_alt_message = message.is_some() || label.is_some();
554-
let span = match self.tcx.sess.codemap().span_to_snippet(span) {
555-
Ok(ref s) if s.starts_with("for ") => {
556-
// On for loops, this error is caused by the element being iterated
557-
// on, but the span points at the entire for loop. Instead of:
558-
//
559-
// / for c in "asdf" {
560-
// | ...
561-
// | }
562-
// |_^ `&str` is not an iterator
563-
//
564-
// lets point at:
565-
//
566-
// for c in "asdf" {
567-
// ^^^^^^^^^^^^^^^ `&str` is not an iterator
568-
self.tcx.sess.codemap().span_until_char(span, '{')
569-
}
570-
_ => span,
571-
};
572554

573555
let mut err = struct_span_err!(
574556
self.tcx.sess,

src/test/compile-fail/issue-20605.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
fn changer<'a>(mut things: Box<Iterator<Item=&'a mut u8>>) {
1212
for item in *things { *item = 0 }
13-
//~^ ERROR `std::iter::Iterator<Item=&mut u8>: std::marker::Sized` is not satisfied
13+
//~^ ERROR the trait bound `std::iter::Iterator<Item=&mut u8>: std::marker::Sized` is not satisfied
1414
}
1515

1616
fn main() {}

src/test/ui/const-fn-error.stderr

+10-12
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,20 @@ error[E0016]: blocks in constant functions are limited to items and tail express
1313
| ^
1414

1515
error[E0015]: calls in constant functions are limited to constant functions, struct and enum constructors
16-
--> $DIR/const-fn-error.rs:17:5
16+
--> $DIR/const-fn-error.rs:17:14
1717
|
18-
17 | / for i in 0..x { //~ ERROR calls in constant functions
19-
18 | | //~| ERROR constant function contains unimplemented
20-
19 | | sum += i;
21-
20 | | }
22-
| |_____^
18+
17 | for i in 0..x { //~ ERROR calls in constant functions
19+
| ^^^^
20+
| |
21+
| in this macro invocation
2322

2423
error[E0019]: constant function contains unimplemented expression type
25-
--> $DIR/const-fn-error.rs:17:5
24+
--> $DIR/const-fn-error.rs:17:14
2625
|
27-
17 | / for i in 0..x { //~ ERROR calls in constant functions
28-
18 | | //~| ERROR constant function contains unimplemented
29-
19 | | sum += i;
30-
20 | | }
31-
| |_____^
26+
17 | for i in 0..x { //~ ERROR calls in constant functions
27+
| ^^^^
28+
| |
29+
| in this macro invocation
3230

3331
error[E0080]: constant evaluation error
3432
--> $DIR/const-fn-error.rs:21:5

src/test/ui/issue-33941.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _,
88
found type `&_`
99

1010
error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`
11-
--> $DIR/issue-33941.rs:14:5
11+
--> $DIR/issue-33941.rs:14:14
1212
|
1313
14 | for _ in HashMap::new().iter().cloned() {} //~ ERROR type mismatch
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference
1515
|
1616
= note: expected type `(&_, &_)`
1717
found type `&_`

src/test/ui/suggestions/for-c-in-str.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied
2-
--> $DIR/for-c-in-str.rs:14:5
2+
--> $DIR/for-c-in-str.rs:14:14
33
|
44
14 | for c in "asdf" {
5-
| ^^^^^^^^^^^^^^^ `&str` is not an iterator; maybe try calling `.iter()` or a similar method
5+
| ^^^^^^ `&str` is not an iterator; maybe try calling `.iter()` or a similar method
66
|
77
= help: the trait `std::iter::Iterator` is not implemented for `&str`
88
= note: required by `std::iter::IntoIterator::into_iter`

0 commit comments

Comments
 (0)