Silence unnecessary "missing dyn" errors and tweak E0746 suggestions by estebank · Pull Request #122957 · rust-lang/rust (original) (raw)

Rework impl Trait and Box return type suggestions in E0746

error[E0746]: return type cannot have an unboxed trait object
  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13
   |
LL | fn bap() -> Trait { Struct }
   |             ^^^^^ doesn't have a size known at compile-time
   |
help: return an `impl Trait` instead of a `dyn Trait`
   |
LL | fn bap() -> impl Trait { Struct }
   |             ++++
help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new`
   |
LL | fn bap() -> Box<dyn Trait> { Box::new(Struct) }
   |             +++++++      +   +++++++++      +
error[E0746]: return type cannot have an unboxed trait object
  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:36:18
   |
LL | fn can(x: &A) -> dyn NotObjectSafe {
   |                  ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
help: trait `NotObjectSafe` is not object safe, so you can't return a boxed trait object `Box<dyn NotObjectSafe>`
  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:36:22
   |
LL | fn can(x: &A) -> dyn NotObjectSafe {
   |                      ^^^^^^^^^^^^^
help: return an `impl Trait` instead of a `dyn Trait`
   |
LL | fn can(x: &A) -> impl NotObjectSafe {
   |                  ~~~~
help: alternatively, you might be able to borrow from the function's argument
   |
LL | fn can(x: &A) -> &dyn NotObjectSafe {
   |                  +
error[E0782]: trait objects must include the `dyn` keyword
  --> $DIR/not-on-bare-trait-2021.rs:12:19
   |
LL | fn bar(x: Foo) -> Foo {
   |                   ^^^
   |
help: use `impl Foo` to return an opaque type, as long as you return a single underlying type
   |
LL | fn bar(x: Foo) -> impl Foo {
   |                   ++++
help: alternatively, you can return a boxed trait object
   |
LL | fn bar(x: Foo) -> Box<dyn Foo> {
   |                   +++++++    +

Silence "missing dyn" error if "?Sized type" error is already emitted.

Account for type Alias = dyn Trait; in unsized return suggestion:

error[E0746]: return type cannot have an unboxed trait object
 --> tests/ui/unsized/issue-91801.rs:8:77
  |
8 | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> {
  |                                                                             ^^^^^^^^^^^^^ doesn't have a size known at compile-time
-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs:566:39
  |
help: box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new`
  |
8 | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box<Validator<'a>> {
  |                                                                             ++++             +
help: alternatively, you might be able to borrow from one of the function's arguments
  |
8 | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> &Validator<'a> {
  |                                                                             +

Use more complex logic for E0277 deduplication of FullfillmentErrors, accounting and customizing the span for SizedArgument obligations and functions with unsized return types. We only emit one unsized local error whenever possible.

Point at the let binding type or init expression instead of the pattern when possible for ?Sized errors.

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
  --> $DIR/unsized-locals-using-unsized-fn-params.rs:13:15
   |
LL |     let _foo: [u8] = *foo;
   |               ^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `[u8]`
   = note: all local variables must have a statically known size

Fix #121037. Fix #105753.