From 3a1aa3c76eb06bf6eba9c10eaccced92420c2fac Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 16 Aug 2022 23:37:56 +0000 Subject: [PATCH] Do not favor projection type when pointing out arg causing fulfillment error --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 20 ++++++++++++++++++- .../associated-types-path-2.stderr | 12 +++++++---- .../issue-27675-unchecked-bounds.stderr | 6 ++---- src/test/ui/issues/issue-69683.stderr | 2 +- .../enforce-supertrait-projection.stderr | 6 ++---- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 5a2a68d0604..f2f327e0812 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1742,7 +1742,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .inputs() .iter() .enumerate() - .filter(|(_, ty)| ty.walk().any(|arg| arg == param_to_point_at)) + .filter(|(_, ty)| { + let mut walk = ty.walk(); + while let Some(arg) = walk.next() { + if arg == param_to_point_at { + return true; + } else if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Projection(..) = ty.kind() + { + // This logic may seem a bit strange, but typically when + // we have a projection type in a function signature, the + // argument that's being passed into that signature is + // not actually constraining that projection in a meaningful + // way. So we skip it, and see improvements in some UI tests + // due to it. + walk.skip_current_subtree(); + } + } + false + }) .collect(); if let [(idx, _)] = args_referencing_param.as_slice() diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr index 7e3cccae3ea..5edd5c864e1 100644 --- a/src/test/ui/associated-types/associated-types-path-2.stderr +++ b/src/test/ui/associated-types/associated-types-path-2.stderr @@ -17,10 +17,12 @@ LL | f1(2i32, 4u32); | ~~~ error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:29:5 + --> $DIR/associated-types-path-2.rs:29:8 | LL | f1(2u32, 4u32); - | ^^ the trait `Foo` is not implemented for `u32` + | -- ^^^^ the trait `Foo` is not implemented for `u32` + | | + | required by a bound introduced by this call | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `f1` @@ -38,10 +40,12 @@ LL | f1(2u32, 4u32); = help: the trait `Foo` is implemented for `i32` error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:35:5 + --> $DIR/associated-types-path-2.rs:35:8 | LL | f1(2u32, 4i32); - | ^^ the trait `Foo` is not implemented for `u32` + | -- ^^^^ the trait `Foo` is not implemented for `u32` + | | + | required by a bound introduced by this call | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `f1` diff --git a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr index 22daaf32910..a14a273b3ec 100644 --- a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr +++ b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/issue-27675-unchecked-bounds.rs:15:31 + --> $DIR/issue-27675-unchecked-bounds.rs:15:12 | LL | copy::>(t) - | ------------------------- ^ the trait `Copy` is not implemented for `T` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T` | note: required by a bound in `copy` --> $DIR/issue-27675-unchecked-bounds.rs:10:12 diff --git a/src/test/ui/issues/issue-69683.stderr b/src/test/ui/issues/issue-69683.stderr index 6d9a1c6fbf9..248fb75b4c4 100644 --- a/src/test/ui/issues/issue-69683.stderr +++ b/src/test/ui/issues/issue-69683.stderr @@ -14,7 +14,7 @@ error[E0283]: type annotations needed --> $DIR/issue-69683.rs:30:10 | LL | 0u16.foo(b); - | ^^^ - type must be known at this point + | ^^^ | note: multiple `impl`s satisfying `u8: Element<_>` found --> $DIR/issue-69683.rs:5:1 diff --git a/src/test/ui/traits/object/enforce-supertrait-projection.stderr b/src/test/ui/traits/object/enforce-supertrait-projection.stderr index 9e221daabe5..cbf09386654 100644 --- a/src/test/ui/traits/object/enforce-supertrait-projection.stderr +++ b/src/test/ui/traits/object/enforce-supertrait-projection.stderr @@ -1,14 +1,12 @@ error[E0271]: type mismatch resolving ` as SuperTrait>::A == B` - --> $DIR/enforce-supertrait-projection.rs:9:42 + --> $DIR/enforce-supertrait-projection.rs:9:17 | LL | fn transmute(x: A) -> B { | - - expected type parameter | | | found type parameter LL | foo::>(x) - | ------------------------------------ ^ expected type parameter `B`, found type parameter `A` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A` | = note: expected type parameter `B` found type parameter `A`