11# Unbounded Lifetimes
22
33Unsafe code can often end up producing references or lifetimes out of thin air.
4- Such lifetimes come into the world as * unbounded* . The most common source of this
5- is dereferencing a raw pointer, which produces a reference with an unbounded lifetime.
6- Such a lifetime becomes as big as context demands. This is in fact more powerful
7- than simply becoming ` 'static ` , because for instance ` &'static &'a T `
8- will fail to typecheck, but the unbound lifetime will perfectly mold into
9- ` &'a &'a T ` as needed. However for most intents and purposes, such an unbounded
10- lifetime can be regarded as ` 'static ` .
4+ Such lifetimes come into the world as * unbounded* . The most common source of
5+ this is taking a reference to a dereferenced raw pointer, which produces a
6+ reference with an unbounded lifetime. Such a lifetime becomes as big as context
7+ demands. This is in fact more powerful than simply becoming ` 'static ` , because
8+ for instance ` &'static &'a T ` will fail to typecheck, but the unbound lifetime
9+ will perfectly mold into ` &'a &'a T ` as needed. However for most intents and
10+ purposes, such an unbounded lifetime can be regarded as ` 'static ` .
1111
1212Almost no reference is ` 'static ` , so this is probably wrong. ` transmute ` and
1313` transmute_copy ` are the two other primary offenders. One should endeavor to
@@ -17,17 +17,25 @@ boundaries.
1717Given a function, any output lifetimes that don't derive from inputs are
1818unbounded. For instance:
1919
20- <!-- ignore: simplified code -->
21- ``` rust,ignore
22- fn get_str<'a>() -> &'a str;
20+ <!-- no_run: This example exhibits undefined behavior. -->
21+ ``` rust,no_run
22+ fn get_str<'a>(s: *const String) -> &'a str {
23+ unsafe { &*s }
24+ }
25+
26+ fn main() {
27+ let soon_dropped = String::from("hello");
28+ let dangling = get_str(&soon_dropped);
29+ drop(soon_dropped);
30+ println!("Invalid str: {}", dangling); // Invalid str: gӚ_`
31+ }
2332```
2433
25- will produce an ` &str ` with an unbounded lifetime. The easiest way to avoid
26- unbounded lifetimes is to use lifetime elision at the function boundary.
27- If an output lifetime is elided, then it * must* be bounded by an input lifetime.
28- Of course it might be bounded by the * wrong* lifetime, but this will usually
29- just cause a compiler error, rather than allow memory safety to be trivially
30- violated.
34+ The easiest way to avoid unbounded lifetimes is to use lifetime elision at the
35+ function boundary. If an output lifetime is elided, then it * must* be bounded by
36+ an input lifetime. Of course it might be bounded by the * wrong* lifetime, but
37+ this will usually just cause a compiler error, rather than allow memory safety
38+ to be trivially violated.
3139
3240Within a function, bounding lifetimes is more error-prone. The safest and easiest
3341way to bound a lifetime is to return it from a function with a bound lifetime.
0 commit comments