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

Comments

Projects
None yet
4 participants
@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.

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented Aug 30, 2017

Looks like a duplicate of #38615

@estebank

This comment has been minimized.

Copy link
Contributor

estebank commented Feb 27, 2018

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

Auto merge of #51444 - estebank:impl-static, r=nikomatsakis
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> + '_ {
   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

@bors bors closed this in #51444 Jun 28, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment