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

lifetime inference fails on *const &'a T but succeeds for *mut &'a T -- why? #21422

Closed
pnkfelix opened this issue Jan 20, 2015 · 4 comments
Closed
Assignees
Labels
A-lifetimes Area: lifetime related

Comments

@pnkfelix
Copy link
Member

Intuitively, I would think that replacing an occurrence of *mut T with *const T is just loosening constraints.

Unfortunately, if you remove too many constraints, apparently lifetime inference fails.

Here is an example reduced down from my attempt to make Rc<T>/Box<T>/Vec<T> all covariant in T and get rustc bootstrapping:

pub struct P<'a> {
    #[cfg(not(use_mut))]
    _ptr: *const &'a u8,
    #[cfg(use_mut)]
    _ptr: *mut &'a u8,
}

impl <'a> PartialEq for P<'a> {
    fn eq(&self, other: &P<'a>) -> bool {
        (self as *const _) == (other as *const _)
    }
}

fn main() {}

Transcript of compilation attempts:

% rustc --version
rustc 1.0.0-dev (71a71ce4f 2015-01-11 09:01:00 +0000)
% rustc --cfg use_mut /tmp/isolate-infer2.rs
% rustc --cfg use_const /tmp/isolate-infer2.rs
/tmp/isolate-infer2.rs:10:9: 11:6 error: cannot infer an appropriate lifetime due to conflicting requirements
/tmp/isolate-infer2.rs:10         (self as *const _) == (other as *const _)
/tmp/isolate-infer2.rs:11     }
/tmp/isolate-infer2.rs:10:9: 10:30 note: first, the lifetime must be contained by the expression at 10:8...
/tmp/isolate-infer2.rs:10         (self as *const _) == (other as *const _)
                                  ^~~~~~~~~~~~~~~~~~~~~
/tmp/isolate-infer2.rs:10:9: 10:30 note: ...so type `*const P<'_>` of expression is valid during the expression
/tmp/isolate-infer2.rs:10         (self as *const _) == (other as *const _)
                                  ^~~~~~~~~~~~~~~~~~~~~
/tmp/isolate-infer2.rs:10:31: 11:6 note: but, the lifetime must also be contained by the expression at 10:30...
/tmp/isolate-infer2.rs:10         (self as *const _) == (other as *const _)
/tmp/isolate-infer2.rs:11     }
/tmp/isolate-infer2.rs:10:31: 11:6 note: ...so type `*const P<'_>` of expression is valid during the expression
/tmp/isolate-infer2.rs:10         (self as *const _) == (other as *const _)
/tmp/isolate-infer2.rs:11     }
error: aborting due to previous error
@pnkfelix
Copy link
Member Author

Update: It appears that feeding a bit more type information into the body of PartialEq::eq gives the lifetime inference what it needs to know:

impl <'a> PartialEq for P<'a> {
    fn eq(&self, other: &P<'a>) -> bool {
        // (self as *const _) == (other as *const _)
        (self as *const P<'a>) == (other as *const P<'a>)
    }
}

This is probably enough to let me make progress on the above mentioned bootstrapping. So maybe this bug is not as important to fix as I thought it was.

Still, it is strange that (I assume) the variance of P<'a> with respect to 'a has an effect in this case, where the type on both sides of the == has been written as just *const _, and thus it is strange to that an covariant P fails while an invariant P succeeds.

@pnkfelix
Copy link
Member Author

(cc @nikomatsakis )

@Gankra Gankra added A-amusing A-lifetimes Area: lifetime related labels Jan 21, 2015
@nikomatsakis
Copy link
Contributor

The problem here is a missing constraint. For some reason I was seeing this on my variance branch but now I'm not. I'll investigate it more in a bit.

@nikomatsakis
Copy link
Contributor

Fixed on my variance branch.

@nikomatsakis nikomatsakis self-assigned this Feb 13, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: lifetime related
Projects
None yet
Development

No branches or pull requests

3 participants