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

Issue 7331 #9841

Closed
wants to merge 3 commits into from
Closed

Issue 7331 #9841

wants to merge 3 commits into from

Conversation

dwrensha
Copy link
Contributor

Closes #7331.

Motivating example:

trait FromVec<'self> {
    fn fromVec(&'self [u8]) -> Self;
}

struct Reader<'self> {
    v : &'self [u8]
}

impl <'self> FromVec<'self> for Reader<'self> {
    fn fromVec(v : &'self [u8]) -> Reader<'self> {
        Reader::<'self> { v : v }
    }
}

impl <'self, T : FromVec<'self>> Reader<'self> {
    fn get(self) -> T {
        FromVec::fromVec(self.v);
    }
}

When we typecheck FromVec::fromVec, we get fn(&'self [u8]) -> T where T is bounded by FromVec<'self>. Usually we would replace the argument's 'self with a new region variable which could match anything. However, if we allow that here then we lose an important constraint between the argument and the return type T, namely that the 'self in FromVec<'self> needs to be the same as the argument's 'self.

In this patch, I handle this case by replacing the argument's 'self with the free region that has already been constructed for 'self in the enclosing scope.

Note that I remove the region param from static trait methods (line 360 of collect.rs). The main motivation for that change is to provide a more sensible error message on something like FromVec::fromVec::<'self>(self.v), which would otherwise confusingly yield the error message "this trait has a lifetime parameter but no lifetime was specified". Moreover, although it could be argued that these methods technically still are region-parameterized, the actual plugged-in region is always the same thing---a free region associated with 'self; I think it's prudent to syntactically prevent anyone from trying to plug anything else in.

@dwrensha
Copy link
Contributor Author

cc @nikomatsakis

@nikomatsakis
Copy link
Contributor

Sorry, this slipped off my radar. I will review.

@dwrensha
Copy link
Contributor Author

Thanks for taking a look!

Imagine a hypothetical future Rust where we could write this function:

fn fromVecBare<'a, T : FromVec<'a>>(v : &'a [u8]) -> T {
   FromVec::fromVec::<for T>(v)
}

Would it be correct to make a fresh region variable when we are typechecking the call FromVec::fromVec::<for T>(v)?

It seems to me that the answer is "no", because the trait bound FromVec<'a> on T is explicitly constrained to use the region variable 'a which is bound at the function definition.

In today's Rust, the only region variable allowed to be used by the trait bounds of a type variable bound at a function definition, like T, is 'self. So 'self will always be exactly the region we want.

More pressingly, with the current way of doing things, the typechecker rejects programs that seem perfectly fine to me, such as the motivating example at the top of this thread. I wrote out the error message here: https://mail.mozilla.org/pipermail/rust-dev/2013-September/005758.html

@dwrensha
Copy link
Contributor Author

Looks like #10153 (which is a really great feature addition--thanks Niko!) invalidates my assumptions and obsoletes this pull request.

It appears that the problem persists, but now it's harder to solve.

@dwrensha dwrensha closed this Nov 10, 2013
flip1995 pushed a commit to flip1995/rust that referenced this pull request Jul 11, 2024
…ednet

Fix some false-positive cases of `explicit_auto_deref`

changelog: [`explicit_auto_deref`] Fix some false-positive cases

Fix part of rust-lang#9841
Fix  rust-lang#12969

r? xFrednet
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Region#subst ICE with certain uses of 'self
2 participants