about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-12-13 08:22:58 -0800
committerEsteban Küber <esteban@kuber.com.ar>2019-12-24 22:17:29 -0800
commit8d316a5a67f3039f2437c4bc284d6f954e1d6806 (patch)
tree6bf5874584329ed7e057f528177892ff71aa5e37
parent66ea471f9d4a14e5af72e86ee7b12ed9d9fa3ca5 (diff)
downloadrust-8d316a5a67f3039f2437c4bc284d6f954e1d6806.tar.gz
rust-8d316a5a67f3039f2437c4bc284d6f954e1d6806.zip
Use structured suggestion for bad `Fn` traits
-rw-r--r--src/librustc_typeck/astconv.rs39
-rw-r--r--src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr9
-rw-r--r--src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr3
-rw-r--r--src/test/ui/issues/issue-23024.stderr3
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr6
5 files changed, 40 insertions, 20 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index f9854aee979..07b2f2c47a2 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -4,9 +4,9 @@
 
 use crate::hir::def::{CtorOf, DefKind, Res};
 use crate::hir::def_id::DefId;
+use crate::hir::print;
 use crate::hir::ptr::P;
-use crate::hir::HirVec;
-use crate::hir::{self, ExprKind, GenericArg, GenericArgs};
+use crate::hir::{self, ExprKind, GenericArg, GenericArgs, HirVec};
 use crate::lint;
 use crate::middle::lang_items::SizedTraitLangItem;
 use crate::middle::resolve_lifetime as rl;
@@ -1025,19 +1025,46 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             && trait_segment.generic_args().parenthesized != trait_def.paren_sugar
         {
             // For now, require that parenthetical notation be used only with `Fn()` etc.
-            let (msg, help) = if trait_def.paren_sugar {
+            let (msg, sugg) = if trait_def.paren_sugar {
                 (
                     "the precise format of `Fn`-family traits' type parameters is subject to \
                      change",
-                    Some("use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`"),
+                    Some(format!(
+                        "{}{} -> {}",
+                        trait_segment.ident,
+                        trait_segment
+                            .args
+                            .as_ref()
+                            .and_then(|args| args.args.get(0))
+                            .and_then(|arg| match arg {
+                                hir::GenericArg::Type(ty) => {
+                                    Some(print::to_string(print::NO_ANN, |s| s.print_type(ty)))
+                                }
+                                _ => None,
+                            })
+                            .unwrap_or_else(|| "()".to_string()),
+                        trait_segment
+                            .generic_args()
+                            .bindings
+                            .iter()
+                            .filter_map(|b| match (b.ident.as_str() == "Output", &b.kind) {
+                                (true, hir::TypeBindingKind::Equality { ty }) => {
+                                    Some(print::to_string(print::NO_ANN, |s| s.print_type(ty)))
+                                }
+                                _ => None,
+                            })
+                            .next()
+                            .unwrap_or_else(|| "()".to_string()),
+                    )),
                 )
             } else {
                 ("parenthetical notation is only stable when used with `Fn`-family traits", None)
             };
             let sess = &self.tcx().sess.parse_sess;
             let mut err = feature_err(sess, sym::unboxed_closures, span, msg);
-            if let Some(help) = help {
-                err.help(help);
+            if let Some(sugg) = sugg {
+                let msg = "use parenthetical notation instead";
+                err.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect);
             }
             err.emit();
         }
diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
index 48230dc035b..4addd16649e 100644
--- a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
+++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
@@ -38,11 +38,10 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:9:6
    |
 LL | impl Fn<()> for Foo {
-   |      ^^^^^^
+   |      ^^^^^^ help: use parenthetical notation instead: `Fn() -> ()`
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-   = help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
 
 error[E0229]: associated type bindings are not allowed here
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:15:6
@@ -54,21 +53,19 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:21:6
    |
 LL | impl FnMut<()> for Bar {
-   |      ^^^^^^^^^
+   |      ^^^^^^^^^ help: use parenthetical notation instead: `FnMut() -> ()`
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-   = help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
 
 error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:27:6
    |
 LL | impl FnOnce<()> for Baz {
-   |      ^^^^^^^^^^
+   |      ^^^^^^^^^^ help: use parenthetical notation instead: `FnOnce() -> ()`
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-   = help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr
index 67814a5d016..005ff06e688 100644
--- a/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr
+++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr
@@ -11,11 +11,10 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
   --> $DIR/feature-gate-unboxed-closures.rs:5:6
    |
 LL | impl FnOnce<(u32, u32)> for Test {
-   |      ^^^^^^^^^^^^^^^^^^
+   |      ^^^^^^^^^^^^^^^^^^ help: use parenthetical notation instead: `FnOnce(u32, u32) -> ()`
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-   = help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr
index 11d5c9f1f2e..1c6dd28ce53 100644
--- a/src/test/ui/issues/issue-23024.stderr
+++ b/src/test/ui/issues/issue-23024.stderr
@@ -2,11 +2,10 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
   --> $DIR/issue-23024.rs:9:39
    |
 LL |     println!("{:?}",(vfnfer[0] as dyn Fn)(3));
-   |                                       ^^
+   |                                       ^^ help: use parenthetical notation instead: `Fn() -> ()`
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-   = help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
 
 error[E0107]: wrong number of type arguments: expected 1, found 0
   --> $DIR/issue-23024.rs:9:39
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr
index d661603465c..ba9d984e703 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr
@@ -2,21 +2,19 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
   --> $DIR/unboxed-closure-sugar-not-used-on-fn.rs:3:17
    |
 LL | fn bar1(x: &dyn Fn<(), Output=()>) {
-   |                 ^^
+   |                 ^^ help: use parenthetical notation instead: `Fn() -> ()`
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-   = help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
 
 error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
   --> $DIR/unboxed-closure-sugar-not-used-on-fn.rs:7:28
    |
 LL | fn bar2<T>(x: &T) where T: Fn<()> {
-   |                            ^^
+   |                            ^^ help: use parenthetical notation instead: `Fn() -> ()`
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-   = help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
 
 error: aborting due to 2 previous errors