summaryrefslogtreecommitdiffstats
path: root/src/doc/nomicon
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:42 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:42 +0000
commit837b550238aa671a591ccf282dddeab29cadb206 (patch)
tree914b6b8862bace72bd3245ca184d374b08d8a672 /src/doc/nomicon
parentAdding debian version 1.70.0+dfsg2-1. (diff)
downloadrustc-837b550238aa671a591ccf282dddeab29cadb206.tar.xz
rustc-837b550238aa671a591ccf282dddeab29cadb206.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/doc/nomicon')
-rw-r--r--src/doc/nomicon/book.toml2
-rw-r--r--src/doc/nomicon/src/intro.md2
-rw-r--r--src/doc/nomicon/src/unbounded-lifetimes.md40
3 files changed, 26 insertions, 18 deletions
diff --git a/src/doc/nomicon/book.toml b/src/doc/nomicon/book.toml
index a2011c61f..693aca4a4 100644
--- a/src/doc/nomicon/book.toml
+++ b/src/doc/nomicon/book.toml
@@ -32,4 +32,4 @@ git-repository-url = "https://github.com/rust-lang/nomicon"
"./arc.html" = "./arc-mutex/arc.html"
[rust]
-edition = "2018"
+edition = "2021"
diff --git a/src/doc/nomicon/src/intro.md b/src/doc/nomicon/src/intro.md
index 4e77ffafe..323c0ceb3 100644
--- a/src/doc/nomicon/src/intro.md
+++ b/src/doc/nomicon/src/intro.md
@@ -39,7 +39,7 @@ Topics that are within the scope of this book include: the meaning of (un)safety
The Rustonomicon is not a place to exhaustively describe the semantics and guarantees of every single API in the standard library, nor is it a place to exhaustively describe every feature of Rust.
-Unless otherwise noted, Rust code in this book uses the Rust 2018 edition.
+Unless otherwise noted, Rust code in this book uses the Rust 2021 edition.
[trpl]: ../book/index.html
[ref]: ../reference/index.html
diff --git a/src/doc/nomicon/src/unbounded-lifetimes.md b/src/doc/nomicon/src/unbounded-lifetimes.md
index 03febd6ad..9ca2a2f2e 100644
--- a/src/doc/nomicon/src/unbounded-lifetimes.md
+++ b/src/doc/nomicon/src/unbounded-lifetimes.md
@@ -1,13 +1,13 @@
# Unbounded Lifetimes
Unsafe code can often end up producing references or lifetimes out of thin air.
-Such lifetimes come into the world as *unbounded*. The most common source of this
-is dereferencing a raw pointer, which produces a reference with an unbounded lifetime.
-Such a lifetime becomes as big as context demands. This is in fact more powerful
-than simply becoming `'static`, because for instance `&'static &'a T`
-will fail to typecheck, but the unbound lifetime will perfectly mold into
-`&'a &'a T` as needed. However for most intents and purposes, such an unbounded
-lifetime can be regarded as `'static`.
+Such lifetimes come into the world as *unbounded*. The most common source of
+this is taking a reference to a dereferenced raw pointer, which produces a
+reference with an unbounded lifetime. Such a lifetime becomes as big as context
+demands. This is in fact more powerful than simply becoming `'static`, because
+for instance `&'static &'a T` will fail to typecheck, but the unbound lifetime
+will perfectly mold into `&'a &'a T` as needed. However for most intents and
+purposes, such an unbounded lifetime can be regarded as `'static`.
Almost no reference is `'static`, so this is probably wrong. `transmute` and
`transmute_copy` are the two other primary offenders. One should endeavor to
@@ -17,17 +17,25 @@ boundaries.
Given a function, any output lifetimes that don't derive from inputs are
unbounded. For instance:
-<!-- ignore: simplified code -->
-```rust,ignore
-fn get_str<'a>() -> &'a str;
+<!-- no_run: This example exhibits undefined behavior. -->
+```rust,no_run
+fn get_str<'a>(s: *const String) -> &'a str {
+ unsafe { &*s }
+}
+
+fn main() {
+ let soon_dropped = String::from("hello");
+ let dangling = get_str(&soon_dropped);
+ drop(soon_dropped);
+ println!("Invalid str: {}", dangling); // Invalid str: gӚ_`
+}
```
-will produce an `&str` with an unbounded lifetime. The easiest way to avoid
-unbounded lifetimes is to use lifetime elision at the function boundary.
-If an output lifetime is elided, then it *must* be bounded by an input lifetime.
-Of course it might be bounded by the *wrong* lifetime, but this will usually
-just cause a compiler error, rather than allow memory safety to be trivially
-violated.
+The easiest way to avoid unbounded lifetimes is to use lifetime elision at the
+function boundary. If an output lifetime is elided, then it *must* be bounded by
+an input lifetime. Of course it might be bounded by the *wrong* lifetime, but
+this will usually just cause a compiler error, rather than allow memory safety
+to be trivially violated.
Within a function, bounding lifetimes is more error-prone. The safest and easiest
way to bound a lifetime is to return it from a function with a bound lifetime.