From 4a5f81c16ff071420a9acca11f406d773d246fb2 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 10 Jun 2026 19:46:58 +0000 Subject: [PATCH] Generalize the wide-pointer total-size bound We document that, for references and `Box`, pointed-to values with slice or `str` metadata must be no larger than `isize::MAX`. We hadn't required this for pointed-to values with `dyn` metadata. It's tempting to think this isn't necessary since we separately require that the metadata point to a vtable generated by the compiler, which ensures the encoded size of the erased type is OK. But the bound is on the total size of the pointed-to value, including any sized prefix of a type with an unsized tail. Since the prefix combined with the size in the vtable can push us past the limit, we need the separate restriction. Let's apply the rule to both cases and add an admonition to remind ourselves of why this is needed. --- src/behavior-considered-undefined.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index a4a285cc9a..28ec9f5ade 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -147,7 +147,12 @@ r[undefined.validity.reference-box] r[undefined.validity.wide] * The [metadata] of a wide reference, [`Box`], or raw pointer must match the type of the [unsized tail]: * `dyn Trait` metadata must be a pointer to a compiler-generated vtable for `Trait`. (For raw pointers, this requirement remains a subject of some debate.) - * Slice (`[T]`) and `str` metadata must be a valid `usize`. Furthermore, for wide references and [`Box`], this metadata is invalid if it makes the total size of the pointed-to value bigger than `isize::MAX`. + * Slice (`[T]`) and `str` metadata must be a valid `usize`. + + In addition, for a wide reference or [`Box`], the metadata is invalid if it makes the total size of the pointed-to value (as determined by `size_of_val`) bigger than `isize::MAX`. + + > [!NOTE] + > This bound is on the size of the entire pointed-to value, not just its unsized tail, and it constrains `dyn Trait` metadata just as it does a slice or `str` length. A valid vtable describes an erased type no larger than `isize::MAX`, but a sized prefix can still carry the total past the limit. r[undefined.validity.valid-range] * If a type has a custom range of valid values, then a valid value must be in that range. In the standard library, this affects [`NonNull`] and [`NonZero`].