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::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<dyn {}>`",
&snippet[5..]
));
err.span_suggestion_verbose(
return_sp,
"you could change the return type to be a boxed trait object",
format!("Box<dyn {}>", &snippet[5..]),
Applicability::MachineApplicable,
);
} else {
err.help(&format!(
"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: 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>
= 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

View File

@ -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
}
}
}
}
}

View File

@ -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 <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>
= 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
--> $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 <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>
= 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
--> $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 <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>
= 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
--> $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 <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>
= 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
--> $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 <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>
= 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
--> $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 <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>
= 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