Skip to content

overly restrictive closure borrow-checking #104477

Open
@aliemjay

Description

@aliemjay

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 returns None in this case!
  • The different behavior in case1 when swapping arguments is due to the shortcut in
    if representative != longer_fr {
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)A-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.NLL-completeWorking towards the "valid code works" goalT-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions