Skip to content

Self::call constrains lifetime covariance and/or inference unexpectedly under NLL #62185

Open
@pnkfelix

Description

@pnkfelix

Spawned off of #60914, namely the regression of the version-compare crate

Look at this (play):

use std::slice::Iter;

pub struct Version<'a> {
    parts: Vec<&'a str>,
}

impl<'a> Version<'a> {
    pub fn compare(&self, other: &Version) {
        Self::compare_iter(self.parts.iter(),  other.parts.iter())
    }
    
    fn compare_iter(_: Iter<&'a str>, _: Iter<&'a str>) { }
}

we get an NLL migration error for it.

  • (The use of Self::compare_iter is important on line 9; if you replace that with Version::compare_iter, then NLL will accept the input.)
  • ((Likewise, the input is accepted if you get rid of the 'a's in the formal parameters to fn compare_iter, but that is perhaps less surprising.))

Why? I'm not sure; at first I thought it made sense, since I assumed that the call to Self::compare_iter would force the two arguments to have the same lifetime 'a that is also attached to the self parameter.

But after reflecting on the matter further, I do not understand why we would not have a reborrow here that would allow the call to compare_iter to use a shorter lifetime that both inputs can satisfy.

  • (Or, wait: Is std::slice::Iter<T> not covariant with respect to T? I guess I'll need to check that.)

Anyway, this is either a soundness fix of AST borrow-check (which would be great news), or it is an NLL-complete bug for MIR borrow-check.

I just didn't want it to get lost in the shuffle of a blog post I am currently working on.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)T-compilerRelevant to the compiler 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