account for lifetime bounds in single_use_lifetimes

This commit is contained in:
Qai Juang
2026-05-24 03:37:29 -04:00
committed by qaijuang
parent 1ac7072415
commit ccb9e9e84a
8 changed files with 57 additions and 61 deletions
@@ -3630,6 +3630,9 @@ pub(crate) fn maybe_report_lifetime_uses(
};
match use_set {
Some(LifetimeUseSet::Many) => {}
// A lifetime bound is a real use of that lifetime parameter, even
// though visiting a bound like `'b: 'a` only records a use of `'a`.
Some(LifetimeUseSet::One { .. }) if !param.bounds.is_empty() => {}
Some(LifetimeUseSet::One { use_span, use_ctxt }) => {
let param_ident = param.ident;
let deletion_span =
+4 -2
View File
@@ -1,3 +1,5 @@
//@ check-pass
#![feature(decl_macro, rustc_attrs)]
#![deny(single_use_lifetimes)]
@@ -35,7 +37,7 @@ fn k<T: Clone>(t1: $T, t2: T) -> (T, $T) {
mod lifetime_params {
macro m($a:lifetime) {
fn f<'b, 'c, $a: 'b, 'a: 'c>(t1: &$a(), t2: &'a ()) -> (&'b (), &'c ()) { //~ ERROR lifetime parameter `'a` only used once
fn f<'b, 'c, $a: 'b, 'a: 'c>(t1: &$a(), t2: &'a ()) -> (&'b (), &'c ()) {
(t1, t2)
}
}
@@ -60,7 +62,7 @@ fn k<'a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) {
}
}
m!('a); //~ ERROR lifetime parameter `'a` only used once
m!('a);
n!('a);
p!('a);
}
@@ -1,28 +0,0 @@
error: lifetime parameter `'a` only used once
--> $DIR/issue-104440.rs:63:8
|
LL | m!('a);
| ^^
| |
| this lifetime...
| ...is used only here
|
note: the lint level is defined here
--> $DIR/issue-104440.rs:2:9
|
LL | #![deny(single_use_lifetimes)]
| ^^^^^^^^^^^^^^^^^^^^
error: lifetime parameter `'a` only used once
--> $DIR/issue-104440.rs:38:30
|
LL | fn f<'b, 'c, $a: 'b, 'a: 'c>(t1: &$a(), t2: &'a ()) -> (&'b (), &'c ()) {
| ^^ this lifetime... -- ...is used only here
...
LL | m!('a);
| ------ in this macro invocation
|
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
+2 -1
View File
@@ -1,3 +1,5 @@
//@ check-pass
#![deny(single_use_lifetimes)]
pub enum Data<'a> {
@@ -7,7 +9,6 @@ pub enum Data<'a> {
impl<'a> Data<'a> {
pub fn get<'b: 'a>(&'b self) -> &'a str {
//~^ ERROR lifetime parameter `'b` only used once
match &self {
Self::Borrowed(val) => val,
Self::Owned(val) => &val,
@@ -1,16 +0,0 @@
error: lifetime parameter `'b` only used once
--> $DIR/issue-117965.rs:9:16
|
LL | pub fn get<'b: 'a>(&'b self) -> &'a str {
| ^^ -- ...is used only here
| |
| this lifetime...
|
note: the lint level is defined here
--> $DIR/issue-117965.rs:1:9
|
LL | #![deny(single_use_lifetimes)]
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
@@ -0,0 +1,34 @@
// Regression test for https://github.com/rust-lang/rust/issues/153836.
#![deny(single_use_lifetimes)]
#![allow(dead_code)]
#![allow(unused_variables)]
struct Foo<'a>(&'a i32);
struct Bar<'b>(&'b i32);
fn function<'a, 'b: 'a>(_: Foo<'a>, _: Bar<'b>) {}
type FnPtr = for<'a, 'b: 'a> fn(Foo<'a>, Bar<'b>);
//~^ ERROR bounds cannot be used in this context
trait WhereBound<'a, 'b> {}
fn where_bound<T>()
where
T: for<'a, 'b: 'a> WhereBound<'a, 'b>,
//~^ ERROR bounds cannot be used in this context
{
}
trait ImplTrait<'a> {
fn foo(self, foo: Foo<'a>);
}
impl<'a, 'b: 'a> ImplTrait<'a> for Bar<'b> {
fn foo(self, foo: Foo<'a>) {
let _: &'a i32 = self.0;
let _: Foo<'a> = foo;
}
}
fn main() {}
@@ -0,0 +1,14 @@
error: bounds cannot be used in this context
--> $DIR/lifetime-bounds.rs:11:26
|
LL | type FnPtr = for<'a, 'b: 'a> fn(Foo<'a>, Bar<'b>);
| ^^
error: bounds cannot be used in this context
--> $DIR/lifetime-bounds.rs:18:20
|
LL | T: for<'a, 'b: 'a> WhereBound<'a, 'b>,
| ^^
error: aborting due to 2 previous errors
@@ -19,18 +19,4 @@ fn next(&mut self) -> Option<Self::Item> {
}
}
trait BoundTrait<'a> {
fn foo(self, handler: &Handler<'a>);
}
struct Handler<'a>(fn(&'a u32));
struct Bar<'b>(&'b u32);
// https://github.com/rust-lang/rust/issues/153836
impl<'a, 'b: 'a> BoundTrait<'a> for Bar<'b> {
fn foo(self, handler: &Handler<'a>) {
(handler.0)(self.0);
}
}
fn main() {}