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

region-outlives obligations lead to uninformative/undecipherable region inference failures #23581

Open
pnkfelix opened this issue Mar 21, 2015 · 4 comments
Labels
A-borrow-checker Area: The borrow checker A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@pnkfelix
Copy link
Member

Consider this program:

use std::cell::Cell;
trait Foo { fn foo(&mut self); }
struct Pair<'a,'b> { x: &'a Cell<u8>, y: &'b Cell<u8> }

// This impl says it callers of `foo` on `Pair<'a,'b>` must ensure
// that 'b outlives 'a.
impl<'a, 'b:'a> Foo for Pair<'a, 'b> {
    fn foo(&mut self) {
        println!("pre  x: {} y: {}", self.x.get(), self.y.get());
        // 'b outlives 'a, so `&'b Cell<u8> <: &'a Cell<u8>`
        self.x = self.y;
        println!("post x: {} y: {}", self.x.get(), self.y.get());
    }
}

impl<'a,'b> Pair<'a,'b> {
    fn bar(&mut self) {
        self.foo();
    }
}

fn baz<'a,'b>(pa: &'a Cell<u8>, pb: &'b Cell<u8>) {
    let mut p = Pair { x: pa, y: pb };
    p.bar();
}

fn main() {
    let a = Cell::new(1);
    let b = Cell::new(2);
    let pa = &a;
    let pb = &b;
    baz(pa, pb);
}

This yields the following error (playpen):

<anon>:18:14: 18:19 error: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
<anon>:18         self.foo();
                       ^~~~~
<anon>:17:5: 19:6 help: consider using an explicit lifetime parameter as shown: fn bar(&mut self)
<anon>:17     fn bar(&mut self) {
<anon>:18         self.foo();
<anon>:19     }
error: aborting due to previous error
playpen: application terminated with error code 101

There is no mention of the region constraint on the impl providing foo that is causing calling foo from bar to fail.

cc @nikomatsakis

@pnkfelix
Copy link
Member Author

Also, the test case above is the result of my trying to determine whether we need to special-case the handling of region-outlives constraints in my code to address #8142 , because the current trait + obligation machinery does not seem to currently have a way to produce a hard-error in such cases. Instead it seems like it always generates a subregion constraint and lets the downstream region inference code determine that the resulting constraint set is unsatisfiable

(Update: moved the rest of my comment into a comment on #8142, once I determined that one can indeed observe unsoundness in Drop due to ... well, due to a potentially-related problem.)

@steveklabnik
Copy link
Member

Triage: no changes here.

@Mark-Simulacrum Mark-Simulacrum added A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Jul 22, 2017
@steveklabnik
Copy link
Member

Triage: no change

@jonas-schievink jonas-schievink added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. D-confusing Diagnostics: Confusing error or lint that should be reworked. labels Dec 25, 2019
@estebank
Copy link
Contributor

estebank commented Jun 8, 2022

Current output:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
  --> src/main.rs:18:14
   |
18 |         self.foo();
   |              ^^^
   |
note: first, the lifetime cannot outlive the lifetime `'b` as defined here...
  --> src/main.rs:16:9
   |
16 | impl<'a,'b> Pair<'a,'b> {
   |         ^^
note: ...but the lifetime must also be valid for the lifetime `'a` as defined here...
  --> src/main.rs:16:6
   |
16 | impl<'a,'b> Pair<'a,'b> {
   |      ^^
note: ...so that the types are compatible
  --> src/main.rs:18:14
   |
18 |         self.foo();
   |              ^^^
   = note: expected `<Pair<'a, 'b> as Foo>`
              found `<Pair<'_, '_> as Foo>`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants