diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 8d7192c1b0fd1..f87b6bbfcfb26 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -63,11 +63,39 @@
 //!
 //! ## Allocated object
 //!
-//! For several operations, such as [`offset`] or field projections (`expr.field`), the notion of an
-//! "allocated object" becomes relevant. An allocated object is a contiguous region of memory.
-//! Common examples of allocated objects include stack-allocated variables (each variable is a
-//! separate allocated object), heap allocations (each allocation created by the global allocator is
-//! a separate allocated object), and `static` variables.
+//! An *allocated object* is a subset of program memory which is addressable
+//! from Rust, and within which pointer arithmetic is possible. Examples of
+//! allocated objects include heap allocations, stack-allocated variables,
+//! statics, and consts. The safety preconditions of some Rust operations -
+//! such as `offset` and field projections (`expr.field`) - are defined in
+//! terms of the allocated objects on which they operate.
+//!
+//! An allocated object has a base address, a size, and a set of memory
+//! addresses. It is possible for an allocated object to have zero size, but
+//! such an allocated object will still have a base address. The base address
+//! of an allocated object is not necessarily unique. While it is currently the
+//! case that an allocated object always has a set of memory addresses which is
+//! fully contiguous (i.e., has no "holes"), there is no guarantee that this
+//! will not change in the future.
+//!
+//! For any allocated object with `base` address, `size`, and a set of
+//! `addresses`, the following are guaranteed:
+//! - For all addresses `a` in `addresses`, `a` is in the range `base .. (base +
+//!   size)` (note that this requires `a < base + size`, not `a <= base + size`)
+//! - `base` is not equal to [`null()`] (i.e., the address with the numerical
+//!   value 0)
+//! - `base + size <= usize::MAX`
+//! - `size <= isize::MAX`
+//!
+//! As a consequence of these guarantees, given any address `a` within the set
+//! of addresses of an allocated object:
+//! - It is guaranteed that `a - base` does not overflow `isize`
+//! - It is guaranteed that `a - base` is non-negative
+//! - It is guaranteed that, given `o = a - base` (i.e., the offset of `a` within
+//!   the allocated object), `base + o` will not wrap around the address space (in
+//!   other words, will not overflow `usize`)
+//!
+//! [`null()`]: null
 //!
 //! # Strict Provenance
 //!
diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md
index 9c2e05b57f5e8..3e1db692f50be 100644
--- a/src/doc/rustc/src/platform-support/fuchsia.md
+++ b/src/doc/rustc/src/platform-support/fuchsia.md
@@ -387,7 +387,7 @@ meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm
 ```
 
 *Note: Relative manifest paths are resolved starting from the working directory
-of `pm`. Make sure to fill out `<SDK_PATH>` with the path to the downloaded
+of `ffx`. Make sure to fill out `<SDK_PATH>` with the path to the downloaded
 SDK.*
 
 The `.manifest` file will be used to describe the contents of the package by
@@ -459,12 +459,10 @@ hello_fuchsia/
 Next, we'll build a package manifest as defined by our manifest:
 
 ```sh
-${SDK_PATH}/tools/${ARCH}/pm \
-    -api-level $(${SDK_PATH}/tools/${ARCH}/ffx version -v | grep "api-level" | head -1 |  awk -F ' ' '{print $2}') \
-    -o pkg/hello_fuchsia_manifest \
-    -m pkg/hello_fuchsia.manifest \
-    build \
-    -output-package-manifest pkg/hello_fuchsia_package_manifest
+${SDK_PATH}/tools/${ARCH}/ffx package build \
+    --api-level $(${SDK_PATH}/tools/${ARCH}/ffx --machine json version | jq .tool_version.api_level) \
+    --out pkg/hello_fuchsia_manifest \
+    pkg/hello_fuchsia.manifest
 ```
 
 This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can
@@ -498,8 +496,7 @@ to.
 We can set up our repository with:
 
 ```sh
-${SDK_PATH}/tools/${ARCH}/pm newrepo \
-    -repo pkg/repo
+${SDK_PATH}/tools/${ARCH}/ffx repository create pkg/repo
 ```
 
 **Current directory structure**
@@ -523,17 +520,17 @@ hello_fuchsia/
 We can publish our new package to that repository with:
 
 ```sh
