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

Support generic lifetime arguments in method calls #42492

Merged
merged 5 commits into from
Jul 18, 2017

Conversation

petrochenkov
Copy link
Contributor

@petrochenkov petrochenkov commented Jun 6, 2017

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

@eddyb
Copy link
Member

eddyb commented Jun 6, 2017

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 ty::Generics. I'm not even sure it's a good idea to expose the distinction.

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).

@eddyb eddyb added I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jun 6, 2017
@aidanhs aidanhs added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 7, 2017
@nikomatsakis
Copy link
Contributor

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.

@petrochenkov
Copy link
Contributor Author

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.

@arielb1 arielb1 added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 13, 2017
@nikomatsakis
Copy link
Contributor

Discussed in the @rust-lang/lang meeting -- we agree that restricting to 100% early-bound is the right thing here.

@alexcrichton
Copy link
Member

ping @petrochenkov, just wanted to keep this on your radar!

@bors
Copy link
Contributor

bors commented Jun 23, 2017

☔ The latest upstream changes (presumably #42856) made this pull request unmergeable. Please resolve the merge conflicts.

@petrochenkov
Copy link
Contributor Author

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. fn f(_: &u8) {}).
@eddyb Is there an easy way to detect presence of such implicit parameters during type checking? I haven't investigated yet.

@eddyb
Copy link
Member

eddyb commented Jun 24, 2017

You can detect them but I wouldn't consider them parameters for the purposes of paths, as I wouldn't an impl Trait somewhere in an argument type.

@petrochenkov
Copy link
Contributor Author

petrochenkov commented Jun 24, 2017

@eddyb

I wouldn't consider them parameters for the purposes of paths

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 late_implicit::<'static> would be legal and late_explicit::<'static> would be not. Writing out the late bound lifetime explicitly would be a breaking change then.

(I suppose turning impl Trait into an explicit parameter shouldn't be a breaking change as well, because it's going to happen all the time.)

@eddyb
Copy link
Member

eddyb commented Jun 24, 2017

IMO there is no other real choice if we want the explicitly written parameters to mean anything.

@petrochenkov
Copy link
Contributor Author

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.)

@eddyb
Copy link
Member

eddyb commented Jun 24, 2017

@petrochenkov I meant that I don't think we can reasonably let you write anything other than what is present between <...> syntactically in the definition of the item, in a path to that item.

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.

@petrochenkov
Copy link
Contributor Author

I believe I've extracted all the necessary logic to catch late bound parameters from resolve_lifetime.rs.
This should be ready for crater now.

(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.)

@petrochenkov petrochenkov added S-waiting-on-crater Status: Waiting on a crater run to be completed. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 24, 2017
@eddyb
Copy link
Member

eddyb commented Jun 25, 2017

Started crater run.

@eddyb
Copy link
Member

eddyb commented Jun 25, 2017

Crater run failed due to the inclusion of rustfmt in the build.

cc @rust-lang/dev-tools

@eddyb
Copy link
Member

eddyb commented Jul 15, 2017

@petrochenkov Started another crater run.

@eddyb
Copy link
Member

eddyb commented Jul 16, 2017

Third crater report shows 4 regressions.
Since the information was never used, I'm not sure why the authors kept the lifetimes (but really, it's our fault for parsing and ignoring them, some of them could be just "documentation").
There is at least one regression in unsafe code, which could potentially mean an invariant wasn't really enforced, but function signatures should prevent a real problem from spreading.

@petrochenkov petrochenkov removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jul 16, 2017
@Mark-Simulacrum Mark-Simulacrum added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 17, 2017
@Mark-Simulacrum
Copy link
Member

I guess this is waiting on review? Or perhaps a decision from the lang team?

@nikomatsakis
Copy link
Contributor

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?

@petrochenkov
Copy link
Contributor Author

@nikomatsakis

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.

The iteration is complete, all found regressions and mistakes are fixed.

Copy link
Contributor

@nikomatsakis nikomatsakis left a 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?)

@@ -205,6 +205,12 @@ declare_lint! {
}

declare_lint! {
pub LATE_BOUND_LIFETIME_ARGUMENTS,
Deny,
Copy link
Contributor

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.
@petrochenkov
Copy link
Contributor Author

The lint level is changed to warn-by-default.
@bors r=nikomatsakis

@bors
Copy link
Contributor

bors commented Jul 17, 2017

📌 Commit 39114f9 has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Jul 18, 2017

⌛ Testing commit 39114f9 with merge 7c758abdad01aaa219c2cb14e4ed6878fb69c236...

@bors
Copy link
Contributor

bors commented Jul 18, 2017

💔 Test failed - status-travis

@alexcrichton
Copy link
Member

@bors: retry

  • curl failure

@bors
Copy link
Contributor

bors commented Jul 18, 2017

⌛ Testing commit 39114f9 with merge 29d60228266412b6bee73098d00ef185d781a8f3...

@bors
Copy link
Contributor

bors commented Jul 18, 2017

💔 Test failed - status-travis

@est31
Copy link
Member

est31 commented Jul 18, 2017

@bors retry

@bors
Copy link
Contributor

bors commented Jul 18, 2017

⌛ Testing commit 39114f9 with merge 83c659e...

bors added a commit that referenced this pull request Jul 18, 2017
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
@bors
Copy link
Contributor

bors commented Jul 18, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing 83c659e to master...

@bors bors merged commit 39114f9 into rust-lang:master Jul 18, 2017
@petrochenkov petrochenkov deleted the methlife branch August 26, 2017 00:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants