Skip to content

Commit 5083378

Browse files
authored
Rollup merge of #157998 - fmease:lint-explicit-outlives-bounds-disclaimer, r=mu001999
Add big disclaimer to the description of lint `explicit_outlives_requirements`
2 parents fd96010 + 0cca8c4 commit 5083378

1 file changed

Lines changed: 35 additions & 13 deletions

File tree

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,23 +2284,45 @@ declare_lint! {
22842284
///
22852285
/// ### Explanation
22862286
///
2287-
/// If a `struct` contains a reference, such as `&'a T`, the compiler
2288-
/// requires that `T` outlives the lifetime `'a`. This historically
2289-
/// required writing an explicit lifetime bound to indicate this
2290-
/// requirement. However, this can be overly explicit, causing clutter and
2291-
/// unnecessary complexity. The language was changed to automatically
2292-
/// infer the bound if it is not specified. Specifically, if the struct
2293-
/// contains a reference, directly or indirectly, to `T` with lifetime
2294-
/// `'x`, then it will infer that `T: 'x` is a requirement.
2295-
///
2296-
/// This lint is "allow" by default because it can be noisy for existing
2297-
/// code that already had these requirements. This is a stylistic choice,
2298-
/// as it is still valid to explicitly state the bound. It also has some
2299-
/// false positives that can cause confusion.
2287+
/// If a struct, enum or union contains a reference, such as `&'a T`,
2288+
/// the compiler requires that `T` outlives the lifetime `'a`.
2289+
/// This historically required writing an explicit lifetime bound to indicate this requirement.
2290+
/// However, this can be overly explicit, causing clutter and unnecessary complexity.
2291+
/// The language was changed to automatically infer some classes of lifetime bounds
2292+
/// if they are not specified.
2293+
/// Specifically, if a struct, enum or union contains a reference, directly or indirectly,
2294+
/// to `T` with lifetime `'x` and `'x` refers to a lifetime parameter,
2295+
/// then it will infer that `T: 'x` is a requirement.
23002296
///
23012297
/// See [RFC 2093] for more details.
23022298
///
2299+
/// > [!WARNING]
2300+
/// > Implicit lifetime bounds are not semantically equivalent to explicit ones since the latter
2301+
/// > may affect the implicit lifetime bound of trait object types that are passed as arguments
2302+
/// > to the overarching struct, enum or union.
2303+
/// > Rephrased, they participate in [trait object lifetime defaulting][TOLD].
2304+
/// >
2305+
/// > Consider the following piece of code where removing bound `T: 'a` would lead to a lifetime
2306+
/// > error in function `scope`:
2307+
/// >
2308+
/// > ```rust,no_run
2309+
/// > struct Ref<'a, T: ?Sized + 'a>(&'a T);
2310+
/// >
2311+
/// > fn scope() {
2312+
/// > let buf = String::new();
2313+
/// > let str = buf.as_str();
2314+
/// > render(Ref(&str));
2315+
/// > }
2316+
/// >
2317+
/// > fn render(_: Ref<dyn std::fmt::Display>) {}
2318+
/// > ```
2319+
/// >
2320+
/// > Consequently, removing explicit outlives-bounds on type parameters of publicly reachable types
2321+
/// > constitutes a **breaking change** if the lifetime refers to a lifetime parameter and
2322+
/// > the type parameter is not bounded by `Sized` (thereby admitting trait object types).
2323+
///
23032324
/// [RFC 2093]: https://github.com/rust-lang/rfcs/blob/master/text/2093-infer-outlives.md
2325+
/// [TOLD]: https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes
23042326
pub EXPLICIT_OUTLIVES_REQUIREMENTS,
23052327
Allow,
23062328
"outlives requirements can be inferred"

0 commit comments

Comments
 (0)