Skip to content

Commit

Permalink
Rollup merge of #108230 - LittleFall:enhance/warning, r=estebank
Browse files Browse the repository at this point in the history
Convert a hard-warning about named static lifetimes into lint "unused_lifetimes"

Fixes #96956.

Some changes are ported from #98079, thanks to jeremydavis519.

r? `@estebank` `@petrochenkov`

Any feedback is appreciated!

## Actions
- [x] resolve conflicts
- [x] fix build
- [x] address review comments in last pr
- [x] update tests
  • Loading branch information
GuillaumeGomez authored Feb 22, 2023
2 parents 89c201e + ce2ae62 commit a32c500
Show file tree
Hide file tree
Showing 21 changed files with 96 additions and 121 deletions.
46 changes: 24 additions & 22 deletions compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use rustc_middle::bug;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::*;
use rustc_middle::ty::{self, ir::TypeVisitor, DefIdTree, TyCtxt, TypeSuperVisitable};
use rustc_session::lint;
use rustc_span::def_id::DefId;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
Expand Down Expand Up @@ -923,17 +924,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
origin,
..
}) => {

let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
bound_generic_params
.iter()
.enumerate()
.map(|(late_bound_idx, param)| {
let pair = ResolvedArg::late(late_bound_idx as u32, param);
let r = late_arg_as_bound_arg(this.tcx, &pair.1, param);
(pair, r)
})
.unzip();
.iter()
.enumerate()
.map(|(late_bound_idx, param)| {
let pair = ResolvedArg::late(late_bound_idx as u32, param);
let r = late_arg_as_bound_arg(this.tcx, &pair.1, param);
(pair, r)
})
.unzip();
this.record_late_bound_vars(hir_id, binders.clone());
// Even if there are no lifetimes defined here, we still wrap it in a binder
// scope. If there happens to be a nested poly trait ref (an error), that
Expand Down Expand Up @@ -968,20 +968,22 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
continue;
}
this.insert_lifetime(lt, ResolvedArg::StaticLifetime);
this.tcx
.sess
.struct_span_warn(
lifetime.ident.span,
&format!(
"unnecessary lifetime parameter `{}`",
this.tcx.struct_span_lint_hir(
lint::builtin::UNUSED_LIFETIMES,
lifetime.hir_id,
lifetime.ident.span,
format!(
"unnecessary lifetime parameter `{}`",
lifetime.ident
),
|lint| {
let help = &format!(
"you can use the `'static` lifetime directly, in place of `{}`",
lifetime.ident,
),
)
.help(&format!(
"you can use the `'static` lifetime directly, in place of `{}`",
lifetime.ident,
))
.emit();
);
lint.help(help)
},
);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied
--> $DIR/method-unsatified-assoc-type-predicate.rs:28:7
--> $DIR/method-unsatisfied-assoc-type-predicate.rs:28:7
|
LL | struct S;
| --------
Expand All @@ -12,7 +12,7 @@ LL | a.f();
| ^ method cannot be called on `S` due to unsatisfied trait bounds
|
note: trait bound `<S as X>::Y<i32> = i32` was not satisfied
--> $DIR/method-unsatified-assoc-type-predicate.rs:12:11
--> $DIR/method-unsatisfied-assoc-type-predicate.rs:12:11
|
LL | impl<T: X<Y<i32> = i32>> M for T {}
| ^^^^^^^^^^^^ - -
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![warn(unused_lifetimes)]

