diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f9854aee9790..07b2f2c47a2a 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 48230dc035b5..4addd16649ea 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 67814a5d0169..005ff06e6889 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 11d5c9f1f2e1..1c6dd28ce539 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 d661603465cc..ba9d984e7036 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(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