From d128c80c7aeb936bdb587734e599b1bdb7c1e442 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 12 Nov 2024 02:08:30 +0000 Subject: [PATCH] Make sure to ignore elided lifetimes when pointing at args for fulfillment errors --- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 20 +++++++++++++++---- .../hr-associated-type-bound-param-3.stderr | 4 ++-- .../hr-associated-type-bound-param-4.stderr | 4 ++-- .../hr-associated-type-bound-param-5.stderr | 4 ++-- .../hr-associated-type-bound-param-6.rs | 1 + .../hr-associated-type-bound-param-6.stderr | 18 ++++++++++++++++- ...didate-from-env-universe-err-2.next.stderr | 4 ++-- 7 files changed, 42 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index f93d0e9340613..b09d78614c321 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -316,12 +316,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .generics_of(def_id) .own_args(ty::GenericArgs::identity_for_item(self.tcx, def_id)); - let Some((index, _)) = - own_args.iter().enumerate().find(|(_, arg)| **arg == param_to_point_at) - else { + let Some(mut index) = own_args.iter().position(|arg| *arg == param_to_point_at) else { return false; }; - let Some(arg) = segment.args().args.get(index) else { + // SUBTLE: We may or may not turbofish lifetime arguments, which will + // otherwise be elided. if our "own args" starts with a lifetime, but + // the args list does not, then we should chop off all of the lifetimes, + // since they're all elided. + let segment_args = segment.args().args; + if matches!(own_args[0].unpack(), ty::GenericArgKind::Lifetime(_)) + && segment_args.first().is_some_and(|arg| arg.is_ty_or_const()) + && let Some(offset) = own_args.iter().position(|arg| { + matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_)) + }) + && let Some(new_index) = index.checked_sub(offset) + { + index = new_index; + } + let Some(arg) = segment_args.get(index) else { return false; }; error.obligation.cause.span = arg diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr index 58b82fc930625..06dca48b61645 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr @@ -15,10 +15,10 @@ LL | for<'b> >::U: Clone, | ^^^^^ required by this bound in `X` error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-3.rs:18:5 + --> $DIR/hr-associated-type-bound-param-3.rs:18:18 | LL | <(i32,) as X<(i32,)>>::f("abc"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | ^^^^^^ the trait `Clone` is not implemented for `str` | = help: the trait `Clone` is implemented for `String` note: required by a bound in `X::f` diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr index 6d6373a19182e..da0cf6f55ba7c 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr @@ -15,10 +15,10 @@ LL | for<'b> <(T,) as X<'b, T>>::U: Clone, | ^^^^^ required by this bound in `X` error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-4.rs:18:5 + --> $DIR/hr-associated-type-bound-param-4.rs:18:18 | LL | <(i32,) as X>::f("abc"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | ^^^ the trait `Clone` is not implemented for `str` | = help: the trait `Clone` is implemented for `String` note: required by a bound in `X::f` diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr index 44c446c599fc7..dd576577dce72 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr @@ -31,10 +31,10 @@ LL | for<'b> >::U: Clone, | ^^^^^ required by this bound in `X` error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-5.rs:36:5 + --> $DIR/hr-associated-type-bound-param-5.rs:36:15 | LL | >>::f("abc"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | ^^^^^^^^ the trait `Clone` is not implemented for `str` | = help: the trait `Clone` is implemented for `String` note: required by a bound in `X::f` diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-6.rs b/tests/ui/associated-types/hr-associated-type-bound-param-6.rs index f6639904ab33a..c09d3675584e4 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-6.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-param-6.rs @@ -17,5 +17,6 @@ impl X<'_, T> for (S,) { pub fn main() { <(i32,) as X>::f("abc"); //~^ ERROR the trait bound `for<'b> i32: X<'b, i32>` is not satisfied + //~| ERROR the trait bound `for<'b> i32: X<'b, i32>` is not satisfied //~| ERROR the trait bound `i32: X<'_, i32>` is not satisfied } diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr index cba83120fdc7d..5278bdb7a5cf2 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr @@ -17,6 +17,22 @@ LL | <(i32,) as X>::f("abc"); | = help: the trait `X<'_, T>` is implemented for `(S,)` +error[E0277]: the trait bound `for<'b> i32: X<'b, i32>` is not satisfied + --> $DIR/hr-associated-type-bound-param-6.rs:18:18 + | +LL | <(i32,) as X>::f("abc"); + | ^^^ the trait `for<'b> X<'b, i32>` is not implemented for `i32` + | + = help: the trait `X<'_, T>` is implemented for `(S,)` +note: required by a bound in `X::f` + --> $DIR/hr-associated-type-bound-param-6.rs:3:16 + | +LL | for<'b> T: X<'b, T>, + | ^^^^^^^^ required by this bound in `X::f` +... +LL | fn f(x: &>::U) { + | - required by a bound in this associated function + error[E0277]: the trait bound `i32: X<'_, i32>` is not satisfied --> $DIR/hr-associated-type-bound-param-6.rs:18:27 | @@ -25,6 +41,6 @@ LL | <(i32,) as X>::f("abc"); | = help: the trait `X<'_, T>` is implemented for `(S,)` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr index 3697bd9cf021d..0f5a9de7ab854 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied - --> $DIR/candidate-from-env-universe-err-2.rs:15:5 + --> $DIR/candidate-from-env-universe-err-2.rs:15:15 | LL | impl_hr::(); - | ^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a, '_>` is not implemented for `T` + | ^ the trait `for<'a> Trait<'a, '_>` is not implemented for `T` | note: required by a bound in `impl_hr` --> $DIR/candidate-from-env-universe-err-2.rs:12:19