pub trait X {
type Y<'a: 'static>;
//~^ WARNING unnecessary lifetime parameter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,45 +1,50 @@
warning: unnecessary lifetime parameter `'a`
--> $DIR/unsatified-item-lifetime-bound.rs:2:12
--> $DIR/unsatisfied-item-lifetime-bound.rs:4:12
|
LL | type Y<'a: 'static>;
| ^^
|
= help: you can use the `'static` lifetime directly, in place of `'a`
note: the lint level is defined here
--> $DIR/unsatisfied-item-lifetime-bound.rs:1:9
|
LL | #![warn(unused_lifetimes)]
| ^^^^^^^^^^^^^^^^

error[E0478]: lifetime bound not satisfied
--> $DIR/unsatified-item-lifetime-bound.rs:11:8
--> $DIR/unsatisfied-item-lifetime-bound.rs:13:8
|
LL | f: <T as X>::Y<'a>,
| ^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
--> $DIR/unsatified-item-lifetime-bound.rs:10:10
--> $DIR/unsatisfied-item-lifetime-bound.rs:12:10
|
LL | struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> {
| ^^
= note: but lifetime parameter must outlive the static lifetime

error[E0478]: lifetime bound not satisfied
--> $DIR/unsatified-item-lifetime-bound.rs:16:8
--> $DIR/unsatisfied-item-lifetime-bound.rs:18:8
|
LL | f: <T as X>::Y<'a>,
| ^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
--> $DIR/unsatified-item-lifetime-bound.rs:15:10
--> $DIR/unsatisfied-item-lifetime-bound.rs:17:10
|
LL | struct C<'a, T: X> {
| ^^
= note: but lifetime parameter must outlive the static lifetime

error[E0478]: lifetime bound not satisfied
--> $DIR/unsatified-item-lifetime-bound.rs:21:8
--> $DIR/unsatisfied-item-lifetime-bound.rs:23:8
|
LL | f: <() as X>::Y<'a>,
| ^^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
--> $DIR/unsatified-item-lifetime-bound.rs:20:10
--> $DIR/unsatisfied-item-lifetime-bound.rs:22:10
|
LL | struct D<'a> {
| ^^
Expand Down
1 change: 0 additions & 1 deletion tests/ui/impl-trait/equal-hidden-lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

// `'a == 'static` so `&'a i32` is fine as the return type
fn equal_regions_static<'a: 'static>(x: &'a i32) -> impl Sized {
//~^ WARNING unnecessary lifetime parameter `'a`
x
}

Expand Down
10 changes: 0 additions & 10 deletions tests/ui/impl-trait/equal-hidden-lifetimes.stderr

This file was deleted.

1 change: 0 additions & 1 deletion tests/ui/issues/issue-30438-c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ trait Trait { type Out; }
struct Test<'a> { s: &'a str }

fn silly<'y, 'z>(_s: &'y Test<'z>) -> &'y <Test<'z> as Trait>::Out where 'z: 'static {
//~^ WARN unnecessary lifetime parameter `'z`
let x = Test { s: "this cannot last" };
&x
//~^ ERROR: cannot return reference to local variable `x`
Expand Down
12 changes: 2 additions & 10 deletions tests/ui/issues/issue-30438-c.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
warning: unnecessary lifetime parameter `'z`
--> $DIR/issue-30438-c.rs:7:74
|
LL | fn silly<'y, 'z>(_s: &'y Test<'z>) -> &'y <Test<'z> as Trait>::Out where 'z: 'static {
| ^^
|
= help: you can use the `'static` lifetime directly, in place of `'z`

error[E0515]: cannot return reference to local variable `x`
--> $DIR/issue-30438-c.rs:10:5
--> $DIR/issue-30438-c.rs:9:5
|
LL | &x
| ^^ returns a reference to data owned by the current function

error: aborting due to previous error; 1 warning emitted
error: aborting due to previous error

For more information about this error, try `rustc --explain E0515`.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
//
// 'a : 'b

#![warn(unused_lifetimes)]

fn test<'a,'b>(x: &'a i32) -> &'b i32
where 'a: 'static //~ WARN unnecessary lifetime parameter `'a`
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
warning: unnecessary lifetime parameter `'a`
--> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:12:11
--> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:14:11
|
LL | where 'a: 'static
| ^^
|
= help: you can use the `'static` lifetime directly, in place of `'a`
note: the lint level is defined here
--> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:11:9
|
LL | #![warn(unused_lifetimes)]
| ^^^^^^^^^^^^^^^^

warning: 1 warning emitted

2 changes: 2 additions & 0 deletions tests/ui/regions/regions-static-bound-rpass.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// run-pass

#![warn(unused_lifetimes)]

fn invariant_id<'a,'b>(t: &'b mut &'static ()) -> &'b mut &'a ()
where 'a: 'static { t }
//~^ WARN unnecessary lifetime parameter `'a`
Expand Down
11 changes: 8 additions & 3 deletions tests/ui/regions/regions-static-bound-rpass.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
warning: unnecessary lifetime parameter `'a`
--> $DIR/regions-static-bound-rpass.rs:4:11
--> $DIR/regions-static-bound-rpass.rs:6:11
|
LL | where 'a: 'static { t }
| ^^
|
= help: you can use the `'static` lifetime directly, in place of `'a`
note: the lint level is defined here
--> $DIR/regions-static-bound-rpass.rs:3:9
|
LL | #![warn(unused_lifetimes)]
| ^^^^^^^^^^^^^^^^

warning: unnecessary lifetime parameter `'a`
--> $DIR/regions-static-bound-rpass.rs:8:11
--> $DIR/regions-static-bound-rpass.rs:10:11
|
LL | where 'a: 'static { t }
| ^^
|
= help: you can use the `'static` lifetime directly, in place of `'a`

warning: unnecessary lifetime parameter `'b`
--> $DIR/regions-static-bound-rpass.rs:12:19
--> $DIR/regions-static-bound-rpass.rs:14:19
|
LL | where 'a: 'b, 'b: 'static { t }
| ^^
Expand Down
8 changes: 5 additions & 3 deletions tests/ui/regions/regions-static-bound.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
fn static_id<'a,'b>(t: &'a ()) -> &'static ()
where 'a: 'static { t }
//~^ WARN unnecessary lifetime parameter `'a`
#![warn(unused_lifetimes)]

fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t }
//~^ WARN lifetime parameter `'b` never used
//~| WARN unnecessary lifetime parameter `'a`

fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
where 'a: 'b, 'b: 'static { t }
Expand Down
30 changes: 22 additions & 8 deletions tests/ui/regions/regions-static-bound.stderr
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
warning: lifetime parameter `'b` never used
--> $DIR/regions-static-bound.rs:3:17
|
LL | fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t }
| -^^
| |
| help: elide the unused lifetime
|
note: the lint level is defined here
--> $DIR/regions-static-bound.rs:1:9
|
LL | #![warn(unused_lifetimes)]
| ^^^^^^^^^^^^^^^^

warning: unnecessary lifetime parameter `'a`
--> $DIR/regions-static-bound.rs:2:11
--> $DIR/regions-static-bound.rs:3:53
|
LL | where 'a: 'static { t }
| ^^
LL | fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t }
| ^^
|
= help: you can use the `'static` lifetime directly, in place of `'a`

warning: unnecessary lifetime parameter `'b`
--> $DIR/regions-static-bound.rs:6:19
--> $DIR/regions-static-bound.rs:8:19
|
LL | where 'a: 'b, 'b: 'static { t }
| ^^
|
= help: you can use the `'static` lifetime directly, in place of `'b`

error: lifetime may not live long enough
--> $DIR/regions-static-bound.rs:10:5
--> $DIR/regions-static-bound.rs:12:5
|
LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
| -- lifetime `'a` defined here
LL | t
| ^ returning this value requires that `'a` must outlive `'static`

error[E0521]: borrowed data escapes outside of function
--> $DIR/regions-static-bound.rs:15:5
--> $DIR/regions-static-bound.rs:17:5
|
LL | fn error(u: &(), v: &()) {
| - - let's call the lifetime of this reference `'1`
Expand All @@ -36,7 +50,7 @@ LL | static_id(&u);
| argument requires that `'1` must outlive `'static`

error[E0521]: borrowed data escapes outside of function
--> $DIR/regions-static-bound.rs:17:5
--> $DIR/regions-static-bound.rs:19:5
|
LL | fn error(u: &(), v: &()) {
| - - let's call the lifetime of this reference `'2`
Expand All @@ -49,6 +63,6 @@ LL | static_id_indirect(&v);
| `v` escapes the function body here
| argument requires that `'2` must outlive `'static`

error: aborting due to 3 previous errors; 2 warnings emitted
error: aborting due to 3 previous errors; 3 warnings emitted

For more information about this error, try `rustc --explain E0521`.
2 changes: 1 addition & 1 deletion tests/ui/static/static-lifetime-bound.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn f<'a: 'static>(_: &'a i32) {} //~WARN unnecessary lifetime parameter `'a`
fn f<'a: 'static>(_: &'a i32) {}

fn main() {
let x = 0;
Expand Down
10 changes: 1 addition & 9 deletions tests/ui/static/static-lifetime-bound.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
warning: unnecessary lifetime parameter `'a`
--> $DIR/static-lifetime-bound.rs:1:6
|
LL | fn f<'a: 'static>(_: &'a i32) {}
| ^^
|
= help: you can use the `'static` lifetime directly, in place of `'a`

error[E0597]: `x` does not live long enough
--> $DIR/static-lifetime-bound.rs:5:7
|
Expand All @@ -19,6 +11,6 @@ LL | f(&x);
LL | }
| - `x` dropped here while still borrowed

error: aborting due to previous error; 1 warning emitted
error: aborting due to previous error

For more information about this error, try `rustc --explain E0597`.
1 change: 0 additions & 1 deletion tests/ui/type-alias-impl-trait/bounds-are-checked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
type X<'a> = impl Into<&'static str> + From<&'a str>;

fn f<'a: 'static>(t: &'a str) -> X<'a> {
//~^ WARNING unnecessary lifetime parameter
t
//~^ ERROR expected generic lifetime parameter, found `'static`
}
Expand Down
12 changes: 2 additions & 10 deletions tests/ui/type-alias-impl-trait/bounds-are-checked.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
warning: unnecessary lifetime parameter `'a`
--> $DIR/bounds-are-checked.rs:8:6
|
LL | fn f<'a: 'static>(t: &'a str) -> X<'a> {
| ^^
|
= help: you can use the `'static` lifetime directly, in place of `'a`

error[E0792]: expected generic lifetime parameter, found `'static`
--> $DIR/bounds-are-checked.rs:10:5
--> $DIR/bounds-are-checked.rs:9:5
|
LL | type X<'a> = impl Into<&'static str> + From<&'a str>;
| -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
...
LL | t
| ^

error: aborting due to previous error; 1 warning emitted
error: aborting due to previous error

For more information about this error, try `rustc --explain E0792`.
Loading

0 comments on commit a32c500

Please sign in to comment.