diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 55a05df763fe6..97f07c3cc820b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1618,7 +1618,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let trait_obj = if has_dyn { &snippet[4..] } else { &snippet }; if only_never_return { // No return paths, probably using `panic!()` or similar. - // Suggest `-> T`, `-> impl Trait`, and if `Trait` is object safe, `-> Box`. + // Suggest `-> impl Trait`, and if `Trait` is object safe, `-> Box`. suggest_trait_object_return_type_alternatives( err, ret_ty.span, @@ -2540,6 +2540,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ObligationCauseCode::SizedArgumentType(sp) => { if let Some(span) = sp { + if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() + && let ty::Clause::Trait(trait_pred) = clause + && let ty::Dynamic(..) = trait_pred.self_ty().kind() + { + let span = if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) + && snippet.starts_with("dyn ") + { + let pos = snippet.len() - snippet[3..].trim_start().len(); + span.with_hi(span.lo() + BytePos(pos as u32)) + } else { + span.shrink_to_lo() + }; + err.span_suggestion_verbose( + span, + "you can use `impl Trait` as the argument type", + "impl ".to_string(), + Applicability::MaybeIncorrect, + ); + } err.span_suggestion_verbose( span.shrink_to_lo(), "function arguments must have a statically known size, borrowed types \ @@ -3580,13 +3599,6 @@ fn suggest_trait_object_return_type_alternatives( trait_obj: &str, is_object_safe: bool, ) { - err.span_suggestion( - ret_ty, - "use some type `T` that is `T: Sized` as the return type if all return paths have the \ - same type", - "T", - Applicability::MaybeIncorrect, - ); err.span_suggestion( ret_ty, &format!( diff --git a/src/test/ui/feature-gates/feature-gate-unsized_fn_params.rs b/src/test/ui/feature-gates/feature-gate-unsized_fn_params.rs index 9b868ed7a9e93..c04e57843d4b2 100644 --- a/src/test/ui/feature-gates/feature-gate-unsized_fn_params.rs +++ b/src/test/ui/feature-gates/feature-gate-unsized_fn_params.rs @@ -1,5 +1,5 @@ +#![allow(unused, bare_trait_objects)] #[repr(align(256))] -#[allow(dead_code)] struct A { v: u8, } @@ -14,13 +14,17 @@ impl Foo for A { } } -fn foo(x: dyn Foo) { - //~^ ERROR [E0277] +fn foo(x: dyn Foo) { //~ ERROR [E0277] x.foo() } +fn bar(x: Foo) { //~ ERROR [E0277] + x.foo() +} + +fn qux(_: [()]) {} //~ ERROR [E0277] + fn main() { let x: Box = Box::new(A { v: 22 }); - foo(*x); - //~^ ERROR [E0277] + foo(*x); //~ ERROR [E0277] } diff --git a/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr b/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr index 0f7520ef7f8a9..92c71392672e1 100644 --- a/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr +++ b/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr @@ -6,13 +6,47 @@ LL | fn foo(x: dyn Foo) { | = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | fn foo(x: impl Foo) { + | ~~~~ help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo(x: &dyn Foo) { | + error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time - --> $DIR/feature-gate-unsized_fn_params.rs:24:9 + --> $DIR/feature-gate-unsized_fn_params.rs:21:8 + | +LL | fn bar(x: Foo) { + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` + = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | fn bar(x: impl Foo) { + | ++++ +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn bar(x: &Foo) { + | + + +error[E0277]: the size for values of type `[()]` cannot be known at compilation time + --> $DIR/feature-gate-unsized_fn_params.rs:25:8 + | +LL | fn qux(_: [()]) {} + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[()]` + = 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 | fn qux(_: &[()]) {} + | + + +error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time + --> $DIR/feature-gate-unsized_fn_params.rs:29:9 | LL | foo(*x); | ^^ doesn't have a size known at compile-time @@ -21,6 +55,6 @@ LL | foo(*x); = note: all function arguments must have a statically known size = help: unsized fn params are gated as an unstable feature -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/feature-gates/feature-gate-unsized_locals.stderr b/src/test/ui/feature-gates/feature-gate-unsized_locals.stderr index c4507843e366e..9aeeb88cf04f2 100644 --- a/src/test/ui/feature-gates/feature-gate-unsized_locals.stderr +++ b/src/test/ui/feature-gates/feature-gate-unsized_locals.stderr @@ -6,6 +6,10 @@ LL | fn f(f: dyn FnOnce()) {} | = help: the trait `Sized` is not implemented for `(dyn FnOnce() + 'static)` = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | fn f(f: impl FnOnce()) {} + | ~~~~ help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn f(f: &dyn FnOnce()) {} diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index f90399b6b9458..7f73d5e12d196 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -70,10 +70,6 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bak() -> dyn Trait { unimplemented!() } | ^^^^^^^^^ doesn't have a size known at compile-time | -help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type - | -LL | fn bak() -> T { unimplemented!() } - | ~ help: use `impl Trait` as the return type if all return paths have the same type but you want to expose only the trait in the signature | LL | fn bak() -> impl Trait { unimplemented!() } diff --git a/src/test/ui/issues/issue-18107.stderr b/src/test/ui/issues/issue-18107.stderr index 28478457b296d..1669b550a9baf 100644 --- a/src/test/ui/issues/issue-18107.stderr +++ b/src/test/ui/issues/issue-18107.stderr @@ -4,10 +4,6 @@ error[E0746]: return type cannot have an unboxed trait object LL | dyn AbstractRenderer | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type - | -LL | T - | help: use `impl AbstractRenderer` as the return type if all return paths have the same type but you want to expose only the trait in the signature | LL | impl AbstractRenderer diff --git a/src/test/ui/issues/issue-42312.stderr b/src/test/ui/issues/issue-42312.stderr index 6fe151622433a..3ca6a2957e14b 100644 --- a/src/test/ui/issues/issue-42312.stderr +++ b/src/test/ui/issues/issue-42312.stderr @@ -23,6 +23,10 @@ LL | pub fn f(_: dyn ToString) {} | = help: the trait `Sized` is not implemented for `(dyn ToString + 'static)` = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | pub fn f(_: impl ToString) {} + | ~~~~ help: function arguments must have a statically known size, borrowed types always have a known size | LL | pub fn f(_: &dyn ToString) {} diff --git a/src/test/ui/issues/issue-5883.stderr b/src/test/ui/issues/issue-5883.stderr index 8a20a60853a63..ffff403e0d465 100644 --- a/src/test/ui/issues/issue-5883.stderr +++ b/src/test/ui/issues/issue-5883.stderr @@ -6,6 +6,10 @@ LL | r: dyn A + 'static | = help: the trait `Sized` is not implemented for `(dyn A + 'static)` = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | r: impl A + 'static + | ~~~~ help: function arguments must have a statically known size, borrowed types always have a known size | LL | r: &dyn A + 'static diff --git a/src/test/ui/resolve/issue-5035-2.stderr b/src/test/ui/resolve/issue-5035-2.stderr index 939392733f0e9..558e6b7b118d8 100644 --- a/src/test/ui/resolve/issue-5035-2.stderr +++ b/src/test/ui/resolve/issue-5035-2.stderr @@ -6,6 +6,10 @@ LL | fn foo(_x: K) {} | = help: the trait `Sized` is not implemented for `(dyn I + 'static)` = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | fn foo(_x: impl K) {} + | ++++ help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo(_x: &K) {} diff --git a/src/test/ui/traits/bound/not-on-bare-trait.stderr b/src/test/ui/traits/bound/not-on-bare-trait.stderr index 8da0b6d6b8505..36b08a7d30931 100644 --- a/src/test/ui/traits/bound/not-on-bare-trait.stderr +++ b/src/test/ui/traits/bound/not-on-bare-trait.stderr @@ -20,6 +20,10 @@ LL | fn foo(_x: Foo + Send) { | = help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)` = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | fn foo(_x: impl Foo + Send) { + | ++++ help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo(_x: &Foo + Send) {