Rollup merge of #132935 - compiler-errors:arg-math, r=nnethercote

Make sure to ignore elided lifetimes when pointing at args for fulfillment errors

See the comment I left in the code.

---

If we have something like:

```
fn foo<'a, T: 'a + BoundThatIsNotSatisfied>() {}
```

And the user turbofishes just the type args:

```
foo::<()>();
```

Then if we try pointing at `()` (i.e. the type argument for `T`), we don't actually consider the possibility that the lifetimes may have been left out of the turbofish. We try indexing incorrectly into the HIR args, and bail on the suggestion.
This commit is contained in:
Matthias Krüger 2024-11-12 08:07:19 +01:00 committed by GitHub
commit 9a4a954359
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 42 additions and 13 deletions

View File

@ -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

View File

@ -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-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`

View File

@ -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<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`

View File

@ -31,10 +31,10 @@ LL | for<'b> <T::Next as X<'b, T::Next>>::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 | <i32 as X<Box<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`

View File

@ -17,5 +17,6 @@ impl<S, T> X<'_, T> for (S,) {
pub fn main() {
<(i32,) as X<i32>>::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
}

View File

@ -17,6 +17,22 @@ LL | <(i32,) as X<i32>>::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<i32>>::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: &<T as X<'_, T>>::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<i32>>::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`.

View File

@ -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::<T>();
| ^^^^^^^^^^^^^^ 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