]> git.lizzy.rs Git - rust.git/commitdiff
Make suggestion more complete
authorEsteban Küber <esteban@kuber.com.ar>
Tue, 18 Aug 2020 23:44:45 +0000 (16:44 -0700)
committerEsteban Küber <esteban@kuber.com.ar>
Sat, 12 Sep 2020 00:05:18 +0000 (17:05 -0700)
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_typeck/src/check/coercion.rs
src/test/ui/impl-trait/equality.stderr
src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr
src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr

index fe53ccdbad50c9e43912f1003b48f951d43e722e..ca6f4243c2880daa8374f14c3492a434aa0a564a 100644 (file)
@@ -749,7 +749,7 @@ fn suggest_boxing_for_return_impl_trait(
             })
             .collect::<Vec<_>>();
         err.multipart_suggestion(
-            "if you change the return type to expect trait objects box the returned expressions",
+            "if you change the return type to expect trait objects, box the returned expressions",
             sugg,
             Applicability::MaybeIncorrect,
         );
index b669476483b101b1131f157b9a849a7ea7287305..4addee1a4c97643c1d094b4d646c163005ae12cf 100644 (file)
@@ -1459,7 +1459,7 @@ fn report_return_mismatched_types<'a>(
             }
         }
         if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.borrow().as_ref(), fn_output) {
-            self.add_impl_trait_explanation(&mut err, fcx, expected, *sp, fn_output);
+            self.add_impl_trait_explanation(&mut err, cause, fcx, expected, *sp, fn_output);
         }
         err
     }
@@ -1467,6 +1467,7 @@ fn report_return_mismatched_types<'a>(
     fn add_impl_trait_explanation<'a>(
         &self,
         err: &mut DiagnosticBuilder<'a>,
+        cause: &ObligationCause<'tcx>,
         fcx: &FnCtxt<'a, 'tcx>,
         expected: Ty<'tcx>,
         sp: Span,
@@ -1531,6 +1532,22 @@ fn add_impl_trait_explanation<'a>(
                     ],
                     Applicability::MachineApplicable,
                 );
+                let sugg = vec![sp, cause.span]
+                    .into_iter()
+                    .flat_map(|sp| {
+                        vec![
+                            (sp.shrink_to_lo(), "Box::new(".to_string()),
+                            (sp.shrink_to_hi(), ")".to_string()),
+                        ]
+                        .into_iter()
+                    })
+                    .collect::<Vec<_>>();
+                err.multipart_suggestion(
+                    "if you change the return type to expect trait objects, box the returned \
+                     expressions",
+                    sugg,
+                    Applicability::MaybeIncorrect,
+                );
             } else {
                 err.help(&format!(
                     "if the trait `{}` were object safe, you could return a boxed trait object",
@@ -1539,7 +1556,7 @@ fn add_impl_trait_explanation<'a>(
             }
             err.note(trait_obj_msg);
         }
-        err.help("alternatively, create a new `enum` with a variant for each returned type");
+        err.help("you could instead create a new `enum` with a variant for each returned type");
     }
 
     fn is_return_ty_unsized(&self, fcx: &FnCtxt<'a, 'tcx>, blk_id: hir::HirId) -> bool {
index 9667a9785dc63b0ef7c01ba9c211a9505aaad5a6..cdaa61ac323dd490fda9c16c930992a0f9487454 100644 (file)
@@ -23,7 +23,7 @@ LL |     0_u32
    = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
    = help: if the trait `Foo` were object safe, you could return a boxed trait object
    = 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 instead create a new `enum` with a variant for each returned type
 
 error[E0277]: cannot add `impl Foo` to `u32`
   --> $DIR/equality.rs:24:11
index 9abebeff95a87a97b05974e01b8e2cd253fbbf7d..66043267f91cd71979f72ae93fabbba300952e0c 100644 (file)
@@ -14,7 +14,7 @@ LL |     B
    = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
    = help: if the trait `NotObjectSafe` were object safe, you could return a boxed trait object
    = 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 instead create a new `enum` with a variant for each returned type
 
 error[E0308]: mismatched types
   --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:43:5
@@ -31,11 +31,17 @@ 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>
    = 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 instead 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> {
    |             ^^^^^^^           ^
+help: if you change the return type to expect trait objects, box the returned expressions
+   |
+LL |         return Box::new(A);
+LL |     }
+LL |     Box::new(B)
+   |
 
 error: aborting due to 2 previous errors
 
index 66d9ff307d98f1c035f95a9936b805bfa99dd639..4265381eb401c6a77a7a396a7fced5e9406b91d9 100644 (file)
@@ -13,11 +13,17 @@ 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>
    = 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 instead 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> {
    |             ^^^^^^^                  ^
+help: if you change the return type to expect trait objects, box the returned expressions
+   |
+LL |         return Box::new(0i32);
+LL |     }
+LL |     Box::new(1u32)
+   |
 
 error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:12:16
@@ -34,11 +40,17 @@ 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>
    = 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 instead 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> {
    |             ^^^^^^^                  ^
+help: if you change the return type to expect trait objects, box the returned expressions
+   |
+LL |         return Box::new(0i32);
+LL |     } else {
+LL |         return Box::new(1u32);
+   |
 
 error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:20:9
@@ -55,11 +67,17 @@ 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>
    = 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 instead 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> {
    |             ^^^^^^^                  ^
+help: if you change the return type to expect trait objects, box the returned expressions
+   |
+LL |         return Box::new(0i32);
+LL |     } else {
+LL |         Box::new(1u32)
+   |
 
 error[E0308]: `if` and `else` have incompatible types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:9
@@ -77,7 +95,7 @@ help: you could change the return type to be a boxed trait object
    |
 LL | fn qux() -> Box<dyn std::fmt::Display> {
    |             ^^^^^^^                  ^
-help: if you change the return type to expect trait objects box the returned expressions
+help: if you change the return type to expect trait objects, box the returned expressions
    |
 LL |         Box::new(0i32)
 LL |     } else {
@@ -98,11 +116,16 @@ 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>
    = 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 instead 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> {
    |             ^^^^^^^                  ^
+help: if you change the return type to expect trait objects, box the returned expressions
+   |
+LL |         0 => return Box::new(0i32),
+LL |         _ => Box::new(1u32),
+   |
 
 error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:40:5
@@ -120,11 +143,19 @@ 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>
    = 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 instead 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> {
    |             ^^^^^^^                  ^
+help: if you change the return type to expect trait objects, box the returned expressions
+   |
+LL |     Box::new(match 13 {
+LL |         0 => return Box::new(0i32),
+LL |         1 => 1u32,
+LL |         _ => 2u32,
+LL |     })
+   |
 
 error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:53:13
@@ -141,11 +172,18 @@ 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>
    = 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 instead 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> {
    |             ^^^^^^^                  ^
+help: if you change the return type to expect trait objects, box the returned expressions
+   |
+LL |             return Box::new(0i32);
+LL |         }
+LL |         _ => {
+LL |             Box::new(1u32)
+   |
 
 error[E0308]: `match` arms have incompatible types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:61:14
@@ -163,7 +201,7 @@ help: you could change the return type to be a boxed trait object
    |
 LL | fn dog() -> Box<dyn std::fmt::Display> {
    |             ^^^^^^^                  ^
-help: if you change the return type to expect trait objects box the returned expressions
+help: if you change the return type to expect trait objects, box the returned expressions
    |
 LL |         0 => Box::new(0i32),
 LL |         1 => Box::new(1u32),