Skip to content

Commit bf96c20

Browse files
author
Kyle Strand
committed
Merge branch 'master' of https://github.com/rust-lang/reference into c-unwind-documentation
2 parents c419c78 + 5c4a7a6 commit bf96c20

File tree

12 files changed

+212
-50
lines changed

12 files changed

+212
-50
lines changed

src/behavior-considered-undefined.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,18 @@ reading uninitialized memory is permitted are inside `union`s and in "padding"
7878
[dangling]: #dangling-pointers
7979

8080
A reference/pointer is "dangling" if it is null or not all of the bytes it
81-
points to are part of the same allocation (so in particular they all have to be
81+
points to are part of the same live allocation (so in particular they all have to be
8282
part of *some* allocation). The span of bytes it points to is determined by the
83-
pointer value and the size of the pointee type (using `size_of_val`). As a
84-
consequence, if the span is empty, "dangling" is the same as "non-null". Note
85-
that slices and strings point to their entire range, so it is important that the length
86-
metadata is never too large. In particular, allocations and therefore slices and strings
87-
cannot be bigger than `isize::MAX` bytes.
83+
pointer value and the size of the pointee type (using `size_of_val`).
84+
85+
If the size is 0, then the pointer must either point inside of a live allocation
86+
(including pointing just after the last byte of the allocation), or it must be
87+
directly constructed from a non-zero integer literal.
88+
89+
Note that dynamically sized types (such as slices and strings) point to their
90+
entire range, so it is important that the length metadata is never too large. In
91+
particular, the dynamic size of a Rust value (as determined by `size_of_val`)
92+
must never exceed `isize::MAX`.
8893

8994
[`bool`]: types/boolean.md
9095
[`const`]: items/constant-items.md

src/expressions.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ A *value expression* is an expression that represents an actual value.
157157
The following contexts are *place expression* contexts:
158158

159159
* The left operand of a [compound assignment] expression.
160-
* The operand of a unary [borrow] or [dereference][deref] operator.
160+
* The operand of a unary [borrow], [address-of][addr-of] or [dereference][deref] operator.
161161
* The operand of a field expression.
162162
* The indexed operand of an array indexing expression.
163163
* The operand of any [implicit borrow].
@@ -308,6 +308,7 @@ They are never allowed before:
308308

309309
[assign]: expressions/operator-expr.md#assignment-expressions
310310
[borrow]: expressions/operator-expr.md#borrow-operators
311+
[addr-of]: expressions/operator-expr.md#raw-address-of-operators
311312
[comparison]: expressions/operator-expr.md#comparison-operators
312313
[compound assignment]: expressions/operator-expr.md#compound-assignment-expressions
313314
[deref]: expressions/operator-expr.md#the-dereference-operator

src/expressions/operator-expr.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,50 @@ let a = && && mut 10;
7979
let a = & & & & mut 10;
8080
```
8181

82+
### Raw address-of operators
83+
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`.
87+
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+
91+
The following is an example of creating a raw pointer to an unaligned place through a `packed` struct:
92+
93+
```rust
94+
use std::ptr;
95+
96+
#[repr(packed)]
97+
struct Packed {
98+
f1: u8,
99+
f2: u16,
100+
}
101+
102+
let packed = Packed { f1: 1, f2: 2 };
103+
// `&packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
104+
let raw_f2 = ptr::addr_of!(packed.f2);
105+
assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
106+
```
107+
108+
The following is an example of creating a raw pointer to a place that does not contain a valid value:
109+
110+
```rust
111+
use std::{ptr, mem::MaybeUninit};
112+
113+
struct Demo {
114+
field: bool,
115+
}
116+
117+
let mut uninit = MaybeUninit::<Demo>::uninit();
118+
// `&uninit.as_mut().field` would create a reference to an uninitialized `bool`,
119+
// and thus be Undefined Behavior!
120+
let f1_ptr = unsafe { ptr::addr_of_mut!((*uninit.as_mut_ptr()).field) };
121+
unsafe { f1_ptr.write(true); }
122+
let init = unsafe { uninit.assume_init() };
123+
```
124+
125+
82126
## The dereference operator
83127

84128
> **<sup>Syntax</sup>**\
@@ -605,6 +649,9 @@ See [this test] for an example of using this dependency.
605649
[float-float]: https://github.com/rust-lang/rust/issues/15536
606650
[Function pointer]: ../types/function-pointer.md
607651
[Function item]: ../types/function-item.md
652+
[undefined behavior]: ../behavior-considered-undefined.md
653+
[addr_of]: ../../std/ptr/macro.addr_of.html
654+
[addr_of_mut]: ../../std/ptr/macro.addr_of_mut.html
608655

609656
[_BorrowExpression_]: #borrow-operators
610657
[_DereferenceExpression_]: #the-dereference-operator

src/items/external-blocks.md

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,29 @@ this to satisfy the linking requirements of extern blocks elsewhere in your
162162
code (including upstream crates) instead of adding the attribute to each extern
163163
block.
164164

165+
#### Linking modifiers: `bundle`
166+
167+
This modifier is only compatible with the `static` linking kind.
168+
Using any other kind will result in a compiler error.
169+
170+
When building a rlib or staticlib `+bundle` means that all object files from the native static
171+
library will be added to the rlib or staticlib archive, and then used from it during linking of
172+
the final binary.
173+
174+
When building a rlib `-bundle` means that the native static library is registered as a dependency
175+
of that rlib "by name", and object files from it are included only during linking of the final
176+
binary, the file search by that name is also performed during final linking. \
177+
When building a staticlib `-bundle` means that the native static library is simply not included
178+
into the archive and some higher level build system will need to add it later during linking of
179+
the final binary.
180+
181+
This modifier has no effect when building other targets like executables or dynamic libraries.
182+
183+
The default for this modifier is `+bundle`.
184+
185+
More implementation details about this modifier can be found in
186+
[`bundle` documentation for rustc].
187+
165188
#### Linking modifiers: `whole-archive`
166189

167190
This modifier is only compatible with the `static` linking kind.
@@ -170,7 +193,10 @@ Using any other kind will result in a compiler error.
170193
`+whole-archive` means that the static library is linked as a whole archive
171194
without throwing any object files away.
172195

173-
More implementation details about this modifier can be found in [documentation for rustc].
196+
The default for this modifier is `-whole-archive`.
197+
198+
More implementation details about this modifier can be found in
199+
[`whole-archive` documentation for rustc].
174200

175201
### The `link_name` attribute
176202

@@ -205,4 +231,5 @@ restrictions as [regular function parameters].
205231
[_Visibility_]: ../visibility-and-privacy.md
206232
[attributes]: ../attributes.md
207233
[regular function parameters]: functions.md#attributes-on-function-parameters
208-
[documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive
234+
[`bundle` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-bundle
235+
[`whole-archive` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive

src/items/unions.md

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ The key property of unions is that all fields of a union share common storage.
2020
As a result, writes to one field of a union can overwrite its other fields, and
2121
size of a union is determined by the size of its largest field.
2222

23+
Union field types are restricted to the following subset of types:
24+
- `Copy` types
25+
- References (`&T` and `&mut T` for arbitrary `T`)
26+
- `ManuallyDrop<T>` (for arbitrary `T`)
27+
- Tuples and arrays containing only allowed union field types
28+
29+
This restriction ensures, in particular, that union fields never need to be
30+
dropped. Like for structs and enums, it is possible to `impl Drop` for a union
31+
to manually define what happens when it gets dropped.
32+
2333
## Initialization of a union
2434

2535
A value of a union type can be created using the same syntax that is used for
@@ -67,32 +77,13 @@ unsafe {
6777
}
6878
```
6979

70-
Writes to [`Copy`] or [`ManuallyDrop`][ManuallyDrop] union fields do not
71-
require reads for running destructors, so these writes don't have to be placed
72-
in `unsafe` blocks
73-
74-
```rust
75-
# use std::mem::ManuallyDrop;
76-
union MyUnion { f1: u32, f2: ManuallyDrop<String> }
77-
let mut u = MyUnion { f1: 1 };
78-
79-
// These do not require `unsafe`.
80-
u.f1 = 2;
81-
u.f2 = ManuallyDrop::new(String::from("example"));
82-
```
83-
8480
Commonly, code using unions will provide safe wrappers around unsafe union
8581
field accesses.
8682

87-
## Unions and `Drop`
88-
89-
When a union is dropped, it cannot know which of its fields needs to be dropped.
90-
For this reason, all union fields must either be of a [`Copy`] type or of the
91-
shape [`ManuallyDrop<_>`][ManuallyDrop]. This ensures that a union does not
92-
need to drop anything when it goes out of scope.
93-
94-
Like for structs and enums, it is possible to `impl Drop` for a union to
95-
manually define what happens when it gets dropped.
83+
In contrast, writes to union fields are safe, since they just overwrite
84+
arbitrary data, but cannot cause undefined behavior. (Note that union field
85+
types can never have drop glue, so a union field write will never implicitly
86+
drop anything.)
9687

9788
## Pattern matching on unions
9889

src/macros-by-example.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,53 @@ compiler knows how to expand them properly:
193193
not have the same number. This requirement applies to every layer of nested
194194
repetitions.
195195

196+
## Dollar-dollar ($$)
197+
198+
`$$` expands to a single `$`.
199+
200+
Since metavariable expressions always apply during the expansion of a macro, they cannot be used in recursive macro definitions and this is where `$$` expressions comes into play, i.e., `$$` can be used to resolve ambiguities in nested macros.
201+
202+
The following example illustrates a macro that fails to compile due to the ambiguity of the repetition in a nested macro:
203+
204+
```rust,compile_fail
205+
macro_rules! foo_error {
206+
() => {
207+
macro_rules! bar_error {
208+
( $( $any:tt )* ) => { $( $any )* };
209+
// ^^^^^^^^^^^ error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth
210+
}
211+
};
212+
}
213+
214+
foo_error!();
215+
```
216+
217+
The following resolves the problem by escaping the `$` in the repetition with `$$`:
218+
219+
```rust
220+
macro_rules! foo_ok {
221+
() => {
222+
macro_rules! bar_ok {
223+
( $$( $any:tt )* ) => { $$( $any )* };
224+
}
225+
};
226+
}
227+
228+
foo_ok!();
229+
```
230+
231+
One consequence of such expansion is that deeper nested levels make dollar-dollar declarations grown linearly, starting at `$$`, then `$$$$`, then `$$$$$` and so on. This is also necessary to be fully featured so that it is possible to specify names of metavariables using other metavariables at each nesting level.
232+
233+
```ignore
234+
$foo => bar => bar // Evaluate foo at level 1
235+
$$foo => $foo => bar // Evaluate foo at level 2
236+
$$$foo => $bar => baz // Evaluate foo at level 1, and use that as a name at level 2
237+
$$$$foo => $$foo => $foo // Evaluate foo at level 3
238+
$$$$$foo => $$bar => $bar // Evaluate foo at level 1, and use that as a name at level 3
239+
$$$$$$foo => $$$foo => $bar // Evaluate foo at level 2, and use that as a name at level 3
240+
$$$$$$$foo => $$$bar => $baz // Evaluate foo at level 1, use that at level 2, and then use *that* at level 3
241+
```
242+
196243
## Scoping, Exporting, and Importing
197244

198245
For historical reasons, the scoping of macros by example does not work entirely

src/paths.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ arguments, then const arguments, then equality constraints.
8181
Const arguments must be surrounded by braces unless they are a
8282
[literal] or a single segment path.
8383

84+
The synthetic type parameters corresponding to `impl Trait` types are implicit,
85+
and these cannot be explicitly specified.
86+
8487
## Qualified paths
8588

8689
> **<sup>Syntax</sup>**\

src/runtime.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ the [subsystem] when linking on a Windows target. It uses the
6363
`console` or `windows`. This attribute is ignored on non-Windows targets, and
6464
for non-`bin` [crate types].
6565

66+
The "console" subsystem is the default. If a console process is run from an
67+
existing console then it will be attached to that console, otherwise a new
68+
console window will be created.
69+
70+
The "windows" subsystem is commonly used by GUI applications that do not want to
71+
display a console window on startup. It will run detached from any existing console.
72+
6673
```rust
6774
#![windows_subsystem = "windows"]
6875
```

src/subtyping.md

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,25 +61,51 @@ Variance of types is automatically determined as follows
6161
| `[T]` and `[T; n]` | | covariant |
6262
| `fn() -> T` | | covariant |
6363
| `fn(T) -> ()` | | contravariant |
64-
| `fn(T) -> T` | | invariant |
6564
| `std::cell::UnsafeCell<T>` | | invariant |
6665
| `std::marker::PhantomData<T>` | | covariant |
6766
| `dyn Trait<T> + 'a` | covariant | invariant |
6867

69-
The variance of other `struct`, `enum`, `union`, and tuple types is decided by
68+
The variance of other `struct`, `enum`, and `union` types is decided by
7069
looking at the variance of the types of their fields. If the parameter is used
7170
in positions with different variances then the parameter is invariant. For
72-
example the following struct is covariant in `'a` and `T` and invariant in `'b`
71+
example the following struct is covariant in `'a` and `T` and invariant in `'b`, `'c`,
7372
and `U`.
7473

7574
```rust
7675
use std::cell::UnsafeCell;
77-
struct Variance<'a, 'b, T, U: 'a> {
76+
struct Variance<'a, 'b, 'c, T, U: 'a> {
7877
x: &'a U, // This makes `Variance` covariant in 'a, and would
7978
// make it covariant in U, but U is used later
8079
y: *const T, // Covariant in T
8180
z: UnsafeCell<&'b f64>, // Invariant in 'b
8281
w: *mut U, // Invariant in U, makes the whole struct invariant
82+
83+
f: fn(&'c ()) -> &'c () // Both co- and contravariant, makes 'c invariant
84+
// in the struct.
85+
}
86+
```
87+
88+
When used outside of an `struct`, `enum`, or `union`, the variance for parameters is checked at each location separately.
89+
90+
```rust
91+
# use std::cell::UnsafeCell;
92+
fn generic_tuple<'short, 'long: 'short>(
93+
// 'long is used inside of a tuple in both a co- and invariant position.
94+
x: (&'long u32, UnsafeCell<&'long u32>),
95+
) {
96+
// As the variance at these positions is computed separately,
97+
// we can freely shrink 'long in the covariant position.
98+
let _: (&'short u32, UnsafeCell<&'long u32>) = x;
99+
}
100+
101+
fn takes_fn_ptr<'short, 'middle: 'short>(
102+
// 'middle is used in both a co- and contravariant position.
103+
f: fn(&'middle ()) -> &'middle (),
104+
) {
105+
// As the variance at these positions is computed separately,
106+
// we can freely shrink 'middle in the covariant position
107+
// and extend it in the contravariant position.
108+
let _: fn(&'static ()) -> &'short () = f;
83109
}
84110
```
85111

src/tokens.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,18 +148,28 @@ which must be _escaped_ by a preceding `U+005C` character (`\`).
148148
Line-breaks are allowed in string literals. A line-break is either a newline
149149
(`U+000A`) or a pair of carriage return and newline (`U+000D`, `U+000A`). Both
150150
byte sequences are normally translated to `U+000A`, but as a special exception,
151-
when an unescaped `U+005C` character (`\`) occurs immediately before the
152-
line-break, then the `U+005C` character, the line-break, and all whitespace at the
153-
beginning of the next line are ignored. Thus `a` and `b` are equal:
151+
when an unescaped `U+005C` character (`\`) occurs immediately before a line
152+
break, then the line break character(s), and all immediately following
153+
` ` (`U+0020`), `\t` (`U+0009`), `\n` (`U+000A`) and `\r` (`U+0000D`) characters
154+
are ignored. Thus `a`, `b` and `c` are equal:
154155

155156
```rust
156157
let a = "foobar";
157158
let b = "foo\
158159
bar";
160+
let c = "foo\
159161
160-
assert_eq!(a,b);
162+
bar";
163+
164+
assert_eq!(a, b);
165+
assert_eq!(b, c);
161166
```
162167

168+
> Note: Rust skipping additional newlines (like in example `c`) is potentially confusing and
169+
> unexpected. This behavior may be adjusted in the future. Until a decision is made, it is
170+
> recommended to avoid relying on this, i.e. skipping multiple newlines with line continuations.
171+
> See [this issue](https://github.com/rust-lang/reference/pull/1042) for more information.
172+
163173
#### Character escapes
164174

165175
Some additional _escapes_ are available in either character or non-raw string

0 commit comments

Comments
 (0)