-${SDK_PATH}/tools/${ARCH}/pm publish \
-    -repo pkg/repo \
-    -lp -f <(echo "pkg/hello_fuchsia_package_manifest")
+${SDK_PATH}/tools/${ARCH}/ffx repository publish \
+    --package pkg/hello_fuchsia_package_manifest \
+    pkg/repo
 ```
 
 Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using:
 
 ```sh
 ${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \
-    pkg/repo \
-    -r hello-fuchsia
+    --repository hello-fuchsia \
+    pkg/repo
 ```
 
 ## Running a Fuchsia component on an emulator
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 18a7cb168b3b4..ca75da9ca2108 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -241,7 +241,6 @@ run-make/rlib-format-packed-bundled-libs-3/Makefile
 run-make/rlib-format-packed-bundled-libs/Makefile
 run-make/rmeta-preferred/Makefile
 run-make/rustc-macro-dep-files/Makefile
-run-make/rustdoc-io-error/Makefile
 run-make/rustdoc-scrape-examples-invalid-expr/Makefile
 run-make/rustdoc-scrape-examples-macros/Makefile
 run-make/rustdoc-scrape-examples-multiple/Makefile
diff --git a/tests/run-make/rustdoc-io-error/Makefile b/tests/run-make/rustdoc-io-error/Makefile
deleted file mode 100644
index 27f5ecf94aba3..0000000000000
--- a/tests/run-make/rustdoc-io-error/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-include ../tools.mk
-
-# This test verifies that rustdoc doesn't ICE when it encounters an IO error
-# while generating files. Ideally this would be a rustdoc-ui test, so we could
-# verify the error message as well.
-
-# ignore-windows
-# The test uses `chmod`.
-
-OUTPUT_DIR := "$(TMPDIR)/rustdoc-io-error"
-
-# This test operates by creating a temporary directory and modifying its
-# permissions so that it is not writable. We have to take special care to set
-# the permissions back to normal so that it's able to be deleted later.
-all:
-	mkdir -p $(OUTPUT_DIR)
-	chmod u-w $(OUTPUT_DIR)
-	-$(shell $(RUSTDOC) -o $(OUTPUT_DIR) foo.rs)
-	chmod u+w $(OUTPUT_DIR)
-	exit $($(.SHELLSTATUS) -eq 1)
diff --git a/tests/run-make/rustdoc-io-error/rmake.rs b/tests/run-make/rustdoc-io-error/rmake.rs
new file mode 100644
index 0000000000000..b1d31395e3de8
--- /dev/null
+++ b/tests/run-make/rustdoc-io-error/rmake.rs
@@ -0,0 +1,32 @@
+// This test verifies that rustdoc doesn't ICE when it encounters an IO error
+// while generating files. Ideally this would be a rustdoc-ui test, so we could
+// verify the error message as well.
+//
+// It operates by creating a temporary directory and modifying its
+// permissions so that it is not writable. We have to take special care to set
+// the permissions back to normal so that it's able to be deleted later.
+
+use run_make_support::{rustdoc, tmp_dir};
+use std::fs;
+
+fn main() {
+    let out_dir = tmp_dir().join("rustdoc-io-error");
+    let output = fs::create_dir(&out_dir).unwrap();
+    let mut permissions = fs::metadata(&out_dir).unwrap().permissions();
+    let original_permissions = permissions.clone();
+    permissions.set_readonly(true);
+    fs::set_permissions(&out_dir, permissions.clone()).unwrap();
+
+    let output = rustdoc().input("foo.rs").output(&out_dir).command_output();
+
+    // Changing back permissions.
+    fs::set_permissions(&out_dir, original_permissions).unwrap();
+
+    // Checks that rustdoc failed with the error code 1.
+    #[cfg(unix)]
+    assert_eq!(output.status.code().unwrap(), 1);
+    assert!(!output.status.success());
+    let stderr = String::from_utf8(output.stderr).unwrap();
+
+    assert!(stderr.contains("error: couldn't generate documentation: Permission denied"));
+}