diff options
| author | Romain Perier <romain.perier@gmail.com> | 2025-03-26 15:49:42 +0100 |
|---|---|---|
| committer | Romain Perier <romain.perier@gmail.com> | 2025-04-09 08:56:04 +0200 |
| commit | 8b6ff4a378e2df03db108bcd918a77f8a759334f (patch) | |
| tree | 910459fffbf95c8d169709be8a4bb47f5d8dba81 | |
| parent | c1b8b7e86f6ca59929ce08471d0877f748f84901 (diff) | |
| download | rust-8b6ff4a378e2df03db108bcd918a77f8a759334f.tar.gz rust-8b6ff4a378e2df03db108bcd918a77f8a759334f.zip | |
Suggest the use of `impl Trait` in function parameter only
Currently in case of a Trait object in closure parameter, the compiler suggests either to use a reference, which is correct or to use an `impl Trait` which is not. Do not emit this suggestion when the parameter is part of a closure.
3 files changed, 38 insertions, 6 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 38fcba4ea62..cfe9120a4a4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3018,12 +3018,23 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { [] => span_bug!(ty.span, "trait object with no traits: {ty:?}"), }; let needs_parens = traits.len() != 1; - err.span_suggestion_verbose( - span, - "you can use `impl Trait` as the argument type", - "impl ", - Applicability::MaybeIncorrect, - ); + // Don't recommend impl Trait as a closure argument + if let Some(hir_id) = hir_id + && matches!( + self.tcx.parent_hir_node(hir_id), + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn { .. }, + .. + }) + ) + { + err.span_suggestion_verbose( + span, + "you can use `impl Trait` as the argument type", + "impl ", + Applicability::MaybeIncorrect, + ); + } let sugg = if !needs_parens { vec![(span.shrink_to_lo(), format!("&{kw}"))] } else { diff --git a/tests/ui/traits/dont-suggest-impl-as-closure-arg.rs b/tests/ui/traits/dont-suggest-impl-as-closure-arg.rs new file mode 100644 index 00000000000..68e234b0f20 --- /dev/null +++ b/tests/ui/traits/dont-suggest-impl-as-closure-arg.rs @@ -0,0 +1,5 @@ +// Suggestion to use impl trait in closure parameter is invalid, see issue 138932 +fn main() { + let c = |f: dyn Fn()| f(); + //~^ ERROR: the size for values of type `(dyn Fn() + 'static)` cannot be known at compilation time +} diff --git a/tests/ui/traits/dont-suggest-impl-as-closure-arg.stderr b/tests/ui/traits/dont-suggest-impl-as-closure-arg.stderr new file mode 100644 index 00000000000..8218990503c --- /dev/null +++ b/tests/ui/traits/dont-suggest-impl-as-closure-arg.stderr @@ -0,0 +1,16 @@ +error[E0277]: the size for values of type `(dyn Fn() + 'static)` cannot be known at compilation time + --> $DIR/dont-suggest-impl-as-closure-arg.rs:3:17 + | +LL | let c = |f: dyn Fn()| f(); + | ^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Fn() + 'static)` + = help: unsized fn params are gated as an unstable feature +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | let c = |f: &dyn Fn()| f(); + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. |
