Use structured suggestion for `impl T` to `Box<dyn T>`

This commit is contained in:
Esteban Küber 2020-08-17 19:04:27 -07:00
parent d778203da2
commit c8ee33714b
4 changed files with 50 additions and 34 deletions

View File

@ -37,7 +37,7 @@
use crate::astconv::AstConv; use crate::astconv::AstConv;
use crate::check::FnCtxt; 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_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{Coercion, InferOk, InferResult}; use rustc_infer::infer::{Coercion, InferOk, InferResult};
@ -1523,10 +1523,12 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
}; };
if has_impl { if has_impl {
if is_object_safe { if is_object_safe {
err.help(&format!( err.span_suggestion_verbose(
"you can instead return a boxed trait object using `Box<dyn {}>`", return_sp,
&snippet[5..] "you could change the return type to be a boxed trait object",
)); format!("Box<dyn {}>", &snippet[5..]),
Applicability::MachineApplicable,
);
} else { } else {
err.help(&format!( err.help(&format!(
"if the trait `{}` were object safe, you could return a boxed trait object", "if the trait `{}` were object safe, you could return a boxed trait object",

View File

@ -30,9 +30,12 @@ LL | B
| |
= note: to return `impl Trait`, all returned values must be of the same type = note: to return `impl Trait`, all returned values must be of the same type
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
= help: you can instead return a boxed trait object using `Box<dyn ObjectSafe>`
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
= help: alternatively, create a new `enum` with a variant for each returned type = 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<dyn ObjectSafe> {
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -2,16 +2,14 @@ fn foo() -> impl std::fmt::Display {
if false { if false {
return 0i32; return 0i32;
} }
1u32 1u32 //~ ERROR mismatched types
//~^ ERROR mismatched types
} }
fn bar() -> impl std::fmt::Display { fn bar() -> impl std::fmt::Display {
if false { if false {
return 0i32; return 0i32;
} else { } else {
return 1u32; return 1u32; //~ ERROR mismatched types
//~^ ERROR mismatched types
} }
} }
@ -19,8 +17,7 @@ fn baz() -> impl std::fmt::Display {
if false { if false {
return 0i32; return 0i32;
} else { } else {
1u32 1u32 //~ ERROR mismatched types
//~^ ERROR mismatched types
} }
} }
@ -28,22 +25,19 @@ fn qux() -> impl std::fmt::Display {
if false { if false {
0i32 0i32
} else { } else {
1u32 1u32 //~ ERROR `if` and `else` have incompatible types
//~^ ERROR `if` and `else` have incompatible types
} }
} }
fn bat() -> impl std::fmt::Display { fn bat() -> impl std::fmt::Display {
match 13 { match 13 {
0 => return 0i32, 0 => return 0i32,
_ => 1u32, _ => 1u32, //~ ERROR mismatched types
//~^ ERROR mismatched types
} }
} }
fn can() -> impl std::fmt::Display { fn can() -> impl std::fmt::Display {
match 13 { match 13 { //~ ERROR mismatched types
//~^ ERROR mismatched types
0 => return 0i32, 0 => return 0i32,
1 => 1u32, 1 => 1u32,
_ => 2u32, _ => 2u32,
@ -56,8 +50,9 @@ fn cat() -> impl std::fmt::Display {
return 0i32; return 0i32;
} }
_ => { _ => {
1u32 1u32 //~ ERROR mismatched types
//~^ ERROR mismatched types }
}
} }
} }
} }

View File

@ -12,12 +12,15 @@ LL | 1u32
| |
= note: to return `impl Trait`, all returned values must be of the same type = note: to return `impl Trait`, all returned values must be of the same type
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
= help: you can instead return a boxed trait object using `Box<dyn std::fmt::Display>`
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
= help: alternatively, create a new `enum` with a variant for each returned type = 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<dyn std::fmt::Display> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types 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 { LL | fn bar() -> impl std::fmt::Display {
| ---------------------- expected because this return type... | ---------------------- 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: to return `impl Trait`, all returned values must be of the same type
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
= help: you can instead return a boxed trait object using `Box<dyn std::fmt::Display>`
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
= help: alternatively, create a new `enum` with a variant for each returned type = 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<dyn std::fmt::Display> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types 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 { LL | fn baz() -> impl std::fmt::Display {
| ---------------------- expected because this return type... | ---------------------- 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: to return `impl Trait`, all returned values must be of the same type
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
= help: you can instead return a boxed trait object using `Box<dyn std::fmt::Display>`
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
= help: alternatively, create a new `enum` with a variant for each returned type = 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<dyn std::fmt::Display> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: `if` and `else` have incompatible types 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 | / if false {
LL | | 0i32 LL | | 0i32
@ -61,12 +70,11 @@ LL | | 0i32
LL | | } else { LL | | } else {
LL | | 1u32 LL | | 1u32
| | ^^^^ expected `i32`, found `u32` | | ^^^^ expected `i32`, found `u32`
LL | |
LL | | } LL | | }
| |_____- `if` and `else` have incompatible types | |_____- `if` and `else` have incompatible types
error[E0308]: mismatched 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 { LL | fn bat() -> impl std::fmt::Display {
| ---------------------- expected because this return type... | ---------------------- 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: to return `impl Trait`, all returned values must be of the same type
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
= help: you can instead return a boxed trait object using `Box<dyn std::fmt::Display>`
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
= help: alternatively, create a new `enum` with a variant for each returned type = 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<dyn std::fmt::Display> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types 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 { LL | fn can() -> impl std::fmt::Display {
| ---------------------- expected because this return type... | ---------------------- expected because this return type...
LL | / match 13 { LL | / match 13 {
LL | |
LL | | 0 => return 0i32, LL | | 0 => return 0i32,
| | ---- ...is found to be `i32` here | | ---- ...is found to be `i32` here
LL | | 1 => 1u32, LL | | 1 => 1u32,
@ -98,12 +108,15 @@ LL | | }
| |
= note: to return `impl Trait`, all returned values must be of the same type = note: to return `impl Trait`, all returned values must be of the same type
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
= help: you can instead return a boxed trait object using `Box<dyn std::fmt::Display>`
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
= help: alternatively, create a new `enum` with a variant for each returned type = 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<dyn std::fmt::Display> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types 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 { LL | fn cat() -> impl std::fmt::Display {
| ---------------------- expected because this return type... | ---------------------- 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: to return `impl Trait`, all returned values must be of the same type
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
= help: you can instead return a boxed trait object using `Box<dyn std::fmt::Display>`
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
= help: alternatively, create a new `enum` with a variant for each returned type = 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<dyn std::fmt::Display> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 7 previous errors error: aborting due to 7 previous errors