about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-07-26 03:03:19 +0000
committerbors <bors@rust-lang.org>2020-07-26 03:03:19 +0000
commita4dd850720369d9e5b9df91820b23cddb2badc06 (patch)
tree50e4f01ff68a29ab7502d900de767e92f40dde5e
parent8e5489ca6760420af33ffa361d5c706eb9badf48 (diff)
parent116ad51c2c931b54c34790f0a56eb012643df987 (diff)
downloadrust-a4dd850720369d9e5b9df91820b23cddb2badc06.tar.gz
rust-a4dd850720369d9e5b9df91820b23cddb2badc06.zip
Auto merge of #74735 - Aaron1011:fix/wf-impl-self-type, r=estebank
Use the proper span when WF-checking an impl self type
-rw-r--r--src/librustc_trait_selection/traits/wf.rs16
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr4
-rw-r--r--src/test/ui/issues/issue-21837.stderr4
-rw-r--r--src/test/ui/unsized/unsized-trait-impl-self-type.stderr4
-rw-r--r--src/test/ui/wf/wf-impl-self-type.rs7
-rw-r--r--src/test/ui/wf/wf-impl-self-type.stderr16
7 files changed, 43 insertions, 12 deletions
diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs
index b8446fa0012..0e445e1e53b 100644
--- a/src/librustc_trait_selection/traits/wf.rs
+++ b/src/librustc_trait_selection/traits/wf.rs
@@ -300,13 +300,21 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
             trait_ref
                 .substs
                 .iter()
-                .filter(|arg| {
+                .enumerate()
+                .filter(|(_, arg)| {
                     matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
                 })
-                .filter(|arg| !arg.has_escaping_bound_vars())
-                .map(|arg| {
+                .filter(|(_, arg)| !arg.has_escaping_bound_vars())
+                .map(|(i, arg)| {
+                    let mut new_cause = cause.clone();
+                    // The first subst is the self ty - use the correct span for it.
+                    if i == 0 {
+                        if let Some(hir::ItemKind::Impl { self_ty, .. }) = item.map(|i| &i.kind) {
+                            new_cause.make_mut().span = self_ty.span;
+                        }
+                    }
                     traits::Obligation::new(
-                        cause.clone(),
+                        new_cause,
                         param_env,
                         ty::PredicateKind::WellFormed(arg).to_predicate(tcx),
                     )
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
index 85ed360a1f7..cd18a013628 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
@@ -1,12 +1,12 @@
 error[E0038]: the trait `NotObjectSafe` cannot be made into an object
-  --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:6
+  --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:24
    |
 LL | trait NotObjectSafe { fn eq(&self, other: Self); }
    |       -------------                       ---- ...because method `eq` references the `Self` type in this parameter
    |       |
    |       this trait cannot be made into an object...
 LL | impl NotObjectSafe for dyn NotObjectSafe { }
-   |      ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
+   |                        ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
    |
    = help: consider moving `eq` to another trait
 
diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
index c66bbb0c504..e3272e8849f 100644
--- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
+++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
@@ -52,7 +52,7 @@ LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
    = help: consider moving `foo` to another trait
 
 error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
-  --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:16
    |
 LL | trait NonObjectSafe1: Sized {}
    |       --------------  ----- ...because it requires `Self: Sized`
@@ -60,7 +60,7 @@ LL | trait NonObjectSafe1: Sized {}
    |       this trait cannot be made into an object...
 ...
 LL | impl Trait for dyn NonObjectSafe1 {}
-   |      ^^^^^ the trait `NonObjectSafe1` cannot be made into an object
+   |                ^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/issues/issue-21837.stderr b/src/test/ui/issues/issue-21837.stderr
index f7e46b25cf8..27e5c606a64 100644
--- a/src/test/ui/issues/issue-21837.stderr
+++ b/src/test/ui/issues/issue-21837.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: Bound` is not satisfied
-  --> $DIR/issue-21837.rs:8:9
+  --> $DIR/issue-21837.rs:8:20
    |
 LL | pub struct Foo<T: Bound>(T);
    |                   ----- required by this bound in `Foo`
 ...
 LL | impl<T> Trait2 for Foo<T> {}
-   |         ^^^^^^ the trait `Bound` is not implemented for `T`
+   |                    ^^^^^^ the trait `Bound` is not implemented for `T`
    |
 help: consider restricting type parameter `T`
    |
diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr
index 4514208a90d..071547c945e 100644
--- a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr
+++ b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the size for values of type `X` cannot be known at compilation time
-  --> $DIR/unsized-trait-impl-self-type.rs:10:17
+  --> $DIR/unsized-trait-impl-self-type.rs:10:27
    |
 LL | struct S5<Y>(Y);
    |           - required by this bound in `S5`
 LL | 
 LL | impl<X: ?Sized> T3<X> for S5<X> {
-   |      -          ^^^^^ doesn't have a size known at compile-time
+   |      -                    ^^^^^ doesn't have a size known at compile-time
    |      |
    |      this type parameter needs to be `std::marker::Sized`
    |
diff --git a/src/test/ui/wf/wf-impl-self-type.rs b/src/test/ui/wf/wf-impl-self-type.rs
new file mode 100644
index 00000000000..2dd9b4ef01d
--- /dev/null
+++ b/src/test/ui/wf/wf-impl-self-type.rs
@@ -0,0 +1,7 @@
+// Tests that we point at the proper location for an error
+// involving the self-type of an impl
+
+trait Foo {}
+impl Foo for Option<[u8]> {} //~ ERROR the size for
+
+fn main() {}
diff --git a/src/test/ui/wf/wf-impl-self-type.stderr b/src/test/ui/wf/wf-impl-self-type.stderr
new file mode 100644
index 00000000000..a3a53113b4f
--- /dev/null
+++ b/src/test/ui/wf/wf-impl-self-type.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/wf-impl-self-type.rs:5:14
+   |
+LL | impl Foo for Option<[u8]> {}
+   |              ^^^^^^^^^^^^ doesn't have a size known at compile-time
+   | 
+  ::: $SRC_DIR/libcore/option.rs:LL:COL
+   |
+LL | pub enum Option<T> {
+   |                 - required by this bound in `std::option::Option`
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `[u8]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.