Skip to content

Commit

Permalink
Use structured suggestion for impl T to Box<dyn T>
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Sep 12, 2020
1 parent d778203 commit c8ee337
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 34 deletions.
12 changes: 7 additions & 5 deletions compiler/rustc_typeck/src/check/coercion.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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",
Expand Down
Expand Up @@ -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

Expand Down
23 changes: 9 additions & 14 deletions src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
Expand Up @@ -2,48 +2,42 @@ 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
}
}

fn baz() -> impl std::fmt::Display {
if false {
return 0i32;
} else {
1u32
//~^ ERROR mismatched types
1u32 //~ ERROR mismatched types
}
}

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,
Expand All @@ -56,8 +50,9 @@ fn cat() -> impl std::fmt::Display {
return 0i32;
}
_ => {
1u32
//~^ ERROR mismatched types
1u32 //~ ERROR mismatched types
}
}
}
}
}
Expand Down
44 changes: 30 additions & 14 deletions src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
Expand Up @@ -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...
Expand All @@ -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...
Expand All @@ -48,25 +54,27 @@ 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
| | ---- expected because of this
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...
Expand All @@ -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,
Expand All @@ -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...
Expand All @@ -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

Expand Down

0 comments on commit c8ee337

Please sign in to comment.