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

NLL regresses diagnostic for impl-trait/static-return-lifetime-infered.rs #53771

Closed
pnkfelix opened this issue Aug 28, 2018 · 1 comment
Closed
Assignees
Labels
A-NLL Area: Non Lexical Lifetimes (NLL) NLL-diagnostics Working torwads the "diagnostic parity" goal

Comments

@pnkfelix
Copy link
Member

Consider this code from static-return-lifetime-infered.rs (play):

// #![feature(nll)]

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

impl A {
    fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
        self.x.iter().map(|a| a.0)
    }
    //~^^ ERROR cannot infer an appropriate lifetime
    fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
        self.x.iter().map(|a| a.0)
    }
    //~^^ ERROR cannot infer an appropriate lifetime
}

fn main() {}

Part of the diagnostic info you get is this useful help message:

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 8:5
  |
8 |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
  |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Unfortunately, under #![feature(nll)], we fail to produce that help diagnostic (play):

error: unsatisfied lifetime constraints
 --> src/main.rs:9:9
  |
8 |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
  |                         - let's call the lifetime of this reference `'1`
9 |         self.x.iter().map(|a| a.0)
  |         ^^^^^^^^^^^^^ requires that `'1` must outlive `'static`

error: unsatisfied lifetime constraints
  --> src/main.rs:13:9
   |
12 |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
   |                    -- lifetime `'a` defined here
13 |         self.x.iter().map(|a| a.0)
   |         ^^^^^^^^^^^^^ requires that `'a` must outlive `'static`

error: aborting due to 2 previous errors

"Luckily", this does not need to be a high priority issue for us to resolve, because in the special "migration" mode for NLL (which you can observe today by opting into the 2018 edition), we do produce the help message (play):

error: cannot infer an appropriate lifetime
 --> src/main.rs:9:16
  |
8 |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
  |                                   ----------------------- this return type evaluates to the `'static` lifetime...
9 |         self.x.iter().map(|a| a.0)
  |         ------ ^^^^
  |         |
  |         ...but this borrow...
  |
note: ...can't outlive the anonymous lifetime #1 defined on the method body at 8:5
 --> src/main.rs:8:5
  |
8 | /     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
9 | |         self.x.iter().map(|a| a.0)
10| |     }
  | |_____^
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 8:5
  |
8 |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
  |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: cannot infer an appropriate lifetime
  --> src/main.rs:13:16
   |
12 |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
   |                                     ----------------------- this return type evaluates to the `'static` lifetime...
13 |         self.x.iter().map(|a| a.0)
   |         ------ ^^^^
   |         |
   |         ...but this borrow...
   |
note: ...can't outlive the lifetime 'a as defined on the method body at 12:20
  --> src/main.rs:12:20
   |
12 |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
   |                    ^^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the method body at 12:20
   |
12 |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors
@pnkfelix pnkfelix changed the title NLL regresses help info for ui/impl-trait/static-return-lifetime-infered.rs NLL regresses help diagnostic for ui/impl-trait/static-return-lifetime-infered.rs Aug 28, 2018
@pnkfelix pnkfelix changed the title NLL regresses help diagnostic for ui/impl-trait/static-return-lifetime-infered.rs NLL regresses diagnostic for impl-trait/static-return-lifetime-infered.rs Aug 28, 2018
@pnkfelix pnkfelix added the NLL-diagnostics Working torwads the "diagnostic parity" goal label Aug 28, 2018
@pnkfelix pnkfelix added the A-NLL Area: Non Lexical Lifetimes (NLL) label Aug 28, 2018
@estebank
Copy link
Contributor

For reference, that suggestion was implemented in #51444, the NLL suggestion will have to follow the same/similar logic.

@davidtwco davidtwco self-assigned this Sep 1, 2018
bors added a commit that referenced this issue Sep 18, 2018
NLL regresses diagnostic for impl-trait/static-return-lifetime-infered.rs

Fixes #53771.

r? @nikomatsakis
cc @pnkfelix @estebank
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non Lexical Lifetimes (NLL) NLL-diagnostics Working torwads the "diagnostic parity" goal
Projects
None yet
Development

No branches or pull requests

3 participants