pub static EXPLICIT_OUTLIVES_REQUIREMENTS: &'static LintExpand description
The explicit_outlives_requirements lint detects unnecessary
lifetime bounds that can be inferred.
§Example
#![deny(explicit_outlives_requirements)]
#![deny(warnings)]
struct SharedRef<'a, T>
where
T: 'a,
{
data: &'a T,
}{{produces}}
§Explanation
If a struct, enum or union contains a reference, such as &'a T,
the compiler requires that T outlives the lifetime 'a.
This historically required writing an explicit lifetime bound to indicate this requirement.
However, this can be overly explicit, causing clutter and unnecessary complexity.
The language was changed to automatically infer some classes of lifetime bounds
if they are not specified.
Specifically, if a struct, enum or union contains a reference, directly or indirectly,
to T with lifetime 'x and 'x refers to a lifetime parameter,
then it will infer that T: 'x is a requirement.
See RFC 2093 for more details.
[!NOTE] This lint intentionally doesn’t get emitted for explicit outlives-bounds on type parameters that aren’t bounded by
Sized(unless they’re higher-ranked) since unlike implicit outlives-bounds these may affect the implicit lifetime bound of trait object types that are passed as arguments to the overarching struct, enum or union.Rephrased, they participate in trait object lifetime defaulting.
Consider the following piece of code where removing bound
T: 'awould lead to a lifetime error in functionscope:struct Ref<'a, T: ?Sized + 'a>(&'a T); fn scope() { let buf = String::new(); let str = buf.as_str(); render(Ref(&str)); } fn render(_: Ref<dyn std::fmt::Display>) {}Due to the explicit outlives-bound the function
renderabove is equivalent to:ⓘfn render<'r>(_: Ref<'r, dyn std::fmt::Display + 'r>) {}If it wasn’t for that explicit bound then the function would mean the following instead:
ⓘfn render<'r>(_: Ref<'r, dyn std::fmt::Display + 'static>) {}