Skip to content

Commit a4ec575

Browse files
committed
Use structured suggestion for bad Fn traits
1 parent fef3c8f commit a4ec575

File tree

5 files changed

+34
-18
lines changed

5 files changed

+34
-18
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::hir::{self, GenericArg, GenericArgs, ExprKind};
77
use crate::hir::def::{CtorOf, Res, DefKind};
88
use crate::hir::def_id::DefId;
99
use crate::hir::HirVec;
10+
use crate::hir::print;
1011
use crate::hir::ptr::P;
1112
use crate::lint;
1213
use crate::middle::lang_items::SizedTraitLangItem;
@@ -981,19 +982,41 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
981982
trait_segment.generic_args().parenthesized != trait_def.paren_sugar
982983
{
983984
// For now, require that parenthetical notation be used only with `Fn()` etc.
984-
let (msg, help) = if trait_def.paren_sugar {
985+
let (msg, sugg) = if trait_def.paren_sugar {
985986
(
986987
"the precise format of `Fn`-family traits' type parameters is subject to \
987988
change",
988-
Some("use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`"),
989+
Some(format!(
990+
"{}{} -> {}",
991+
trait_segment.ident,
992+
trait_segment.args.as_ref()
993+
.and_then(|args| args.args.get(0))
994+
.and_then(|arg| match arg {
995+
hir::GenericArg::Type(ty) => {
996+
Some(print::to_string(print::NO_ANN, |s| s.print_type(ty)))
997+
}
998+
_ => None,
999+
})
1000+
.unwrap_or_else(|| "()".to_string()),
1001+
trait_segment.generic_args().bindings.iter()
1002+
.filter_map(|b| match (b.ident.as_str() == "Output", &b.kind) {
1003+
(true, hir::TypeBindingKind::Equality { ty }) => {
1004+
Some(print::to_string(print::NO_ANN, |s| s.print_type(ty)))
1005+
}
1006+
_ => None,
1007+
})
1008+
.next()
1009+
.unwrap_or_else(|| "()".to_string()),
1010+
)),
9891011
)
9901012
} else {
9911013
("parenthetical notation is only stable when used with `Fn`-family traits", None)
9921014
};
9931015
let sess = &self.tcx().sess.parse_sess;
9941016
let mut err = feature_err(sess, sym::unboxed_closures, span, msg);
995-
if let Some(help) = help {
996-
err.help(help);
1017+
if let Some(sugg) = sugg {
1018+
let msg = "use parenthetical notation instead";
1019+
err.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect);
9971020
}
9981021
err.emit();
9991022
}

src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,10 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
3838
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:9:6
3939
|
4040
LL | impl Fn<()> for Foo {
41-
| ^^^^^^
41+
| ^^^^^^ help: use parenthetical notation instead: `Fn() -> ()`
4242
|
4343
= note: for more information, see https://github.com/rust-lang/rust/issues/29625
4444
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
45-
= help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
4645

4746
error[E0229]: associated type bindings are not allowed here
4847
--> $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
5453
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:21:6
5554
|
5655
LL | impl FnMut<()> for Bar {
57-
| ^^^^^^^^^
56+
| ^^^^^^^^^ help: use parenthetical notation instead: `FnMut() -> ()`
5857
|
5958
= note: for more information, see https://github.com/rust-lang/rust/issues/29625
6059
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
61-
= help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
6260

6361
error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
6462
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:27:6
6563
|
6664
LL | impl FnOnce<()> for Baz {
67-
| ^^^^^^^^^^
65+
| ^^^^^^^^^^ help: use parenthetical notation instead: `FnOnce() -> ()`
6866
|
6967
= note: for more information, see https://github.com/rust-lang/rust/issues/29625
7068
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
71-
= help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
7269

7370
error: aborting due to 8 previous errors
7471

src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
1111
--> $DIR/feature-gate-unboxed-closures.rs:5:6
1212
|
1313
LL | impl FnOnce<(u32, u32)> for Test {
14-
| ^^^^^^^^^^^^^^^^^^
14+
| ^^^^^^^^^^^^^^^^^^ help: use parenthetical notation instead: `FnOnce(u32, u32) -> ()`
1515
|
1616
= note: for more information, see https://github.com/rust-lang/rust/issues/29625
1717
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
18-
= help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
1918

2019
error: aborting due to 2 previous errors
2120

src/test/ui/issues/issue-23024.stderr

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
22
--> $DIR/issue-23024.rs:9:39
33
|
44
LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3));
5-
| ^^
5+
| ^^ help: use parenthetical notation instead: `Fn() -> ()`
66
|
77
= note: for more information, see https://github.com/rust-lang/rust/issues/29625
88
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
9-
= help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
109

1110
error[E0107]: wrong number of type arguments: expected 1, found 0
1211
--> $DIR/issue-23024.rs:9:39

src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,19 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
22
--> $DIR/unboxed-closure-sugar-not-used-on-fn.rs:3:17
33
|
44
LL | fn bar1(x: &dyn Fn<(), Output=()>) {
5-
| ^^
5+
| ^^ help: use parenthetical notation instead: `Fn() -> ()`
66
|
77
= note: for more information, see https://github.com/rust-lang/rust/issues/29625
88
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
9-
= help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
109

1110
error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
1211
--> $DIR/unboxed-closure-sugar-not-used-on-fn.rs:7:28
1312
|
1413
LL | fn bar2<T>(x: &T) where T: Fn<()> {
15-
| ^^
14+
| ^^ help: use parenthetical notation instead: `Fn() -> ()`
1615
|
1716
= note: for more information, see https://github.com/rust-lang/rust/issues/29625
1817
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
19-
= help: use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`
2018

2119
error: aborting due to 2 previous errors
2220

0 commit comments

Comments
 (0)