Stream: t-compiler/wg-nll

Topic: #53528 impl Trait: borrowck error on else branch


Basile Desloges (Sep 05 2018 at 10:11, on Zulip):

https://github.com/rust-lang/rust/issues/53528

I'm not sure what to make of it, but it seems this error might be related to lifetime annotation.

In particular, with this example :

#![feature(nll)]

trait Trait1 {
    type Item;
}
impl<'a> Trait1 for &'a u32 {
    type Item = &'a u32;
}

trait Trait2 {
}
impl<'a> Trait2 for &'a u32 {
}

struct Y(u32);
impl Y {
    // Error
    fn get<'a>(&'a self) -> Option<impl Trait1<Item=&'a u32>> {
    // fn get<'a>(&'a self) -> Option<impl Trait2 + 'a> {
    // No errors
    // fn get(&self) -> Option<&u32> {
        Some(&self.0)
    }

    fn set(&mut self, y: u32) {
        self.0 = y;
    }
}

pub fn test_iflet() {
    let mut tmp = Y(0);

    if let Some(_xx) = tmp.get() {
        // error[E0597]: `tmp` does not live long enough
    } else {
        tmp.set(2);
        // error[E0502]: cannot borrow `tmp` as mutable because it is also borrowed as immutable
    }

    // "tmp does not live long enough" when commenting the following line
    tmp.get();
}

We can see in the logs and the MIR that the 'a lifetime seems to be missing with Trait1 and Trait2. For instance:

DEBUG 2018-09-05T10:04:14Z: rustc_mir::borrow_check::nll::universal_regions: defining_ty (pre-replacement): for<'a> fn(&'a Y) -> std::option::Option<impl Trait1> {Y::get}

vs

DEBUG 2018-09-05T10:09:44Z: rustc_mir::borrow_check::nll::universal_regions: defining_ty (pre-replacement): for<'r> fn(&'r Y) -> std::option::Option<&'r u32> {Y::get}

Could that be the source of the problem?

Last update: Nov 21 2019 at 14:40UTC