From f90c445637385c2526990119b3f177d809ac5459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 25 Jan 2018 14:07:45 -0800 Subject: [PATCH] Modify spans of expanded expression Modify the spans used for `for`-loop expression expansion, instead of creating a new span during error creation. --- src/librustc/hir/lowering.rs | 46 ++++++++++----------- src/librustc/traits/error_reporting.rs | 18 -------- src/test/compile-fail/issue-20605.rs | 2 +- src/test/ui/const-fn-error.stderr | 22 +++++----- src/test/ui/issue-33941.stderr | 4 +- src/test/ui/suggestions/for-c-in-str.stderr | 4 +- 6 files changed, 38 insertions(+), 58 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index a87f2747a57..8a48dca0152 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3021,7 +3021,7 @@ impl<'a> LoweringContext<'a> { // `match { ... }` let arms = hir_vec![pat_arm, break_arm]; - let match_expr = self.expr(e.span, + let match_expr = self.expr(sub_expr.span, hir::ExprMatch(sub_expr, arms, hir::MatchSource::WhileLetDesugar), @@ -3059,24 +3059,25 @@ impl<'a> LoweringContext<'a> { // expand let head = self.lower_expr(head); + let head_sp = head.span; let iter = self.str_to_ident("iter"); let next_ident = self.str_to_ident("__next"); - let next_pat = self.pat_ident_binding_mode(e.span, + let next_pat = self.pat_ident_binding_mode(pat.span, next_ident, hir::BindingAnnotation::Mutable); // `::std::option::Option::Some(val) => next = val` let pat_arm = { let val_ident = self.str_to_ident("val"); - let val_pat = self.pat_ident(e.span, val_ident); - let val_expr = P(self.expr_ident(e.span, val_ident, val_pat.id)); - let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id)); - let assign = P(self.expr(e.span, + let val_pat = self.pat_ident(pat.span, val_ident); + let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat.id)); + let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat.id)); + let assign = P(self.expr(pat.span, hir::ExprAssign(next_expr, val_expr), ThinVec::new())); - let some_pat = self.pat_some(e.span, val_pat); + let some_pat = self.pat_some(pat.span, val_pat); self.arm(hir_vec![some_pat], assign) }; @@ -3089,46 +3090,45 @@ impl<'a> LoweringContext<'a> { }; // `mut iter` - let iter_pat = self.pat_ident_binding_mode(e.span, + let iter_pat = self.pat_ident_binding_mode(head_sp, iter, hir::BindingAnnotation::Mutable); // `match ::std::iter::Iterator::next(&mut iter) { ... }` let match_expr = { - let iter = P(self.expr_ident(e.span, iter, iter_pat.id)); - let ref_mut_iter = self.expr_mut_addr_of(e.span, iter); + let iter = P(self.expr_ident(head_sp, iter, iter_pat.id)); + let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter); let next_path = &["iter", "Iterator", "next"]; - let next_path = P(self.expr_std_path(e.span, next_path, ThinVec::new())); - let next_expr = P(self.expr_call(e.span, next_path, + let next_path = P(self.expr_std_path(head_sp, next_path, ThinVec::new())); + let next_expr = P(self.expr_call(head_sp, next_path, hir_vec![ref_mut_iter])); let arms = hir_vec![pat_arm, break_arm]; - P(self.expr(e.span, + P(self.expr(head_sp, hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), ThinVec::new())) }; - let match_stmt = respan(e.span, hir::StmtExpr(match_expr, self.next_id().node_id)); + let match_stmt = respan(head_sp, hir::StmtExpr(match_expr, self.next_id().node_id)); - let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id)); + let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id)); // `let mut __next` - let next_let = self.stmt_let_pat(e.span, + let next_let = self.stmt_let_pat(head_sp, None, next_pat, hir::LocalSource::ForLoopDesugar); // `let = __next` let pat = self.lower_pat(pat); - let pat_let = self.stmt_let_pat(e.span, + let pat_let = self.stmt_let_pat(head_sp, Some(next_expr), pat, hir::LocalSource::ForLoopDesugar); - let body_block = self.with_loop_scope(e.id, - |this| this.lower_block(body, false)); + let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false)); let body_expr = P(self.expr_block(body_block, ThinVec::new())); - let body_stmt = respan(e.span, hir::StmtExpr(body_expr, self.next_id().node_id)); + let body_stmt = respan(body.span, hir::StmtExpr(body_expr, self.next_id().node_id)); let loop_block = P(self.block_all(e.span, hir_vec![next_let, @@ -3155,12 +3155,12 @@ impl<'a> LoweringContext<'a> { // `match ::std::iter::IntoIterator::into_iter() { ... }` let into_iter_expr = { let into_iter_path = &["iter", "IntoIterator", "into_iter"]; - let into_iter = P(self.expr_std_path(e.span, into_iter_path, + let into_iter = P(self.expr_std_path(head_sp, into_iter_path, ThinVec::new())); - P(self.expr_call(e.span, into_iter, hir_vec![head])) + P(self.expr_call(head_sp, into_iter, hir_vec![head])) }; - let match_expr = P(self.expr_match(e.span, + let match_expr = P(self.expr_match(head_sp, into_iter_expr, hir_vec![iter_arm], hir::MatchSource::ForLoopDesugar)); diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 61456b3b003..e649f1b49df 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -551,24 +551,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let OnUnimplementedNote { message, label } = self.on_unimplemented_note(trait_ref, obligation); let have_alt_message = message.is_some() || label.is_some(); - let span = match self.tcx.sess.codemap().span_to_snippet(span) { - Ok(ref s) if s.starts_with("for ") => { - // On for loops, this error is caused by the element being iterated - // on, but the span points at the entire for loop. Instead of: - // - // / for c in "asdf" { - // | ... - // | } - // |_^ `&str` is not an iterator - // - // lets point at: - // - // for c in "asdf" { - // ^^^^^^^^^^^^^^^ `&str` is not an iterator - self.tcx.sess.codemap().span_until_char(span, '{') - } - _ => span, - }; let mut err = struct_span_err!( self.tcx.sess, diff --git a/src/test/compile-fail/issue-20605.rs b/src/test/compile-fail/issue-20605.rs index b7c544c7848..5eb0e4360fc 100644 --- a/src/test/compile-fail/issue-20605.rs +++ b/src/test/compile-fail/issue-20605.rs @@ -10,7 +10,7 @@ fn changer<'a>(mut things: Box>) { for item in *things { *item = 0 } -//~^ ERROR `std::iter::Iterator: std::marker::Sized` is not satisfied +//~^ ERROR the trait bound `std::iter::Iterator: std::marker::Sized` is not satisfied } fn main() {} diff --git a/src/test/ui/const-fn-error.stderr b/src/test/ui/const-fn-error.stderr index 0e275e78fc6..de2a9299473 100644 --- a/src/test/ui/const-fn-error.stderr +++ b/src/test/ui/const-fn-error.stderr @@ -13,22 +13,20 @@ error[E0016]: blocks in constant functions are limited to items and tail express | ^ error[E0015]: calls in constant functions are limited to constant functions, struct and enum constructors - --> $DIR/const-fn-error.rs:17:5 + --> $DIR/const-fn-error.rs:17:14 | -17 | / for i in 0..x { //~ ERROR calls in constant functions -18 | | //~| ERROR constant function contains unimplemented -19 | | sum += i; -20 | | } - | |_____^ +17 | for i in 0..x { //~ ERROR calls in constant functions + | ^^^^ + | | + | in this macro invocation error[E0019]: constant function contains unimplemented expression type - --> $DIR/const-fn-error.rs:17:5 + --> $DIR/const-fn-error.rs:17:14 | -17 | / for i in 0..x { //~ ERROR calls in constant functions -18 | | //~| ERROR constant function contains unimplemented -19 | | sum += i; -20 | | } - | |_____^ +17 | for i in 0..x { //~ ERROR calls in constant functions + | ^^^^ + | | + | in this macro invocation error[E0080]: constant evaluation error --> $DIR/const-fn-error.rs:21:5 diff --git a/src/test/ui/issue-33941.stderr b/src/test/ui/issue-33941.stderr index 953e6fe77d7..78c9ce9a1b1 100644 --- a/src/test/ui/issue-33941.stderr +++ b/src/test/ui/issue-33941.stderr @@ -8,10 +8,10 @@ error[E0271]: type mismatch resolving ` as std::iter::Iterator>::Item == &_` - --> $DIR/issue-33941.rs:14:5 + --> $DIR/issue-33941.rs:14:14 | 14 | for _ in HashMap::new().iter().cloned() {} //~ ERROR type mismatch - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference | = note: expected type `(&_, &_)` found type `&_` diff --git a/src/test/ui/suggestions/for-c-in-str.stderr b/src/test/ui/suggestions/for-c-in-str.stderr index e99a7d7fe55..7a6dc9a5040 100644 --- a/src/test/ui/suggestions/for-c-in-str.stderr +++ b/src/test/ui/suggestions/for-c-in-str.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied - --> $DIR/for-c-in-str.rs:14:5 + --> $DIR/for-c-in-str.rs:14:14 | 14 | for c in "asdf" { - | ^^^^^^^^^^^^^^^ `&str` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^ `&str` is not an iterator; maybe try calling `.iter()` or a similar method | = help: the trait `std::iter::Iterator` is not implemented for `&str` = note: required by `std::iter::IntoIterator::into_iter`