From a64e5d91da0c22f3999552fec9179db71b5e143a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 25 Aug 2019 12:44:51 +0200 Subject: [PATCH 01/16] update UB --- src/behavior-considered-undefined.md | 56 +++++++++++++++++----------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index b6a9aabe9..bac2d93a1 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -23,30 +23,38 @@ code. * Data races. -* Dereferencing a null or dangling raw pointer. -* Unaligned pointer reading and writing outside of [`read_unaligned`] - and [`write_unaligned`]. -* Reads of [undef] \(uninitialized) memory. -* Breaking the [pointer aliasing rules] on accesses through raw pointers; - a subset of the rules used by C. -* `&mut T` and `&T` follow LLVM’s scoped [noalias] model, except if the `&T` - contains an [`UnsafeCell`]. -* Mutating non-mutable data — that is, data reached through a shared +* Dereferencing (using the `*` operator on) a dangling or unaligned raw pointer. +* Breaking the [pointer aliasing rules]. `&mut T` and `&T` follow LLVM’s scoped + [noalias] model, except if the `&T` contains an [`UnsafeCell`]. +* Mutating non-mutable data (that is, data reached through a shared reference or data owned by a `let` binding), unless that data is contained within an [`UnsafeCell`]. -* Invoking undefined behavior via compiler intrinsics: - * Indexing outside of the bounds of an object with [`offset`] with - the exception of one byte past the end of the object. - * Using [`std::ptr::copy_nonoverlapping_memory`], a.k.a. the `memcpy32`and - `memcpy64` intrinsics, on overlapping buffers. -* Invalid values in primitive types, even in private fields and locals: - * Dangling or null references and boxes. +* Invoking undefined behavior via compiler intrinsics. +* Executing code compiled with platform features that the current platform + does not support (see [`target_feature`]). +* Unwinding into another language. +* Producing an invalid value, even in private fields and locals. "Producing" a + value happens any time a value is assigned, passed to a function/primitive + operation or returned from a function/primitive operation. + The following values are invalid (at their respective type): * A value other than `false` (`0`) or `true` (`1`) in a `bool`. * A discriminant in an `enum` not included in the type definition. + * A null `fn` pointer. * A value in a `char` which is a surrogate or above `char::MAX`. + * A `!` (all values are invalid for this type). + * A dangling or unaligned reference or `Box`, or one that points to an invalid value. + * Invalid metadata in a wide reference, `Box` or raw pointer: + * slice metadata is invalid if the slice has a total size larger than + `isize::MAX` bytes in memory. + * `dyn Trait` metadata is invalid if it is not a pointer to a vtable for + `Trait` that matches the actual dynamic trait the reference points to. * Non-UTF-8 byte sequences in a `str`. -* Executing code compiled with platform features that the current platform - does not support (see [`target_feature`]). + * [Uninitialized memory][undef] in the value of an integer (`i*`/`u*`), + floating point value (`f*`), or raw pointer. + * Invalid values for a type with a custom definition of invalid values, such + as a `NonNull` that is null. (Requesting custom invalid values is an + unstable feature, but some stable libstd types, like `NonNull`, make use of + it.) > **Note**: Undefined behavior affects the entire program. For example, calling > a function in C that exhibits undefined behavior of C means your entire @@ -54,13 +62,17 @@ code. > vice versa, undefined behavior in Rust can cause adverse affects on code > executed by any FFI calls to other languages. +A reference/pointer is "dangling" if it is null or not all of the bytes it +points to are part of the same allocation (so in particular they all have to be +part of *some* allocation). The span of bytes it points to is determined by the +pointer value and the size of the pointee type. As a consequence, if the span is +empty, "dangling" is the same as "non-null". Note that slices point to their +entire range, so it is very important that the length metadata is never too +large. + [noalias]: http://llvm.org/docs/LangRef.html#noalias [pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules [undef]: http://llvm.org/docs/LangRef.html#undefined-values -[`offset`]: ../std/primitive.pointer.html#method.offset -[`std::ptr::copy_nonoverlapping_memory`]: ../std/ptr/fn.copy_nonoverlapping.html [`target_feature`]: attributes/codegen.md#the-target_feature-attribute [`UnsafeCell`]: ../std/cell/struct.UnsafeCell.html -[`read_unaligned`]: ../std/ptr/fn.read_unaligned.html -[`write_unaligned`]: ../std/ptr/fn.write_unaligned.html [Rustonomicon]: ../nomicon/index.html From 6a6b0176a1566d7c46377d2271d99d31b42260b5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 26 Aug 2019 19:55:18 +0200 Subject: [PATCH 02/16] fix slice metadata --- src/behavior-considered-undefined.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index bac2d93a1..644c28e23 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -42,15 +42,15 @@ code. * A null `fn` pointer. * A value in a `char` which is a surrogate or above `char::MAX`. * A `!` (all values are invalid for this type). + * [Uninitialized memory][undef] in the value of an integer (`i*`/`u*`), + floating point value (`f*`), or raw pointer. * A dangling or unaligned reference or `Box`, or one that points to an invalid value. - * Invalid metadata in a wide reference, `Box` or raw pointer: - * slice metadata is invalid if the slice has a total size larger than - `isize::MAX` bytes in memory. + * Invalid metadata in a wide reference, `Box`, or raw pointer: * `dyn Trait` metadata is invalid if it is not a pointer to a vtable for `Trait` that matches the actual dynamic trait the reference points to. + * Slice metadata is invalid if if the length is not a valid `usize` + (i.e., it must not be read from uninitialized memory). * Non-UTF-8 byte sequences in a `str`. - * [Uninitialized memory][undef] in the value of an integer (`i*`/`u*`), - floating point value (`f*`), or raw pointer. * Invalid values for a type with a custom definition of invalid values, such as a `NonNull` that is null. (Requesting custom invalid values is an unstable feature, but some stable libstd types, like `NonNull`, make use of @@ -68,7 +68,8 @@ part of *some* allocation). The span of bytes it points to is determined by the pointer value and the size of the pointee type. As a consequence, if the span is empty, "dangling" is the same as "non-null". Note that slices point to their entire range, so it is very important that the length metadata is never too -large. +large. In particular, allocations and therefore slices cannot be bigger than +`isize::MAX` bytes. [noalias]: http://llvm.org/docs/LangRef.html#noalias [pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules From a93e37a836f315c53316aa55e64a906e3780569c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 26 Aug 2019 20:01:05 +0200 Subject: [PATCH 03/16] Apply suggestions from code review Co-Authored-By: Mazdak Farrokhzad --- src/behavior-considered-undefined.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 644c28e23..4b6193f5b 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -44,15 +44,15 @@ code. * A `!` (all values are invalid for this type). * [Uninitialized memory][undef] in the value of an integer (`i*`/`u*`), floating point value (`f*`), or raw pointer. - * A dangling or unaligned reference or `Box`, or one that points to an invalid value. + * A reference or `Box` that is dangling, unaligned, or points to an invalid value. * Invalid metadata in a wide reference, `Box`, or raw pointer: * `dyn Trait` metadata is invalid if it is not a pointer to a vtable for - `Trait` that matches the actual dynamic trait the reference points to. + `Trait` that matches the actual dynamic trait the pointer or reference points to. * Slice metadata is invalid if if the length is not a valid `usize` (i.e., it must not be read from uninitialized memory). * Non-UTF-8 byte sequences in a `str`. * Invalid values for a type with a custom definition of invalid values, such - as a `NonNull` that is null. (Requesting custom invalid values is an + as a `NonNull` that is null. (Requesting custom invalid values is an unstable feature, but some stable libstd types, like `NonNull`, make use of it.) @@ -67,7 +67,7 @@ points to are part of the same allocation (so in particular they all have to be part of *some* allocation). The span of bytes it points to is determined by the pointer value and the size of the pointee type. As a consequence, if the span is empty, "dangling" is the same as "non-null". Note that slices point to their -entire range, so it is very important that the length metadata is never too +entire range, so it is important that the length metadata is never too large. In particular, allocations and therefore slices cannot be bigger than `isize::MAX` bytes. From 90251b3a833981ca93eabecdb0e2e2775e52e609 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 26 Aug 2019 20:04:09 +0200 Subject: [PATCH 04/16] tweaks --- src/behavior-considered-undefined.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 4b6193f5b..142f71d72 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -34,8 +34,9 @@ code. does not support (see [`target_feature`]). * Unwinding into another language. * Producing an invalid value, even in private fields and locals. "Producing" a - value happens any time a value is assigned, passed to a function/primitive - operation or returned from a function/primitive operation. + value happens any time a value is assigned to or read from a place, passed to + a function/primitive operation or returned from a function/primitive + operation. The following values are invalid (at their respective type): * A value other than `false` (`0`) or `true` (`1`) in a `bool`. * A discriminant in an `enum` not included in the type definition. @@ -45,7 +46,7 @@ code. * [Uninitialized memory][undef] in the value of an integer (`i*`/`u*`), floating point value (`f*`), or raw pointer. * A reference or `Box` that is dangling, unaligned, or points to an invalid value. - * Invalid metadata in a wide reference, `Box`, or raw pointer: + * Invalid metadata in a wide reference, `Box`, or raw pointer: * `dyn Trait` metadata is invalid if it is not a pointer to a vtable for `Trait` that matches the actual dynamic trait the pointer or reference points to. * Slice metadata is invalid if if the length is not a valid `usize` From e8303bea57a8511628308873c23c94d288c12af8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 26 Aug 2019 20:18:11 +0200 Subject: [PATCH 05/16] let is too specific --- src/behavior-considered-undefined.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 142f71d72..63d3f0534 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -27,7 +27,7 @@ code. * Breaking the [pointer aliasing rules]. `&mut T` and `&T` follow LLVM’s scoped [noalias] model, except if the `&T` contains an [`UnsafeCell`]. * Mutating non-mutable data (that is, data reached through a shared - reference or data owned by a `let` binding), unless that data is contained + reference or data owned by an immutable binding), unless that data is contained within an [`UnsafeCell`]. * Invoking undefined behavior via compiler intrinsics. * Executing code compiled with platform features that the current platform From 7b76cc37537dfa0b5c6cb69fe33c34ed48f312ca Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 26 Aug 2019 22:23:37 +0200 Subject: [PATCH 06/16] make it more clear that the uninit-mem clause is type-driven --- src/behavior-considered-undefined.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 63d3f0534..223e92fa9 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -43,8 +43,8 @@ code. * A null `fn` pointer. * A value in a `char` which is a surrogate or above `char::MAX`. * A `!` (all values are invalid for this type). - * [Uninitialized memory][undef] in the value of an integer (`i*`/`u*`), - floating point value (`f*`), or raw pointer. + * An integer (`i*`/`u*`), floating point value (`f*`), or raw pointer obtained + from [uninitialized memory][undef]. * A reference or `Box` that is dangling, unaligned, or points to an invalid value. * Invalid metadata in a wide reference, `Box`, or raw pointer: * `dyn Trait` metadata is invalid if it is not a pointer to a vtable for From 5c7362c5745965d7fd19c0323271e04dce06b58b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2019 10:46:58 +0200 Subject: [PATCH 07/16] note rustc-specific details --- src/behavior-considered-undefined.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 223e92fa9..74b62bd1a 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -52,10 +52,10 @@ code. * Slice metadata is invalid if if the length is not a valid `usize` (i.e., it must not be read from uninitialized memory). * Non-UTF-8 byte sequences in a `str`. - * Invalid values for a type with a custom definition of invalid values, such - as a `NonNull` that is null. (Requesting custom invalid values is an - unstable feature, but some stable libstd types, like `NonNull`, make use of - it.) + * Invalid values for a type with a custom definition of invalid values. + + > **Note**: For `rustc`, those types are [`NonNull`] and [`NonZero*`]. + > Requesting custom invalid types requires the unstable `rustc_layout_scalar_valid_range_*` attributes. > **Note**: Undefined behavior affects the entire program. For example, calling > a function in C that exhibits undefined behavior of C means your entire @@ -78,3 +78,5 @@ large. In particular, allocations and therefore slices cannot be bigger than [`target_feature`]: attributes/codegen.md#the-target_feature-attribute [`UnsafeCell`]: ../std/cell/struct.UnsafeCell.html [Rustonomicon]: ../nomicon/index.html +[`NonNull`]: ../core/ptr/struct.NonNull.html +[`NonZero*`]: ../core/num/index.html From 1fc9b119e26a22b68a8a6651f756bc3b4d9926fa Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2019 10:47:48 +0200 Subject: [PATCH 08/16] avoid two notes right next to each other --- src/behavior-considered-undefined.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 74b62bd1a..7aaff5134 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -57,12 +57,6 @@ code. > **Note**: For `rustc`, those types are [`NonNull`] and [`NonZero*`]. > Requesting custom invalid types requires the unstable `rustc_layout_scalar_valid_range_*` attributes. -> **Note**: Undefined behavior affects the entire program. For example, calling -> a function in C that exhibits undefined behavior of C means your entire -> program contains undefined behaviour that can also affect the Rust code. And -> vice versa, undefined behavior in Rust can cause adverse affects on code -> executed by any FFI calls to other languages. - A reference/pointer is "dangling" if it is null or not all of the bytes it points to are part of the same allocation (so in particular they all have to be part of *some* allocation). The span of bytes it points to is determined by the @@ -72,6 +66,12 @@ entire range, so it is important that the length metadata is never too large. In particular, allocations and therefore slices cannot be bigger than `isize::MAX` bytes. +> **Note**: Undefined behavior affects the entire program. For example, calling +> a function in C that exhibits undefined behavior of C means your entire +> program contains undefined behaviour that can also affect the Rust code. And +> vice versa, undefined behavior in Rust can cause adverse affects on code +> executed by any FFI calls to other languages. + [noalias]: http://llvm.org/docs/LangRef.html#noalias [pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules [undef]: http://llvm.org/docs/LangRef.html#undefined-values From ccf3d7a1b5e3c185cb2427857da273d3d4e3805e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2019 10:48:23 +0200 Subject: [PATCH 09/16] typo --- src/behavior-considered-undefined.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 7aaff5134..32e982a14 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -55,7 +55,7 @@ code. * Invalid values for a type with a custom definition of invalid values. > **Note**: For `rustc`, those types are [`NonNull`] and [`NonZero*`]. - > Requesting custom invalid types requires the unstable `rustc_layout_scalar_valid_range_*` attributes. + > Requesting custom invalid values requires the unstable `rustc_layout_scalar_valid_range_*` attributes. A reference/pointer is "dangling" if it is null or not all of the bytes it points to are part of the same allocation (so in particular they all have to be From f10ed4b986c6b05bdb5b341ad321bb1ad8736e4f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2019 10:53:48 +0200 Subject: [PATCH 10/16] move libstd concerns out of the rustc note --- src/behavior-considered-undefined.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 32e982a14..31841e573 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -53,9 +53,10 @@ code. (i.e., it must not be read from uninitialized memory). * Non-UTF-8 byte sequences in a `str`. * Invalid values for a type with a custom definition of invalid values. + In the standard library, this affects [`NonNull`] and [`NonZero*`]. - > **Note**: For `rustc`, those types are [`NonNull`] and [`NonZero*`]. - > Requesting custom invalid values requires the unstable `rustc_layout_scalar_valid_range_*` attributes. + > **Note**: For `rustc`, requesting custom invalid values requires the + > unstable `rustc_layout_scalar_valid_range_*` attributes. A reference/pointer is "dangling" if it is null or not all of the bytes it points to are part of the same allocation (so in particular they all have to be From c9e23d1ce91897bbe668588b87c2292e181d478a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2019 12:29:45 +0200 Subject: [PATCH 11/16] generalize from uwnind ABI --- src/behavior-considered-undefined.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 31841e573..9066b05e4 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -32,7 +32,7 @@ code. * Invoking undefined behavior via compiler intrinsics. * Executing code compiled with platform features that the current platform does not support (see [`target_feature`]). -* Unwinding into another language. +* Calling a function with the wrong call ABI (including unwind ABI). * Producing an invalid value, even in private fields and locals. "Producing" a value happens any time a value is assigned to or read from a place, passed to a function/primitive operation or returned from a function/primitive From ad60b7a5f9ea9dc3ea11cf4df38eb2267f03ab34 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2019 12:30:52 +0200 Subject: [PATCH 12/16] more concise note --- src/behavior-considered-undefined.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 9066b05e4..d3d48dc28 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -55,8 +55,8 @@ code. * Invalid values for a type with a custom definition of invalid values. In the standard library, this affects [`NonNull`] and [`NonZero*`]. - > **Note**: For `rustc`, requesting custom invalid values requires the - > unstable `rustc_layout_scalar_valid_range_*` attributes. + > **Note**: `rustc` achieves this with the unstable + > `rustc_layout_scalar_valid_range_*` attributes. A reference/pointer is "dangling" if it is null or not all of the bytes it points to are part of the same allocation (so in particular they all have to be From 3c18f693261c271548f2efdd50a5cf42310143d8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2019 12:51:33 +0200 Subject: [PATCH 13/16] clarify --- src/behavior-considered-undefined.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index d3d48dc28..19d759b6b 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -32,7 +32,7 @@ code. * Invoking undefined behavior via compiler intrinsics. * Executing code compiled with platform features that the current platform does not support (see [`target_feature`]). -* Calling a function with the wrong call ABI (including unwind ABI). +* Calling a function with the wrong call ABI (in particular, with the wrong unwind ABI). * Producing an invalid value, even in private fields and locals. "Producing" a value happens any time a value is assigned to or read from a place, passed to a function/primitive operation or returned from a function/primitive From 80432783ebe36028bf6803f8c4895da5936679f1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2019 19:06:25 +0200 Subject: [PATCH 14/16] sync with nomicon --- src/behavior-considered-undefined.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 19d759b6b..7751d1359 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -32,7 +32,7 @@ code. * Invoking undefined behavior via compiler intrinsics. * Executing code compiled with platform features that the current platform does not support (see [`target_feature`]). -* Calling a function with the wrong call ABI (in particular, with the wrong unwind ABI). +* Calling a function with the wrong call ABI or wrong unwind ABI. * Producing an invalid value, even in private fields and locals. "Producing" a value happens any time a value is assigned to or read from a place, passed to a function/primitive operation or returned from a function/primitive From 6e175823457e7aed78641c87c009b2ad5977c4a5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 29 Aug 2019 10:49:41 +0200 Subject: [PATCH 15/16] update immutability rule --- src/behavior-considered-undefined.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 7751d1359..223f4fd4f 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -26,9 +26,9 @@ code. * Dereferencing (using the `*` operator on) a dangling or unaligned raw pointer. * Breaking the [pointer aliasing rules]. `&mut T` and `&T` follow LLVM’s scoped [noalias] model, except if the `&T` contains an [`UnsafeCell`]. -* Mutating non-mutable data (that is, data reached through a shared - reference or data owned by an immutable binding), unless that data is contained - within an [`UnsafeCell`]. +* Mutating immutable data. All data inside a `const` is immutable. Moreover, all + data reached through a shared reference or data owned by an immutable binding + is immutable, unless that data is contained within an [`UnsafeCell`]. * Invoking undefined behavior via compiler intrinsics. * Executing code compiled with platform features that the current platform does not support (see [`target_feature`]). From 6c9a399153febd66b5c9a4c08f3e787be5f4511a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 29 Aug 2019 11:19:05 +0200 Subject: [PATCH 16/16] Apply suggestions from code review Co-Authored-By: Mazdak Farrokhzad --- src/behavior-considered-undefined.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 223f4fd4f..437a86212 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -26,7 +26,7 @@ code. * Dereferencing (using the `*` operator on) a dangling or unaligned raw pointer. * Breaking the [pointer aliasing rules]. `&mut T` and `&T` follow LLVM’s scoped [noalias] model, except if the `&T` contains an [`UnsafeCell`]. -* Mutating immutable data. All data inside a `const` is immutable. Moreover, all +* Mutating immutable data. All data inside a [`const`] item is immutable. Moreover, all data reached through a shared reference or data owned by an immutable binding is immutable, unless that data is contained within an [`UnsafeCell`]. * Invoking undefined behavior via compiler intrinsics. @@ -73,6 +73,7 @@ large. In particular, allocations and therefore slices cannot be bigger than > vice versa, undefined behavior in Rust can cause adverse affects on code > executed by any FFI calls to other languages. +[`const`]: items/constant-items.html [noalias]: http://llvm.org/docs/LangRef.html#noalias [pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules [undef]: http://llvm.org/docs/LangRef.html#undefined-values