Skip to content

GAT in path suggests wrong lifetime name when elided lifetime is rejected #103815

Closed
@kupiakos

Description

@kupiakos

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)A-diagnosticsArea: Messages for errors, warnings, and lintsF-generic_associated_types`#![feature(generic_associated_types)]` a.k.a. GATsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions