Uh oh!
There was an error while loading. Please reload this page.
Implement underscore lifetimes - #44691
Conversation
rust-highfive
commented
Sep 19, 2017
(rust_highfive has picked a reviewer for you, use r? to override) |
There was a problem hiding this comment.
Feel free to bikeshed this error message (it shows up in code that tries to explicitly bind '_ in the generics of an item declaration).
There was a problem hiding this comment.
An equivalent error is already issued for 'static, so the wording can be reused:
invalid lifetime parameter name: `'static`
arielb1
commented
Sep 19, 2017
r? @eddyb |
There was a problem hiding this comment.
Should be 1.22.0? (BTW match_beginning_vert should also be 1.22.0?)
There was a problem hiding this comment.
I never know what to actually put here.
eddyb
commented
Sep 19, 2017
r=me with build & nit fixed |
There was a problem hiding this comment.
Lifetime definitions can happen in for<'a, 'b, 'c> in fn pointers, trait objects, etc.
It's better to place the error in fn visit_lifetime_def.
petrochenkov
commented
Sep 19, 2017
@cramertj |
0c3b9ef to
942a85cCompareThere was a problem hiding this comment.
So I've never been crazy about using a "sentinel value" here rather than an enum -- now that we've got more than one sentinel, I feel even less good. Can't we change this to something like
enumLifetimeName{Elided,Underscore,Static,Name(Token)// or whatever this is}There was a problem hiding this comment.
It's a Symbol / ast::Name I think.
There was a problem hiding this comment.
...if we were using an enum, this code would be rather cleaner
There was a problem hiding this comment.
can we have some tests that use multiple lifetime parameters in one function? For example:
fnfoo(x:&'_u8,y:&'_u8) -> &'_u8{}// ERROR from elisionfn foo(x:&mutVec<&'_u8>,y:&'_u8){ x.push(y);// ERROR }structFoo<'a,'b>{a:&'au32,b:&'bu32}fnfoo_a<'b>(foo:Foo<'_,'b>) -> &'bu32{&foo.a}// ERRORfnfoo_b<'b>(foo:Foo<'_,'b>) -> &'bu32{&foo.b}// OKnikomatsakis
commented
Sep 19, 2017
@cramertj thanks for jumping on this btw -- so excited to see it land =) |
ac16bad to
c91a1a7CompareThere was a problem hiding this comment.
Nooooo.
This LifetimeName over Name is pure over-engineering, N extra lines of boilerplate just to avoid one string comparison.
There was a problem hiding this comment.
Heh. I don't have any strong opinion here. Take it up with @nikomatsakis 😄
I left it as its own commit so it's easy to pull out if that's the decision.
There was a problem hiding this comment.
I'd better turn '_ into a weak keyword.
There was a problem hiding this comment.
I disagree. Sentinel values mean you wind up with if-else-if chains like if foo.is_elided() { ... } which are easily forgotten. Having an enum means we can use exhaustive matching, so that when we add variants in the future, the compiler helps us catch cases that are missing etc.
Plus, there isn't a lot of boilerplate here.
There was a problem hiding this comment.
@nikomatsakis
Ok, not a big deal.
(I'll revert this when you are on vacation, ha-ha.)
cramertj
commented
Sep 20, 2017
Gah! I didn't try building rustdoc and the others... |
eddyb
commented
Sep 20, 2017
cc @Mark-Simulacrum this is why I have |
c91a1a7 to
051b5cfCompareThere was a problem hiding this comment.
Symbol::intern("'static") => keywords::StaticLifetime.name()
051b5cf to
71c8ad4Comparepetrochenkov
commented
Sep 20, 2017
@cramertj |
bors
commented
Sep 21, 2017
☔ The latest upstream changes (presumably #44551) made this pull request unmergeable. Please resolve the merge conflicts. |
8f5f35c to
31fd099CompareThere was a problem hiding this comment.
@cramertj
Actually, can you tweak the naming slightly.
enumLifetimeKind{// This is not a nameImplicit,// `Elided` is not correct, because implicit can be both elided and inferred, but we don't discern between them yet when lowering into HIRUnderscore,Static,Named(Name),// Named lifetime}There was a problem hiding this comment.
(The variants are going to change anyway when lifetimes are first resolved, then lowered into HIR.)
There was a problem hiding this comment.
I think what we want is name resolution to give us a Def, and the existing resolve_lifetimes pass to do elision and compute the semantic representation from Def::Lifetime(DefId).
There was a problem hiding this comment.
@petrochenkov I don't object to calling "Implicit" for sure, but I'm curious: what does "elided" mean to you? To me, it means "not written". I would then say that the behavior around elided lifetimes depends on context: in function signatures, we use defaulting rules (as specified by the lifetime elision RFCs plus the object-lifetime RFCs), and in function bodies, we use inference.
There was a problem hiding this comment.
Using "elided" to mean literally "not written" may be correct wrt the English language but then "elision rules" doesn't mean much anymore and we have to say "default lifetime rules" I guess? And "lifetime defaulting" for the process of picking a lifetime.
There was a problem hiding this comment.
So personally, when I explain to people, I say something like "sometimes you can elide lifetimes. The meaning of this depends on context. In a function signature, we use the following system of defaults. etc". In other words, I think I do use the terms the way you described. =) But also I rely on context. That is, I might say "elision rules" when it's clear we're talking about function signatures, in which case it just means "defaulting rules" (but including, naturally, the object defaults).
In any case, it seems clear that calling things elided is ripe for confusion. I prefer either "implicit", "not written", or "not present", all of which seem reasonably clear.
There was a problem hiding this comment.
@nikomatsakis
Well, I usually associate "elided" with "lifetime elision RFCs", i.e. "defaulting", not inference.
It's useful to have some separate words for "not-written-in-signature" and "not-written-in-body", and "elided" and "inferred" already kinda serve this purpose given that "lifetime elision" is commonly used to describe what happens in signatures.
There was a problem hiding this comment.
That makes some sense. I guess I prefer to have words that match their English meanings to the extent possible, though, and to me "elided" just means "not written" (whereas "defaulted" seems more specific -- we assigned it a default value). I admit that the distinction between defaulted (based on some simple rules) and inferred (based on complex analysis) is a subtle one as well. =)
There was a problem hiding this comment.
Regardless, the question at hand is whether to use elided here with the broader meaning, right? In which case, "Implicit" or "Not written" seems fine.
31fd099 to
f5505d1Comparenikomatsakis
commented
Sep 21, 2017
@bors r+ |
bors
commented
Sep 21, 2017
📌 Commit f5505d1 has been approved by |
bors
commented
Sep 22, 2017
Implement underscore lifetimes Part of #44524
bors
commented
Sep 22, 2017
☀️ Test successful - status-appveyor, status-travis |
Part of #44524