diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index e1913011297..c19bc767563 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -37,7 +37,7 @@ use crate::astconv::AstConv; use crate::check::FnCtxt; -use rustc_errors::{struct_span_err, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{Coercion, InferOk, InferResult}; @@ -1523,10 +1523,12 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { }; if has_impl { if is_object_safe { - err.help(&format!( - "you can instead return a boxed trait object using `Box`", - &snippet[5..] - )); + err.span_suggestion_verbose( + return_sp, + "you could change the return type to be a boxed trait object", + format!("Box", &snippet[5..]), + Applicability::MachineApplicable, + ); } else { err.help(&format!( "if the trait `{}` were object safe, you could return a boxed trait object", diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr index dd4260fbe4f..a3bf2183255 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr @@ -30,9 +30,12 @@ LL | B | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn cat() -> Box { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs index a80e5df1a26..6114e8c72a3 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs @@ -2,16 +2,14 @@ fn foo() -> impl std::fmt::Display { if false { return 0i32; } - 1u32 - //~^ ERROR mismatched types + 1u32 //~ ERROR mismatched types } fn bar() -> impl std::fmt::Display { if false { return 0i32; } else { - return 1u32; - //~^ ERROR mismatched types + return 1u32; //~ ERROR mismatched types } } @@ -19,8 +17,7 @@ fn baz() -> impl std::fmt::Display { if false { return 0i32; } else { - 1u32 - //~^ ERROR mismatched types + 1u32 //~ ERROR mismatched types } } @@ -28,22 +25,19 @@ fn qux() -> impl std::fmt::Display { if false { 0i32 } else { - 1u32 - //~^ ERROR `if` and `else` have incompatible types + 1u32 //~ ERROR `if` and `else` have incompatible types } } fn bat() -> impl std::fmt::Display { match 13 { 0 => return 0i32, - _ => 1u32, - //~^ ERROR mismatched types + _ => 1u32, //~ ERROR mismatched types } } fn can() -> impl std::fmt::Display { - match 13 { - //~^ ERROR mismatched types + match 13 { //~ ERROR mismatched types 0 => return 0i32, 1 => 1u32, _ => 2u32, @@ -56,8 +50,9 @@ fn cat() -> impl std::fmt::Display { return 0i32; } _ => { - 1u32 - //~^ ERROR mismatched types + 1u32 //~ ERROR mismatched types + } + } } } } diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index b663cccbeef..4e4d57f35d2 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -12,12 +12,15 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn foo() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:12:16 | LL | fn bar() -> impl std::fmt::Display { | ---------------------- expected because this return type... @@ -30,12 +33,15 @@ LL | return 1u32; | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn bar() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:22:9 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:20:9 | LL | fn baz() -> impl std::fmt::Display { | ---------------------- expected because this return type... @@ -48,12 +54,15 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn baz() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: `if` and `else` have incompatible types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:31:9 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:9 | LL | / if false { LL | | 0i32 @@ -61,12 +70,11 @@ LL | | 0i32 LL | | } else { LL | | 1u32 | | ^^^^ expected `i32`, found `u32` -LL | | LL | | } | |_____- `if` and `else` have incompatible types error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:39:14 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:35:14 | LL | fn bat() -> impl std::fmt::Display { | ---------------------- expected because this return type... @@ -78,17 +86,19 @@ LL | _ => 1u32, | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn bat() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:45:5 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:40:5 | LL | fn can() -> impl std::fmt::Display { | ---------------------- expected because this return type... LL | / match 13 { -LL | | LL | | 0 => return 0i32, | | ---- ...is found to be `i32` here LL | | 1 => 1u32, @@ -98,12 +108,15 @@ LL | | } | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn can() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:59:13 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:53:13 | LL | fn cat() -> impl std::fmt::Display { | ---------------------- expected because this return type... @@ -116,9 +129,12 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn cat() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 7 previous errors