Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"only named lifetimes allowed in impl Trait" could have a better error message #43719

Closed
Manishearth opened this issue Aug 7, 2017 · 2 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-diagnostics Working group: Diagnostics

Comments

@Manishearth
Copy link
Member

Manishearth commented Aug 7, 2017

struct A {
    x: [(u32, u32); 10]
}

impl A {
    
    fn iter_values(&self) -> impl Iterator<Item=u32>{
        self.x.iter().map(|a| a.0)
    }
}

gives the error:

error[E0564]: only named lifetimes are allowed in `impl Trait`, but `` was found in the type `std::iter::Map<std::slice::Iter<'_, (u32, u32)>, [closure@src/main.rs:12:27: 12:34]>`
  --> src/main.rs:11:30
   |
11 |     fn iter_values(&self) -> impl Iterator<Item=u32>{
   |                              ^^^^^^^^^^^^^^^^^^^^^^^

The correct fix is fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a (or use into_iter, but that's not always an option), however this error message has no indication that this is the way to go in, in fact not many people are aware of the Trait + 'a syntax. We probably can do better.

@Manishearth Manishearth added A-diagnostics Area: Messages for errors, warnings, and lints A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. labels Aug 7, 2017
@Mark-Simulacrum Mark-Simulacrum added C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 10, 2017
@gnzlbg
Copy link
Contributor

gnzlbg commented Aug 30, 2017

Looks like a duplicate of #38615

@estebank
Copy link
Contributor

Current output:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/main.rs:10:16
   |
10 |         self.x.iter().map(|a| a.0)
   |                ^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 9:5...
  --> src/main.rs:9:5
   |
9  | /     fn iter_values(&self) -> impl Iterator<Item=u32>{
10 | |         self.x.iter().map(|a| a.0)
11 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:10:9
   |
10 |         self.x.iter().map(|a| a.0)
   |         ^^^^^^
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that return value is valid for the call
  --> src/main.rs:9:30
   |
9  |     fn iter_values(&self) -> impl Iterator<Item=u32>{
   |                              ^^^^^^^^^^^^^^^^^^^^^^^

bors added a commit that referenced this issue Jun 28, 2018
Suggestion for 'static impl Trait return

When encountering a named or anonymous sup requirement (for example,
`&'a self`) and a `'static` impl Trait return type, suggest adding the
`'_` lifetime constraing to the return type.

Fix #43719, #51282.

```
error: cannot infer an appropriate lifetime
  --> $DIR/static-return-lifetime-infered.rs:17:16
   |
LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
   |                                   ----------------------- this return type evaluates to the `'static` lifetime...
LL |         self.x.iter().map(|a| a.0)
   |         ------ ^^^^
   |         |
   |         ...but this borrow...
   |
note: ...can't outlive the anonymous lifetime #1 defined on the method body at 16:5
  --> $DIR/static-return-lifetime-infered.rs:16:5
   |
LL | /     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
LL | |         self.x.iter().map(|a| a.0)
LL | |     }
   | |_____^
help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 16:5
   |
LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-diagnostics Working group: Diagnostics
Projects
None yet
Development

No branches or pull requests

4 participants