about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-06-12 15:13:43 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-06-15 19:46:27 -0700
commitd2b8e6090cb694898d4481f4a55d5489fa4b279e (patch)
tree7e8d032c1f0cb91f1501802a41d31f99e8dd42f3
parent95e56051088e5c03cd5c5146739bd6b783d61445 (diff)
downloadrust-d2b8e6090cb694898d4481f4a55d5489fa4b279e.tar.gz
rust-d2b8e6090cb694898d4481f4a55d5489fa4b279e.zip
Account for derived obligations to suggest `?Sized` bound
Fix #27964.
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/mod.rs16
-rw-r--r--src/test/ui/dst/dst-sized-trait-param.stderr4
-rw-r--r--src/test/ui/extern/extern-types-unsized.stderr12
-rw-r--r--src/test/ui/issues/issue-10412.stderr4
-rw-r--r--src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr4
-rw-r--r--src/test/ui/unsized3.stderr8
-rw-r--r--src/test/ui/unsized7.stderr4
7 files changed, 44 insertions, 8 deletions
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index 3afdd709f3b..a99c14f763f 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -1696,14 +1696,14 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
         err: &mut DiagnosticBuilder<'tcx>,
         obligation: &PredicateObligation<'tcx>,
     ) {
-        let (pred, item_def_id, span) = match (obligation.predicate.kind(), &obligation.cause.code)
-        {
-            (
-                ty::PredicateKind::Trait(pred, _),
-                ObligationCauseCode::BindingObligation(item_def_id, span),
-            ) => (pred, item_def_id, span),
-            _ => return,
-        };
+        let (pred, item_def_id, span) =
+            match (obligation.predicate.kind(), &obligation.cause.code.peel_derives()) {
+                (
+                    ty::PredicateKind::Trait(pred, _),
+                    ObligationCauseCode::BindingObligation(item_def_id, span),
+                ) => (pred, item_def_id, span),
+                _ => return,
+            };
 
         let node = match (
             self.tcx.hir().get_if_local(*item_def_id),
diff --git a/src/test/ui/dst/dst-sized-trait-param.stderr b/src/test/ui/dst/dst-sized-trait-param.stderr
index 749d569b9ae..006a334021b 100644
--- a/src/test/ui/dst/dst-sized-trait-param.stderr
+++ b/src/test/ui/dst/dst-sized-trait-param.stderr
@@ -9,6 +9,10 @@ LL | impl Foo<[isize]> for usize { }
    |
    = help: the trait `std::marker::Sized` is not implemented for `[isize]`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Foo<T: ?Sized> : Sized { fn take(self, x: &T) { } } // Note: T is sized
+   |            ^^^^^^^^
 
 error[E0277]: the size for values of type `[usize]` cannot be known at compilation time
   --> $DIR/dst-sized-trait-param.rs:10:6
diff --git a/src/test/ui/extern/extern-types-unsized.stderr b/src/test/ui/extern/extern-types-unsized.stderr
index 9ed52511fa3..0c7995fde32 100644
--- a/src/test/ui/extern/extern-types-unsized.stderr
+++ b/src/test/ui/extern/extern-types-unsized.stderr
@@ -26,6 +26,10 @@ LL |     assert_sized::<Foo>();
    = help: within `Foo`, the trait `std::marker::Sized` is not implemented for `A`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because it appears within the type `Foo`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn assert_sized<T: ?Sized>() { }
+   |                  ^^^^^^^^
 
 error[E0277]: the size for values of type `A` cannot be known at compilation time
   --> $DIR/extern-types-unsized.rs:28:5
@@ -39,6 +43,10 @@ LL |     assert_sized::<Bar<A>>();
    = help: within `Bar<A>`, the trait `std::marker::Sized` is not implemented for `A`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because it appears within the type `Bar<A>`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn assert_sized<T: ?Sized>() { }
+   |                  ^^^^^^^^
 
 error[E0277]: the size for values of type `A` cannot be known at compilation time
   --> $DIR/extern-types-unsized.rs:31:5
@@ -53,6 +61,10 @@ LL |     assert_sized::<Bar<Bar<A>>>();
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because it appears within the type `Bar<A>`
    = note: required because it appears within the type `Bar<Bar<A>>`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn assert_sized<T: ?Sized>() { }
+   |                  ^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/issues/issue-10412.stderr b/src/test/ui/issues/issue-10412.stderr
index 888576c4336..d7a4bf4f21f 100644
--- a/src/test/ui/issues/issue-10412.stderr
+++ b/src/test/ui/issues/issue-10412.stderr
@@ -57,6 +57,10 @@ LL | impl<'self> Serializable<str> for &'self str {
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Serializable<'self, T: ?Sized> {
+   |                            ^^^^^^^^
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr
index 4cf054d177f..e423a9bdeab 100644
--- a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr
+++ b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr
@@ -11,6 +11,10 @@ LL | impl<X: ?Sized> T2<X> for S4<X> {
    |
    = help: the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait T2<Z: ?Sized> {
+   |           ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr
index 828e8bc9f4a..e0a0389dc46 100644
--- a/src/test/ui/unsized3.stderr
+++ b/src/test/ui/unsized3.stderr
@@ -48,6 +48,10 @@ LL |     f5(x1);
    = help: within `S<X>`, the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because it appears within the type `S<X>`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn f5<Y: ?Sized>(x: &Y) {}
+   |        ^^^^^^^^
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized3.rs:40:8
@@ -91,6 +95,10 @@ LL |     f5(&(32, *x1));
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because it appears within the type `S<X>`
    = note: required because it appears within the type `({integer}, S<X>)`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn f5<Y: ?Sized>(x: &Y) {}
+   |        ^^^^^^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/unsized7.stderr b/src/test/ui/unsized7.stderr
index d18644f005a..e616a5cf0f9 100644
--- a/src/test/ui/unsized7.stderr
+++ b/src/test/ui/unsized7.stderr
@@ -11,6 +11,10 @@ LL | impl<X: ?Sized + T> T1<X> for S3<X> {
    |
    = help: the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait T1<Z: T + ?Sized> {
+   |               ^^^^^^^^
 
 error: aborting due to previous error