mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Actually, just reuse the UNUSED_LIFETIMES lint
This commit is contained in:
parent
03c901fd35
commit
89409494e3
@ -20,7 +20,6 @@ use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::middle::resolve_bound_vars::*;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::Span;
|
||||
@ -867,31 +866,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||
}) => {
|
||||
self.visit_lifetime(lifetime);
|
||||
walk_list!(self, visit_param_bound, bounds);
|
||||
|
||||
if lifetime.res != hir::LifetimeName::Static {
|
||||
for bound in bounds {
|
||||
let hir::GenericBound::Outlives(lt) = bound else {
|
||||
continue;
|
||||
};
|
||||
if lt.res != hir::LifetimeName::Static {
|
||||
continue;
|
||||
}
|
||||
self.insert_lifetime(lt, ResolvedArg::StaticLifetime);
|
||||
self.tcx.node_span_lint(
|
||||
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,
|
||||
);
|
||||
lint.help(help);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
&hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
|
||||
self.visit_ty(lhs_ty);
|
||||
|
@ -534,7 +534,8 @@ lint_reason_must_be_string_literal = reason must be a string literal
|
||||
|
||||
lint_reason_must_come_last = reason in lint attribute must come last
|
||||
|
||||
lint_redundant_lifetime_args = lifetime `{$victim}` is required to be equal to `{$candidate}`, and is redundant and can be removed
|
||||
lint_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}`
|
||||
.note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}`
|
||||
|
||||
lint_redundant_semicolons =
|
||||
unnecessary trailing {$multiple ->
|
||||
|
@ -8,19 +8,13 @@ use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::{SubregionOrigin, TyCtxtInferExt};
|
||||
use rustc_macros::LintDiagnostic;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::lint::builtin::UNUSED_LIFETIMES;
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_trait_selection::traits::{outlives_bounds::InferCtxtExt, ObligationCtxt};
|
||||
|
||||
use crate::{LateContext, LateLintPass};
|
||||
|
||||
declare_lint! {
|
||||
/// Docs
|
||||
pub REDUNDANT_LIFETIME_ARGS,
|
||||
Allow,
|
||||
"do something"
|
||||
}
|
||||
|
||||
declare_lint_pass!(RedundantLifetimeArgs => [REDUNDANT_LIFETIME_ARGS]);
|
||||
declare_lint_pass!(RedundantLifetimeArgs => []);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for RedundantLifetimeArgs {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
@ -142,10 +136,10 @@ fn check<'tcx>(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, owner_id: hir::
|
||||
if infcx.resolve_regions(outlives_env).is_empty() {
|
||||
shadowed.insert(victim);
|
||||
tcx.emit_spanned_lint(
|
||||
REDUNDANT_LIFETIME_ARGS,
|
||||
UNUSED_LIFETIMES,
|
||||
tcx.local_def_id_to_hir_id(def_id.expect_local()),
|
||||
tcx.def_span(def_id),
|
||||
RedundantLifetimeArgsList { candidate, victim },
|
||||
RedundantLifetimeArgsLint { candidate, victim },
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -154,7 +148,8 @@ fn check<'tcx>(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, owner_id: hir::
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_redundant_lifetime_args)]
|
||||
struct RedundantLifetimeArgsList<'tcx> {
|
||||
#[note]
|
||||
struct RedundantLifetimeArgsLint<'tcx> {
|
||||
candidate: ty::Region<'tcx>,
|
||||
victim: ty::Region<'tcx>,
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
#![warn(unused_lifetimes)]
|
||||
|
||||
pub trait X {
|
||||
type Y<'a: 'static>;
|
||||
//~^ WARNING unnecessary lifetime parameter
|
||||
}
|
||||
|
||||
impl X for () {
|
||||
|
@ -1,18 +1,5 @@
|
||||
warning: unnecessary lifetime parameter `'a`
|
||||
--> $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/unsatisfied-item-lifetime-bound.rs:9:18
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:6:18
|
||||
|
|
||||
LL | type Y<'a: 'static>;
|
||||
| ------------------- definition of `Y` from trait
|
||||
@ -21,7 +8,7 @@ LL | type Y<'a> = &'a ();
|
||||
| ^^^^^^
|
||||
|
|
||||
note: lifetime parameter instantiated with the lifetime `'a` as defined here
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:9:12
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:6:12
|
||||
|
|
||||
LL | type Y<'a> = &'a ();
|
||||
| ^^
|
||||
@ -32,44 +19,44 @@ LL | type Y<'a> = &'a () where 'a: 'static;
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0478]: lifetime bound not satisfied
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:14:8
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:11:8
|
||||
|
|
||||
LL | f: <T as X>::Y<'a>,
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: lifetime parameter instantiated with the lifetime `'a` as defined here
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:13:10
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:10: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/unsatisfied-item-lifetime-bound.rs:19:8
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:16:8
|
||||
|
|
||||
LL | f: <T as X>::Y<'a>,
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: lifetime parameter instantiated with the lifetime `'a` as defined here
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:18:10
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:15:10
|
||||
|
|
||||
LL | struct C<'a, T: X> {
|
||||
| ^^
|
||||
= note: but lifetime parameter must outlive the static lifetime
|
||||
|
||||
error[E0478]: lifetime bound not satisfied
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:24:8
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:21:8
|
||||
|
|
||||
LL | f: <() as X>::Y<'a>,
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: lifetime parameter instantiated with the lifetime `'a` as defined here
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:23:10
|
||||
--> $DIR/unsatisfied-item-lifetime-bound.rs:20:10
|
||||
|
|
||||
LL | struct D<'a> {
|
||||
| ^^
|
||||
= note: but lifetime parameter must outlive the static lifetime
|
||||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0478`.
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
#![warn(unused_lifetimes)]
|
||||
|
||||
fn test<'a,'b>(x: &'a i32) -> &'b i32
|
||||
where 'a: 'static //~ WARN unnecessary lifetime parameter `'a`
|
||||
fn test<'a,'b>(x: &'a i32) -> &'b i32 //~ WARN unnecessary lifetime parameter `'a`
|
||||
where 'a: 'static
|
||||
{
|
||||
x
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
warning: unnecessary lifetime parameter `'a`
|
||||
--> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:14:11
|
||||
--> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:13:9
|
||||
|
|
||||
LL | where 'a: 'static
|
||||
| ^^
|
||||
LL | fn test<'a,'b>(x: &'a i32) -> &'b i32
|
||||
| ^^
|
||||
|
|
||||
= help: you can use the `'static` lifetime directly, in place of `'a`
|
||||
= note: 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
|
||||
|
|
||||
|
@ -3,16 +3,17 @@
|
||||
#![warn(unused_lifetimes)]
|
||||
|
||||
fn invariant_id<'a,'b>(t: &'b mut &'static ()) -> &'b mut &'a ()
|
||||
where 'a: 'static { t }
|
||||
//~^ WARN unnecessary lifetime parameter `'a`
|
||||
where 'a: 'static { t }
|
||||
|
||||
fn static_id<'a>(t: &'a ()) -> &'static ()
|
||||
where 'a: 'static { t }
|
||||
//~^ WARN unnecessary lifetime parameter `'a`
|
||||
where 'a: 'static { t }
|
||||
|
||||
fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
|
||||
//~^ WARN unnecessary lifetime parameter `'a`
|
||||
//~| WARN unnecessary lifetime parameter `'b`
|
||||
where 'a: 'b, 'b: 'static { t }
|
||||
//~^ WARN unnecessary lifetime parameter `'b`
|
||||
|
||||
fn ref_id<'a>(t: &'a ()) -> &'a () where 'static: 'a { t }
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
warning: unnecessary lifetime parameter `'a`
|
||||
--> $DIR/regions-static-bound-rpass.rs:6:11
|
||||
--> $DIR/regions-static-bound-rpass.rs:5:17
|
||||
|
|
||||
LL | where 'a: 'static { t }
|
||||
| ^^
|
||||
LL | fn invariant_id<'a,'b>(t: &'b mut &'static ()) -> &'b mut &'a ()
|
||||
| ^^
|
||||
|
|
||||
= help: you can use the `'static` lifetime directly, in place of `'a`
|
||||
= note: 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
|
||||
|
|
||||
@ -12,20 +12,28 @@ LL | #![warn(unused_lifetimes)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unnecessary lifetime parameter `'a`
|
||||
--> $DIR/regions-static-bound-rpass.rs:10:11
|
||||
--> $DIR/regions-static-bound-rpass.rs:9:14
|
||||
|
|
||||
LL | where 'a: 'static { t }
|
||||
| ^^
|
||||
LL | fn static_id<'a>(t: &'a ()) -> &'static ()
|
||||
| ^^
|
||||
|
|
||||
= help: you can use the `'static` lifetime directly, in place of `'a`
|
||||
= note: you can use the `'static` lifetime directly, in place of `'a`
|
||||
|
||||
warning: unnecessary lifetime parameter `'a`
|
||||
--> $DIR/regions-static-bound-rpass.rs:13:23
|
||||
|
|
||||
LL | fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
|
||||
| ^^
|
||||
|
|
||||
= note: you can use the `'static` lifetime directly, in place of `'a`
|
||||
|
||||
warning: unnecessary lifetime parameter `'b`
|
||||
--> $DIR/regions-static-bound-rpass.rs:14:19
|
||||
--> $DIR/regions-static-bound-rpass.rs:13:26
|
||||
|
|
||||
LL | where 'a: 'b, 'b: 'static { t }
|
||||
| ^^
|
||||
LL | fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
|
||||
| ^^
|
||||
|
|
||||
= help: you can use the `'static` lifetime directly, in place of `'b`
|
||||
= note: you can use the `'static` lifetime directly, in place of `'b`
|
||||
|
||||
warning: 3 warnings emitted
|
||||
warning: 4 warnings emitted
|
||||
|
||||
|
@ -1,12 +1,7 @@
|
||||
#![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 }
|
||||
//~^ WARN unnecessary lifetime parameter `'b`
|
||||
|
||||
fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
|
||||
t
|
||||
|
@ -1,35 +1,5 @@
|
||||
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:3:53
|
||||
|
|
||||
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: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:12:5
|
||||
--> $DIR/regions-static-bound.rs:7:5
|
||||
|
|
||||
LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
|
||||
| -- lifetime `'a` defined here
|
||||
@ -37,7 +7,7 @@ LL | t
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
error[E0521]: borrowed data escapes outside of function
|
||||
--> $DIR/regions-static-bound.rs:17:5
|
||||
--> $DIR/regions-static-bound.rs:12:5
|
||||
|
|
||||
LL | fn error(u: &(), v: &()) {
|
||||
| - - let's call the lifetime of this reference `'1`
|
||||
@ -50,7 +20,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:19:5
|
||||
--> $DIR/regions-static-bound.rs:14:5
|
||||
|
|
||||
LL | fn error(u: &(), v: &()) {
|
||||
| - - let's call the lifetime of this reference `'2`
|
||||
@ -63,6 +33,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; 3 warnings emitted
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0521`.
|
||||
|
16
tests/ui/regions/transitively-redundant-lifetimes.rs
Normal file
16
tests/ui/regions/transitively-redundant-lifetimes.rs
Normal file
@ -0,0 +1,16 @@
|
||||
#![allow(unused)]
|
||||
#![deny(unused_lifetimes)]
|
||||
|
||||
fn a<'a, 'b>(x: &'a &'b &'a ()) {} //~ ERROR unnecessary lifetime parameter `'b`
|
||||
|
||||
fn b<'a: 'b, 'b: 'a>() {} //~ ERROR unnecessary lifetime parameter `'b`
|
||||
|
||||
struct Foo<T: 'static>(T);
|
||||
fn c<'a>(_: Foo<&'a ()>) {} //~ ERROR unnecessary lifetime parameter `'a`
|
||||
|
||||
struct Bar<'a>(&'a ());
|
||||
impl<'a> Bar<'a> {
|
||||
fn d<'b: 'a>(&'b self) {} //~ ERROR unnecessary lifetime parameter `'b`
|
||||
}
|
||||
|
||||
fn main() {}
|
39
tests/ui/regions/transitively-redundant-lifetimes.stderr
Normal file
39
tests/ui/regions/transitively-redundant-lifetimes.stderr
Normal file
@ -0,0 +1,39 @@
|
||||
error: unnecessary lifetime parameter `'b`
|
||||
--> $DIR/transitively-redundant-lifetimes.rs:4:10
|
||||
|
|
||||
LL | fn a<'a, 'b>(x: &'a &'b &'a ()) {}
|
||||
| ^^
|
||||
|
|
||||
= note: you can use the `'a` lifetime directly, in place of `'b`
|
||||
note: the lint level is defined here
|
||||
--> $DIR/transitively-redundant-lifetimes.rs:2:9
|
||||
|
|
||||
LL | #![deny(unused_lifetimes)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unnecessary lifetime parameter `'b`
|
||||
--> $DIR/transitively-redundant-lifetimes.rs:6:14
|
||||
|
|
||||
LL | fn b<'a: 'b, 'b: 'a>() {}
|
||||
| ^^
|
||||
|
|
||||
= note: you can use the `'a` lifetime directly, in place of `'b`
|
||||
|
||||
error: unnecessary lifetime parameter `'a`
|
||||
--> $DIR/transitively-redundant-lifetimes.rs:9:6
|
||||
|
|
||||
LL | fn c<'a>(_: Foo<&'a ()>) {}
|
||||
| ^^
|
||||
|
|
||||
= note: you can use the `'static` lifetime directly, in place of `'a`
|
||||
|
||||
error: unnecessary lifetime parameter `'b`
|
||||
--> $DIR/transitively-redundant-lifetimes.rs:13:10
|
||||
|
|
||||
LL | fn d<'b: 'a>(&'b self) {}
|
||||
| ^^
|
||||
|
|
||||
= note: you can use the `'a` lifetime directly, in place of `'b`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user