From 0555d256dd395ff65aa4435d26de36806edb2729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 17 Dec 2017 22:22:24 -0800 Subject: [PATCH] Rework expected closure error * point at def span * add label to primary span * use `span_label`s instead of `span_note`s --- src/librustc/traits/error_reporting.rs | 10 +++++++--- .../closure_context/issue-26046-fn-mut.stderr | 19 ++++++------------- .../issue-26046-fn-once.stderr | 19 ++++++------------- ...-infer-fn-once-move-from-projection.stderr | 11 ++++------- 4 files changed, 23 insertions(+), 36 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 635921134be77..f249a6131aec4 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -647,7 +647,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap(); - let closure_span = self.tcx.hir.span_if_local(closure_def_id).unwrap(); + let closure_span = self.tcx.sess.codemap() + .def_span(self.tcx.hir.span_if_local(closure_def_id).unwrap()); let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap(); let mut err = struct_span_err!( self.tcx.sess, closure_span, E0525, @@ -656,6 +657,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { kind, found_kind); + err.span_label( + closure_span, + format!("this closure implements `{}`, not `{}`", found_kind, kind)); err.span_label( obligation.cause.span, format!("the requirement to implement `{}` derives from here", kind)); @@ -667,12 +671,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let closure_hir_id = self.tcx.hir.node_to_hir_id(node_id); match (found_kind, tables.closure_kind_origins().get(closure_hir_id)) { (ty::ClosureKind::FnOnce, Some((span, name))) => { - err.span_note(*span, &format!( + err.span_label(*span, format!( "closure is `FnOnce` because it moves the \ variable `{}` out of its environment", name)); }, (ty::ClosureKind::FnMut, Some((span, name))) => { - err.span_note(*span, &format!( + err.span_label(*span, format!( "closure is `FnMut` because it mutates the \ variable `{}` here", name)); }, diff --git a/src/test/ui/closure_context/issue-26046-fn-mut.stderr b/src/test/ui/closure_context/issue-26046-fn-mut.stderr index 82c83da4daec7..77ce1176b5cd0 100644 --- a/src/test/ui/closure_context/issue-26046-fn-mut.stderr +++ b/src/test/ui/closure_context/issue-26046-fn-mut.stderr @@ -1,20 +1,13 @@ error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut` --> $DIR/issue-26046-fn-mut.rs:14:19 | -14 | let closure = || { //~ ERROR expected a closure that - | ___________________^ -15 | | num += 1; -16 | | }; - | |_____^ -17 | -18 | Box::new(closure) - | ----------------- the requirement to implement `Fn` derives from here - | -note: closure is `FnMut` because it mutates the variable `num` here - --> $DIR/issue-26046-fn-mut.rs:15:9 - | +14 | let closure = || { //~ ERROR expected a closure that + | ^^ this closure implements `FnMut`, not `Fn` 15 | num += 1; - | ^^^ + | --- closure is `FnMut` because it mutates the variable `num` here +... +18 | Box::new(closure) + | ----------------- the requirement to implement `Fn` derives from here error: aborting due to previous error diff --git a/src/test/ui/closure_context/issue-26046-fn-once.stderr b/src/test/ui/closure_context/issue-26046-fn-once.stderr index 0bc84872dde5f..4eed4461ebafe 100644 --- a/src/test/ui/closure_context/issue-26046-fn-once.stderr +++ b/src/test/ui/closure_context/issue-26046-fn-once.stderr @@ -1,20 +1,13 @@ error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> $DIR/issue-26046-fn-once.rs:14:19 | -14 | let closure = move || { //~ ERROR expected a closure - | ___________________^ -15 | | vec -16 | | }; - | |_____^ -17 | -18 | Box::new(closure) - | ----------------- the requirement to implement `Fn` derives from here - | -note: closure is `FnOnce` because it moves the variable `vec` out of its environment - --> $DIR/issue-26046-fn-once.rs:15:9 - | +14 | let closure = move || { //~ ERROR expected a closure + | ^^^^^^^ this closure implements `FnOnce`, not `Fn` 15 | vec - | ^^^ + | --- closure is `FnOnce` because it moves the variable `vec` out of its environment +... +18 | Box::new(closure) + | ----------------- the requirement to implement `Fn` derives from here error: aborting due to previous error diff --git a/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr b/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr index d3d9ce2b34a1c..2c16c5b619a8b 100644 --- a/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr +++ b/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr @@ -2,15 +2,12 @@ error[E0525]: expected a closure that implements the `Fn` trait, but this closur --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:24:13 | 24 | let c = || drop(y.0); //~ ERROR expected a closure that implements the `Fn` trait - | ^^^^^^^^^^^^ + | ^^^^^^^^-^^^ + | | | + | | closure is `FnOnce` because it moves the variable `y` out of its environment + | this closure implements `FnOnce`, not `Fn` 25 | foo(c); | --- the requirement to implement `Fn` derives from here - | -note: closure is `FnOnce` because it moves the variable `y` out of its environment - --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:24:21 - | -24 | let c = || drop(y.0); //~ ERROR expected a closure that implements the `Fn` trait - | ^ error: aborting due to previous error