-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
'missing lifetime specifier' regression in protobuf-1.0.1 #27248
Comments
Reduces to: trait T:'static {}
fn main() {
fn _message_down_cast(_m: &T) -> &i8 {
panic!()
}
} |
RFC 141 says that "a lifetime position is anywhere you can write a lifetime in a type". According to that rule, On the other hand, I'm pretty sure that isn't actually what we want, so we need a more precise rule which specifies exactly what lifetimes qualify as a "lifetime position". Other random observations: nightly accepts the following, but stable doesn't: fn main() {
type T<'a> = &'a &'a i8;
fn s(m: T) -> &i8 { m }
static S: i8 = 1;
static S2: &'static i8 = &S;
s(&S2);
} Neither nightly nor stable accept the following: fn main() {
type T<'a> = &'a &'static i8;
fn s(m: T) -> &i8 { m }
static S: i8 = 1;
static S2: &'static i8 = &S;
s(&S2);
} |
I think I accidentally introduced the regression as part of #26667. The previous version ignored object lifetime bounds - I should have caught this. I think the root cause here is that lifetime elision wasn't updated to respect object bounds. |
@nikomatsakis Per irlo this seems to affect some crates. Is there any way we can get this fixed this week in time for beta, or if not sometime in the next cycle for a backport? |
cc @rust-lang/compiler |
triage: P-high |
Sorry, I dropped the ball on compiler triage, but trying to get that wagon back on track now. Anyway, I'll look at this. |
Ah, yes, I remember this issue now. I think this relates to the discussion about |
To be more specific, I think the rule we want is that object lifetimes only affect the elision rules if they are written explicitly, and not if defaults are used. I have to investigate how easy that will be to implement. |
cc @rust-lang/lang -- see previous two comments |
also cc @wycats -- see previous two comments |
OK, as I thought, the elision determination is made based on the I think that approaching this basic on the position where the lifetime appears is probably best. However, one might also approach by making special treatment for struct Foo<'s> { x: &'s i32 }
fn foo(x: &Foo<'static>) -> &Foo<'static> { x }
fn main() { } But it does not today, since there are two lifetimes (in principle) one might choose in the return type: the anonymous one, or (Mostly just thinking through the possibilities here, not endorsing a plan of action.) |
I'm going to re-nominate, but this time for |
This is going into stable. |
Note: we need to discuss the logistics that let this slip through and try to make sure it doesn't happen again. |
If we want to change this, it probably requires an RFC. The rules as they are today are somewhat confusing, which is somewhat inevitable with the invisible trait lifetime bounds. The new rules means that code like fn foo(t: Box<Trait>) -> &u8 will compile with the interpretation Because duplicate lifetimes are ignored, this code can only cause an issue if either the user explicitly specifies an object lifetime bound (e.g. My preferred solution is to prevent elision to |
We discussed in the language subteam meeting today and reached the conclusions that:
To that end, I'm going to close this issue and open (shortly) an RFC issue with a summary of the various cases that arise and the proposed solutions. |
As reported by crater, Rust 1.3 nightlies appear to have introduced a regression in lifetime elision, probably related to default trait bounds.
cc @nikomatsakis @nrc @pnkfelix
Nominating in hopes a fix for this will appear before 1.3 beta.
The text was updated successfully, but these errors were encountered: