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

Add warning for use of lifetime parameter with 'static bound #40734

Merged
merged 2 commits into from
Mar 26, 2017

Conversation

adamransom
Copy link
Contributor

@adamransom adamransom commented Mar 22, 2017

Previously a 'static lifetime bound would result in an undeclared lifetime error when compiling, even though it could be considered valid.

However, it is unnecessary to use it as a lifetime bound so we present the user with a warning instead and suggest using the 'static lifetime directly, in place of the lifetime parameter. We can change this to an error (or warning with lint) if that's decided to be more appropriate.

Example output:

warning: unnecessary lifetime parameter `'a`
 --> ../static-lifetime-bound.rs:3:10
  |
3 | fn f<'a: 'static>(val: &'a i32) {
  |      ^^^^^^^^^^^
  |
  = help: you can use the `'static` lifetime directly, in place `'a`

Fixes #40661

r? @jseyfried

Simply move the test for `keywords::StaticLifetime` into the
`Lifetime` impl, to match how elision is checked.
@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @jseyfried (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

Copy link
Contributor

@jseyfried jseyfried left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

self.insert_lifetime(lifetime_ref, Region::Static);
return;
}
self.resolve_lifetime_ref(lifetime_ref);
self.resolve_lifetime_ref(lifetime_ref, lifetime_ref);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make the second parameter Option<&hir::Lifetime> and use None here to make it clear that the second argument won't get used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was thinking about this also. I'll add that.

// The only way we end up here is if there is a static lifetime bound (due to early
// return on `visit_lifetime()`)
self.insert_lifetime(lifetime_ref, Region::Static);
let full_span = mk_sp(context_ref.span.lo, lifetime_ref.span.hi);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would become context_ref.unwrap().span.lo, enforcing the invariant described in the above comment.

self.sess.struct_span_warn(full_span,
&format!("unnecessary lifetime parameter `{}`", context_ref.name))
.help(&format!("you can use a `'static` lifetime directly, in place of \
the lifetime parameter `{}`", context_ref.name))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would reword: you can use the lifetime `'static` directly in place of `{}` .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's better. I was also wondering if it's worth adding a note? Something like:

note: due to use of `'static` bound on `'a`

or whether the help message alone is enough?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The help message is sufficient, imo.

@jseyfried jseyfried added I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Mar 23, 2017
@jseyfried
Copy link
Contributor

jseyfried commented Mar 23, 2017

Nominating for @rust-lang/lang decision: should we allow, warn, or forbid a 'static bound on a lifetime parameter, e.g. fn f<'a: 'static>(_: &'a ()) {}?

Today, this causes a confusing error.

@nikomatsakis
Copy link
Contributor

@jseyfried conclusion from @rust-lang/lang meeting was that we should accept it, but warn (as I believe this PR does)

fn resolve_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) {
fn resolve_lifetime_ref(&mut self,
lifetime_ref: &hir::Lifetime,
context_ref: Option<&hir::Lifetime>) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terminology here is wrong IMO. The intention of _ref, AFAICT, is to mean "lifetime reference", as in, one use of (referring to) a lifetime. So this extra argument should be maybe_def or some such, but even then, I would just bypass this whole function from check_lifetime_defs, for 'static, i.e. handle it there instead of here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree that's a better place to handle it. Will make that change!

@adamransom adamransom force-pushed the fix/40661 branch 2 times, most recently from a9b9fa6 to e7949d0 Compare March 25, 2017 01:46
Previously a `'static` lifetime bound would result in an `undeclared
lifetime` error when compiling, even though it could be considered
valid.

However, it is unnecessary to use it as a lifetime bound so we present
the user with a warning instead and suggest using the `'static` lifetime
directly, in place of the lifetime parameter.
@adamransom
Copy link
Contributor Author

Updated with latest suggestions.

@@ -1464,7 +1464,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
self.check_lifetime_def_for_shadowing(old_scope, &lifetime_i.lifetime);

for bound in &lifetime_i.bounds {
self.resolve_lifetime_ref(bound);
if !bound.is_static() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose to put the common path first, even though its a negated condition. I can change if this is not preferred style though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@jseyfried
Copy link
Contributor

@adamransom Thanks!
@bors r+

@bors
Copy link
Contributor

bors commented Mar 25, 2017

📌 Commit e7949d0 has been approved by jseyfried

@bors
Copy link
Contributor

bors commented Mar 25, 2017

⌛ Testing commit e7949d0 with merge e425597...

@bors
Copy link
Contributor

bors commented Mar 25, 2017

💔 Test failed - status-travis

@arielb1
Copy link
Contributor

arielb1 commented Mar 25, 2017

@bors
Copy link
Contributor

bors commented Mar 25, 2017

⌛ Testing commit e7949d0 with merge d73c258...

@bors
Copy link
Contributor

bors commented Mar 25, 2017

💔 Test failed - status-travis

@arielb1
Copy link
Contributor

arielb1 commented Mar 25, 2017

frewsxcv added a commit to frewsxcv/rust that referenced this pull request Mar 25, 2017
Add warning for use of lifetime parameter with 'static bound

Previously a `'static` lifetime bound would result in an `undeclared lifetime` error when compiling, even though it could be considered valid.

However, it is unnecessary to use it as a lifetime bound so we present the user with a warning instead and suggest using the `'static` lifetime directly, in place of the lifetime parameter. We can change this to an error (or warning with lint) if that's decided to be more appropriate.

Example output:
```
warning: unnecessary lifetime parameter `'a`
 --> ../static-lifetime-bound.rs:3:10
  |
3 | fn f<'a: 'static>(val: &'a i32) {
  |      ^^^^^^^^^^^
  |
  = help: you can use the `'static` lifetime directly, in place `'a`
```

Fixes rust-lang#40661

r? @jseyfried
frewsxcv added a commit to frewsxcv/rust that referenced this pull request Mar 25, 2017
Add warning for use of lifetime parameter with 'static bound

Previously a `'static` lifetime bound would result in an `undeclared lifetime` error when compiling, even though it could be considered valid.

However, it is unnecessary to use it as a lifetime bound so we present the user with a warning instead and suggest using the `'static` lifetime directly, in place of the lifetime parameter. We can change this to an error (or warning with lint) if that's decided to be more appropriate.

Example output:
```
warning: unnecessary lifetime parameter `'a`
 --> ../static-lifetime-bound.rs:3:10
  |
3 | fn f<'a: 'static>(val: &'a i32) {
  |      ^^^^^^^^^^^
  |
  = help: you can use the `'static` lifetime directly, in place `'a`
```

Fixes rust-lang#40661

r? @jseyfried
@arielb1
Copy link
Contributor

arielb1 commented Mar 25, 2017

bors added a commit that referenced this pull request Mar 26, 2017
Rollup of 7 pull requests

- Successful merges: #40642, #40734, #40740, #40771, #40807, #40820, #40821
- Failed merges:
@bors bors merged commit e7949d0 into rust-lang:master Mar 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants