Skip to content

Commit 8d316a5

Browse files
committed
Use structured suggestion for bad Fn traits
1 parent 66ea471 commit 8d316a5

File tree

5 files changed

+40
-20
lines changed

5 files changed

+40
-20
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
55
use crate::hir::def::{CtorOf, DefKind, Res};
66
use crate::hir::def_id::DefId;
7+
use crate::hir::print;
78
use crate::hir::ptr::P;
8-
use crate::hir::HirVec;
9-
use crate::hir::{self, ExprKind, GenericArg, GenericArgs};
9+
use crate::hir::{self, ExprKind, GenericArg, GenericArgs, HirVec};
1010
use crate::lint;
1111
use crate::middle::lang_items::SizedTraitLangItem;
1212
use crate::middle::resolve_lifetime as rl;
@@ -1025,19 +1025,46 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10251025
&& trait_segment.generic_args().parenthesized != trait_def.paren_sugar
10261026
{
10271027
// For now, require that parenthetical notation be used only with `Fn()` etc.
1028-
let (msg, help) = if trait_def.paren_sugar {
1028+
let (msg, sugg) = if trait_def.paren_sugar {
10291029
(
10301030
"the precise format of `Fn`-family traits' type parameters is subject to \
10311031
change",
1032-
Some("use parenthetical notation instead: `Fn(Foo, Bar) -> Baz`"),
1032+
Some(format!(
1033+
"{}{} -> {}",
1034+
trait_segment.ident,
1035+
trait_segment
1036+
.args
1037+
.as_ref()
1038+
.and_then(|args| args.args.get(0))
1039+
.and_then(|arg| match arg {
1040+
hir::GenericArg::Type(ty) => {
1041+
Some(print::to_string(print::NO_ANN, |s| s.print_type(ty)))
1042+
}
1043+
_ => None,
1044+
})
1045+
.unwrap_or_else(|| "()".to_string()),
1046+
trait_segment
1047+
.generic_args()
1048+
.bindings
1049+
.iter()
1050+
.filter_map(|b| match (b.ident.as_str() == "Output", &b.kind) {
1051+
(true, hir::TypeBindingKind::Equality { ty }) => {
1052+
Some(print::to_string(print::NO_ANN, |s| s.print_type(ty)))
1053+
}
1054+
_ => None,
1055+
})
1056+
.next()
1057+
.unwrap_or_else(|| "()".to_string()),
1058+
)),
10331059
)
10341060
} else {
10351061
("parenthetical notation is only stable when used with `Fn`-family traits", None)
10361062
};
10371063
let sess = &self.tcx().sess.parse_sess;
10381064
let mut err = feature_err(sess, sym::unboxed_closures, span, msg);
1039-
if let Some(help) = help {
1040-
err.help(help);
1065+
if let Some(sugg) = sugg {
1066+
let msg = "use parenthetical notation instead";
1067+
err.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect);
10411068
}
10421069
err.emit();
10431070
}

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)