Skip to content

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

New issue

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

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

Already on GitHub? # to your account

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>`

# for free to join this conversation on GitHub. Already have an account? # 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