Description
Usage of GATs must specify lifetime generic parameters even if they can be inferred, unlike structs and type aliases. Personally, I think this is the wrong choice, though I recognize the linting folks disagree. In any case, the diagnostic output for when '_
is necessary isn't tested in enough scenarios.
Given the following code: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=dec1ee3c77e71e10d6217f53ebb0f86f
// Copyright 2022 Google LLC.
// SPDX-License-Identifier: Apache-2.0
struct MyElement;
struct MyContainer {
data: Vec<MyElement>,
}
trait MyIndex<Key> {
type Output<'a> where Self : 'a;
fn my_index(&self, k: Key) -> Self::Output<'_>;
}
impl MyIndex<usize> for MyContainer {
type Output<'a> = &'a MyElement;
fn my_index(&self, n: usize) -> Self::Output {
&self.data[n]
}
}
The current output is:
error[E0107]: missing generics for associated type `MyIndex::Output`
--> src/lib.rs:36:43
|
36 | fn my_index(&self, n: usize) -> Self::Output {
| ^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> src/lib.rs:10:10
|
10 | type Output<'a> where Self : 'a;
| ^^^^^^ --
help: add missing lifetime argument
|
36 | fn my_index(&self, n: usize) -> Self::Output<'a> {
| ~~~~~~~~~~
Ideally the output should look like:
error[E0107]: missing generics for associated type `MyIndex::Output`
--> src/lib.rs:36:43
|
36 | fn my_index(&self, n: usize) -> Self::Output {
| ^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> src/lib.rs:10:10
|
10 | type Output<'a> where Self : 'a;
| ^^^^^^ --
help: add missing lifetime argument
|
36 | fn my_index(&self, n: usize) -> Self::Output<'_> {
| ~~~~~~~~~~
The only difference here is that it suggests using '_
before suggesting it use the lifetime parameter declared in the type definition. It really shouldn't consider any of the generic params in the GAT definition. Note that if I replace it with fn my_index<'b>(&'b self, n: usize) -> Self::Output
or fn my_index<'b>(&self, n: usize) -> Self::Output
, it suggests using 'b
, as expected.