Open
Description
Both of these test cases should pass borrowck: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2015&gist=50a263a9626cb0b08f5cee334df8a852
mod case1 {
struct MyTy<'x, 'a, 'b>(std::cell::Cell<(&'x &'a u8, &'x &'b u8)>);
fn wf<T>(_: T) {}
fn test<'a, 'b>() {
|_: &'a u8, x: MyTy<'_, 'a, 'b>| wf(x); // FAIL!
|x: MyTy<'_, 'a, 'b>, _: &'a u8| wf(x); // PASS!!!
}
}
mod case2 {
struct MyTy<'a, 'b, 'x>(std::cell::Cell<(&'a &'x u8, &'b &'x u8)>);
fn wf<T>(_: T) {}
fn test<'a, 'b>() {
|x: MyTy<'a, 'b, '_>| wf(x); // FAIL!
}
}
They both fail because of the unnecessarily restrictive algorithm in try_propagate_universal_region_error:
case1
fails because'_
has multiple "non-local upper bounds"['a, 'b]
and we do propagate the error to both of them while choosing a single one would be sufficient.case2
fails because'_
has multiple "non-local lower bounds"['a, 'b]
and the call to non_lcal_lower_bound simply returnsNone
in this case!- The different behavior in
case1
when swapping arguments is due to the shortcut in which is sensitive to region numbering, but I think that's irrelevant here.
@rustbot label C-bug T-types A-NLL NLL-complete A-borrow-checker
@rustbot claim