Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

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

Closed
dylanede opened this issue Apr 17, 2018 · 1 comment
Labels
A-borrow-checker Area: The borrow checker C-enhancement Category: An issue proposing an enhancement or a PR with one. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@dylanede
Copy link
Contributor

dylanede commented Apr 17, 2018

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.

@XAMPPRocky XAMPPRocky added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-borrow-checker Area: The borrow checker T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Aug 27, 2018
@oskgo
Copy link
Contributor

oskgo commented Jan 25, 2024

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

@Enselic Enselic closed this as completed Feb 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker C-enhancement Category: An issue proposing an enhancement or a PR with one. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants