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 { = 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); | ----- required by this bound in `Foo` ... LL | impl Trait2 for Foo {} - | ^^^^^^ 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); | - required by this bound in `S5` LL | LL | impl T3 for S5 { - | - ^^^^^ 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 { + | - 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`.