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

back-noncompat error about lifetimes #43372

Closed
donhcd opened this issue Jul 20, 2017 · 5 comments
Closed

back-noncompat error about lifetimes #43372

donhcd opened this issue Jul 20, 2017 · 5 comments
Labels
A-lifetimes Area: Lifetimes / regions C-bug Category: This is a bug. P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Milestone

Comments

@donhcd
Copy link

donhcd commented Jul 20, 2017

Probably the easiest way to see this is to run it on playground, but I'll copy the code onto here as well.

static X: usize = 3;

fn x() -> &'static usize {
    &X
}

fn foo(y: Option<&usize>) -> &usize {
    y.unwrap_or_else(x)
}

fn main() {
    foo(None);
}

This code compiles and runs fine on stable, but fails to compile in beta and nightly with

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
 --> src/main.rs:8:7
  |
8 |     y.unwrap_or_else(x)
  |       ^^^^^^^^^^^^^^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 7:1...
 --> src/main.rs:7:1
  |
7 | / fn foo(y: Option<&usize>) -> &usize {
8 | |     y.unwrap_or_else(x)
9 | | }
  | |_^
note: ...so that types are compatible (expected std::option::Option<&usize>, found std::option::Option<&usize>)
 --> src/main.rs:8:7
  |
8 |     y.unwrap_or_else(x)
  |       ^^^^^^^^^^^^^^
  = note: but, the lifetime must be valid for the static lifetime...
note: ...so that types are compatible (expected &'static usize, found &usize)
 --> src/main.rs:8:7
  |
8 |     y.unwrap_or_else(x)
  |       ^^^^^^^^^^^^^^

error: aborting due to previous error

Apologies if this has already been reported - I searched a bit but didn't see anything like it

@hanna-kruppe
Copy link
Contributor

cc @eddyb could this be a consequence of #42417?

@eddyb
Copy link
Member

eddyb commented Jul 21, 2017

@rkruppe Indeed - with no code left in the wild being affected (at least as far as cargobomb can tell us), and with the potential solution I came up turning out unsound, we decided to be conservative.

This can be considered an inference bugfix, where previously typeof x (the argument) was inferred to be different (and be usable with a lifetime shorter than 'static) than the function itself.

The solution, in user code, is to write fn x<'a>() -> &'a usize instead, which, for unwrap_or_else, implements FnOnce() -> &'a usize (with 'a inferred separately each time x is mentioned), rather than FnOnce() -> &'static usize.

Having more variance (or even coercion support!) specifically in convenience methods like Option's unwrap_or_else would probably be the "right" approach here.
match self { Some(x) => x, None => f() } already coerces x and f() to a common type, if it can, but we have no way to express this in bounds (and not really any good way to then satisfy them).

@Mark-Simulacrum Mark-Simulacrum added A-lifetimes Area: Lifetimes / regions regression-from-stable-to-beta Performance or correctness regression from stable to beta. I-nominated P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Jul 26, 2017
@michaelwoerister michaelwoerister added T-lang Relevant to the language team, which will review and decide on the PR/issue. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 10, 2017
@michaelwoerister
Copy link
Member

Discussed in the compiler team meeting. We decided to let the lang team take a look at it.

@alexcrichton alexcrichton modified the milestone: 1.20 Aug 23, 2017
@alexcrichton alexcrichton added regression-from-stable-to-stable Performance or correctness regression from one stable version to another. and removed regression-from-stable-to-beta Performance or correctness regression from stable to beta. labels Aug 28, 2017
@alexcrichton
Copy link
Member

1.20 will soon be stable

@aturon
Copy link
Member

aturon commented Oct 19, 2017

Lang team meeting: this is an ~intended, conservative fix, which has at this point shipped. While at some point we might be able to soundly support this use case, it will need additional design. Closing for the time being.

@aturon aturon closed this as completed Oct 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: Lifetimes / regions C-bug Category: This is a bug. P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants