-
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
Support generic lifetime arguments in method calls #42492
Conversation
cc @nikomatsakis Whom I've discussed this with previously. So I'm not sure I still have them somewhere, but I've done a crater run on a stricter version of this (just banning lifetimes) and found a few problems, mostly related to the fact that late-bound lifetimes do not appear in There were some ideas to prevent explicit lifetimes when any ended up being late-bound, or outright support them (after #42417 we could start playing with that idea). |
So I am pretty nervous about exposing only the early-bound lifetimes. This ties in to that other issue, where we do allow such regions sometimes. I really would prefer it we only allow users to manually specify regions when they are all early-bound, so we can do it realiably and in a clearly forwards compatible way. |
I'll implement this then for both method calls and UFCS as a deny-by-default lint for cratering. |
Discussed in the @rust-lang/lang meeting -- we agree that restricting to 100% early-bound is the right thing here. |
ping @petrochenkov, just wanted to keep this on your radar! |
☔ The latest upstream changes (presumably #42856) made this pull request unmergeable. Please resolve the merge conflicts. |
I've almost submitted an update implementing #42492 (comment), but then realized that late bound lifetime parameters can be defined implicitly through lifetime elision (e.g. |
You can detect them but I wouldn't consider them parameters for the purposes of paths, as I wouldn't an |
It's just strange that these two functions are identical fn late_explicit<'early, 'late>(_: &'late u8) -> &'early u8 { loop {} }
fn late_implicit<'early >(_: & u8) -> &'early u8 { loop {} } , but (I suppose turning |
IMO there is no other real choice if we want the explicitly written parameters to mean anything. |
I'm not sure what do you mean. (I'm still going to check for implicit parameters, at least to look at what crater will say.) |
@petrochenkov I meant that I don't think we can reasonably let you write anything other than what is present between But I suppose I'm okay with going the even more conservative route of banning explicit parameters of a certain kind when there are implicit ones of that kind which could be later made explicit. |
I believe I've extracted all the necessary logic to catch late bound parameters from (There's also an interesting case with lifetimes in struct/variant constructors which are currently treated as early bound (#30904), but I haven't touched it, only added a test.) |
Started crater run. |
Crater run failed due to the inclusion of cc @rust-lang/dev-tools |
@petrochenkov Started another crater run. |
Third crater report shows 4 regressions. |
I guess this is waiting on review? Or perhaps a decision from the lang team? |
I think the relevant decisions have all been made -- we want to limit explicit lifetimes to cases that have only early-bound lifetimes for now (which are clearly backwards compatible). However, I'm not sure of the current back-and-forth between @eddyb and @petrochenkov on the state of the PR itself, it seems like they are iterating on crater runs. As an aside, @brson has been complaining to me that people still use crater, and suggesting that we should try to do some cargobomb runs for better coverage. @brson-- who should be ping to try and get that going? |
The iteration is complete, all found regressions and mistakes are fixed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I skimmed mostly, given that there has been so much back and forth, but this looks good to me. r=me once we change to warn-by-default (I expect this is what was intended, right?)
src/librustc/lint/builtin.rs
Outdated
@@ -205,6 +205,12 @@ declare_lint! { | |||
} | |||
|
|||
declare_lint! { | |||
pub LATE_BOUND_LIFETIME_ARGUMENTS, | |||
Deny, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really want to default to Deny
here?
Fix treatment of lifetimes defined in nested types during detection of late bound regions in signatures. Do not replace substs with inference variables when "cannot specify lifetime arguments explicitly..." is reported as a lint.
The lint level is changed to warn-by-default. |
📌 Commit 39114f9 has been approved by |
⌛ Testing commit 39114f9 with merge 7c758abdad01aaa219c2cb14e4ed6878fb69c236... |
💔 Test failed - status-travis |
@bors: retry
|
⌛ Testing commit 39114f9 with merge 29d60228266412b6bee73098d00ef185d781a8f3... |
💔 Test failed - status-travis |
@bors retry |
Support generic lifetime arguments in method calls Fixes #42403 Fixes #42115 Lifetimes in a method call `x.f::<'a, 'b, T, U>()` are treated exactly like lifetimes in the equivalent UFCS call `X::f::<'a, 'b, T, U>`. In addition, if the method has late bound lifetime parameters (explicit or implicit), then explicitly specifying lifetime arguments is not permitted (guarded by a compatibility lint). [breaking-change] because previously lifetimes in method calls were accepted unconditionally. r? @eddyb
☀️ Test successful - status-appveyor, status-travis |
Fixes #42403
Fixes #42115
Lifetimes in a method call
x.f::<'a, 'b, T, U>()
are treated exactly like lifetimes in the equivalent UFCS callX::f::<'a, 'b, T, U>
.In addition, if the method has late bound lifetime parameters (explicit or implicit), then explicitly specifying lifetime arguments is not permitted (guarded by a compatibility lint).
[breaking-change] because previously lifetimes in method calls were accepted unconditionally.
r? @eddyb