Skip to content

Borrow checker determines borrows by examining lifetime parameters on unexpanded associated types instead of inspecting their lifetime bounds #50029

Closed

Description

@dylanede

Consider the following (playpen):

trait Foo<'a> {
    type Out: 'a;
}

fn foo<'a, T>(_: &'a mut T) -> <T as Foo<'a>>::Out where T : Foo<'a> {
    unimplemented!()
}

fn baz<T>(mut x: T) where for<'a> T : Foo<'a>, for<'a> <T as Foo<'a>>::Out : 'static {
    let y = foo(&mut x);
    let z = foo(&mut x);
}

fn main() {
    struct Bar;
    impl<'a> Foo<'a> for Bar {
        type Out = i32;
    }
    let mut b = Bar;
    let y = foo(&mut b);
    let z = foo(&mut b);
}

main compiles fine, as expected, since the associated type expands to i32, which does not use the lifetime 'a that the mutable reference input argument is bound by.

baz however fails to compile (error message below), despite the additional constraint on Out to be 'static, implying that the return value of foo does not borrow the argument.

error[E0499]: cannot borrow `x` as mutable more than once at a time
  --> src/main.rs:11:22
   |
10 |     let y = foo(&mut x);
   |                      - first mutable borrow occurs here
11 |     let z = foo(&mut x);
   |                      ^ second mutable borrow occurs here
12 | }
   | - first borrow ends here

This problem appears to be unique to unexpanded associated types, as they are the only case where the lifetime parameters do not directly determine the lifetime bounds on the type.

Activity

  1. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    T-langRelevant to the language team
    on Aug 27, 2018
  2. oskgo commented on Jan 25, 2024

    @oskgo
    Contributor

    No longer reproduces. Fixed by #116733.

    searched nightlies: from nightly-2023-05-23 to nightly-2024-01-23
    regressed nightly: nightly-2023-10-30
    searched commit range: e5cfc55...608e968
    regressed commit: ec2b311

    bisected with cargo-bisect-rustc v0.6.7

    Host triple: x86_64-pc-windows-msvc
    Reproduce with:

    cargo bisect-rustc success --start=2023-05-23 --end=2024-01-23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions