Skip to content

Commit b23eb69

Browse files
committed
operator expressions: add &raw
1 parent 7226782 commit b23eb69

File tree

2 files changed

+14
-16
lines changed

2 files changed

+14
-16
lines changed

src/expressions.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ A *value expression* is an expression that represents an actual value.
146146
The following contexts are *place expression* contexts:
147147

148148
* The left operand of a [compound assignment] expression.
149-
* The operand of a unary [borrow], [address-of][addr-of] or [dereference][deref] operator.
149+
* The operand of a unary [borrow], [raw borrow][raw-borrow] or [dereference][deref] operator.
150150
* The operand of a field expression.
151151
* The indexed operand of an array indexing expression.
152152
* The operand of any [implicit borrow].
@@ -276,7 +276,7 @@ They are never allowed before:
276276

277277
[assign]: expressions/operator-expr.md#assignment-expressions
278278
[borrow]: expressions/operator-expr.md#borrow-operators
279-
[addr-of]: expressions/operator-expr.md#raw-address-of-operators
279+
[raw-borrow]: expressions/operator-expr.md#raw-borrow-operators
280280
[comparison]: expressions/operator-expr.md#comparison-operators
281281
[compound assignment]: expressions/operator-expr.md#compound-assignment-expressions
282282
[deref]: expressions/operator-expr.md#the-dereference-operator

src/expressions/operator-expr.md

+12-14
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ The following things are considered to be overflow:
4141
> **<sup>Syntax</sup>**\
4242
> _BorrowExpression_ :\
4343
> &nbsp;&nbsp; &nbsp;&nbsp; (`&`|`&&`) [_Expression_]\
44-
> &nbsp;&nbsp; | (`&`|`&&`) `mut` [_Expression_]
44+
> &nbsp;&nbsp; | (`&`|`&&`) `mut` [_Expression_]\
45+
> &nbsp;&nbsp; | (`&`|`&&`) `raw` `const` [_Expression_]\
46+
> &nbsp;&nbsp; | (`&`|`&&`) `raw` `mut` [_Expression_]
4547
4648
The `&` (shared borrow) and `&mut` (mutable borrow) operators are unary prefix operators.
4749
When applied to a [place expression], this expressions produces a reference (pointer) to the location that the value refers to.
@@ -79,20 +81,18 @@ let a = && && mut 10;
7981
let a = & & & & mut 10;
8082
```
8183

82-
### Raw address-of operators
84+
### Raw borrow operators
8385

84-
Related to the borrow operators are the *raw address-of operators*, which do not have first-class syntax, but are exposed via the macros [`ptr::addr_of!(expr)`][addr_of] and [`ptr::addr_of_mut!(expr)`][addr_of_mut].
85-
The expression `expr` is evaluated in place expression context.
86-
`ptr::addr_of!(expr)` then creates a const raw pointer of type `*const T` to the given place, and `ptr::addr_of_mut!(expr)` creates a mutable raw pointer of type `*mut T`.
86+
`&raw const` and `&raw mut` are the *raw borrow operators*.
87+
The operand expression of these operators is evaluated in place expression context.
88+
`&raw const expr` then creates a const raw pointer of type `*const T` to the given place, and `&raw mut expr` creates a mutable raw pointer of type `*mut T`.
8789

88-
The raw address-of operators must be used instead of a borrow operator whenever the place expression could evaluate to a place that is not properly aligned or does not store a valid value as determined by its type, or whenever creating a reference would introduce incorrect aliasing assumptions.
89-
In those situations, using a borrow operator would cause [undefined behavior] by creating an invalid reference, but a raw pointer may still be constructed using an address-of operator.
90+
The raw borrow operators must be used instead of a borrow operator whenever the place expression could evaluate to a place that is not properly aligned or does not store a valid value as determined by its type, or whenever creating a reference would introduce incorrect aliasing assumptions.
91+
In those situations, using a borrow operator would cause [undefined behavior] by creating an invalid reference, but a raw pointer may still be constructed.
9092

9193
The following is an example of creating a raw pointer to an unaligned place through a `packed` struct:
9294

9395
```rust
94-
use std::ptr;
95-
9696
#[repr(packed)]
9797
struct Packed {
9898
f1: u8,
@@ -101,14 +101,14 @@ struct Packed {
101101

102102
let packed = Packed { f1: 1, f2: 2 };
103103
// `&packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
104-
let raw_f2 = ptr::addr_of!(packed.f2);
104+
let raw_f2 = &raw const packed.f2;
105105
assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
106106
```
107107

108108
The following is an example of creating a raw pointer to a place that does not contain a valid value:
109109

110110
```rust
111-
use std::{ptr, mem::MaybeUninit};
111+
use std::mem::MaybeUninit;
112112

113113
struct Demo {
114114
field: bool,
@@ -117,7 +117,7 @@ struct Demo {
117117
let mut uninit = MaybeUninit::<Demo>::uninit();
118118
// `&uninit.as_mut().field` would create a reference to an uninitialized `bool`,
119119
// and thus be Undefined Behavior!
120-
let f1_ptr = unsafe { ptr::addr_of_mut!((*uninit.as_mut_ptr()).field) };
120+
let f1_ptr = unsafe { &raw mut (*uninit.as_mut_ptr()).field };
121121
unsafe { f1_ptr.write(true); }
122122
let init = unsafe { uninit.assume_init() };
123123
```
@@ -674,8 +674,6 @@ See [this test] for an example of using this dependency.
674674
[Function pointer]: ../types/function-pointer.md
675675
[Function item]: ../types/function-item.md
676676
[undefined behavior]: ../behavior-considered-undefined.md
677-
[addr_of]: ../../std/ptr/macro.addr_of.html
678-
[addr_of_mut]: ../../std/ptr/macro.addr_of_mut.html
679677

680678
[_BorrowExpression_]: #borrow-operators
681679
[_DereferenceExpression_]: #the-dereference-operator

0 commit comments

Comments
 (0)