about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-08-17 19:04:27 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-09-11 17:05:18 -0700
commitc8ee33714becbda0f1deddf1befe0383b4aad135 (patch)
treee27b5f9be0d056e7e91e73b7064c2cf47de66820
parentd778203da2157f47af6d1f7ba5f44eb933ee2df1 (diff)
downloadrust-c8ee33714becbda0f1deddf1befe0383b4aad135.tar.gz
rust-c8ee33714becbda0f1deddf1befe0383b4aad135.zip
Use structured suggestion for `impl T` to `Box<dyn T>`
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs12
-rw-r--r--src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr5
-rw-r--r--src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs23
-rw-r--r--src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr44
4 files changed, 50 insertions, 34 deletions
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<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",
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 <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
 
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 <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