region-outlives obligations lead to uninformative/undecipherable region inference failures
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
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
Dropdue to ... well, due to a potentially-related problem.)Felix S Klock II at 2015-03-21 17:08:17
Triage: no changes here.
Steve Klabnik at 2016-06-06 20:59:34
Triage: no change
Steve Klabnik at 2019-12-25 16:16:34
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>`Esteban Kuber at 2022-06-08 21:35:25