Skip to content

Commit

Permalink
Merge branch 'master' into 'c-unwind-documentation'
Browse files Browse the repository at this point in the history
  • Loading branch information
BatmanAoD committed Aug 30, 2024
2 parents 36c74ea + df36291 commit 3ad52f3
Show file tree
Hide file tree
Showing 18 changed files with 95 additions and 52 deletions.
2 changes: 1 addition & 1 deletion docs/authoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,4 @@ The reference does not document which targets exist, or the properties of specif

### Editions

The main text and flow should document only the current edition. Whenever there is a difference between editions, the differences should be called out with an "Edition Differences" block.
The main text and flow should document only the current edition. Whenever there is a difference between editions, the differences should be called out with an "Edition differences" block.
8 changes: 5 additions & 3 deletions mdbook-spec/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![deny(rust_2018_idioms, unused_lifetimes)]

use mdbook::book::{Book, Chapter};
use mdbook::errors::Error;
use mdbook::preprocess::{CmdPreprocessor, Preprocessor, PreprocessorContext};
Expand Down Expand Up @@ -82,8 +84,8 @@ impl Spec {
}
}
format!(
"<div class=\"rule\" id=\"{rule_id}\">\
<a class=\"rule-link\" href=\"#{rule_id}\">[{rule_id}]</a>\
"<div class=\"rule\" id=\"r-{rule_id}\">\
<a class=\"rule-link\" href=\"#r-{rule_id}\">[{rule_id}]</a>\
</div>\n"
)
})
Expand All @@ -102,7 +104,7 @@ impl Spec {
.iter()
.map(|(rule_id, (_, path))| {
let relative = pathdiff::diff_paths(path, current_path).unwrap();
format!("[{rule_id}]: {}#{rule_id}\n", relative.display())
format!("[{rule_id}]: {}#r-{rule_id}\n", relative.display())
})
.collect();
format!(
Expand Down
4 changes: 2 additions & 2 deletions mdbook-spec/src/std_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ fn collect_markdown_links(chapter: &Chapter) -> Vec<Link<'_>> {
// Broken links are collected so that you can write something like
// `[std::option::Option]` which in pulldown_cmark's eyes is a broken
// link. However, that is the normal syntax for rustdoc.
let broken_link = |broken_link: BrokenLink| {
let broken_link = |broken_link: BrokenLink<'_>| {
broken_links.push(Link {
link_type: broken_link.link_type,
// Necessary due to lifetime issues.
Expand Down Expand Up @@ -205,7 +205,7 @@ fn collect_markdown_links(chapter: &Chapter) -> Vec<Link<'_>> {
/// generate intra-doc links on them.
///
/// The output will be in the given `tmp` directory.
fn run_rustdoc(tmp: &TempDir, chapter_links: &HashMap<&PathBuf, Vec<Link>>) {
fn run_rustdoc(tmp: &TempDir, chapter_links: &HashMap<&PathBuf, Vec<Link<'_>>>) {
let src_path = tmp.path().join("a.rs");
// Allow redundant since there could some in-scope things that are
// technically not necessary, but we don't care about (like
Expand Down
30 changes: 7 additions & 23 deletions src/const_eval.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,40 +61,24 @@ A _const context_ is one of the following:
* A [const generic argument]
* A [const block]

Const contexts that are used as parts of types (array type and repeat length
expressions as well as const generic arguments) can only make restricted use of
surrounding generic parameters: such an expression must either be a single bare
const generic parameter, or an arbitrary expression not making use of any
generics.

## Const Functions

A _const fn_ is a function that one is permitted to call from a const context. Declaring a function
`const` has no effect on any existing uses, it only restricts the types that arguments and the
return type may use, as well as prevent various expressions from being used within it. You can freely
do anything with a const function that you can do with a regular function.
return type may use, and restricts the function body to constant expressions.

When called from a const context, the function is interpreted by the
compiler at compile time. The interpretation happens in the
environment of the compilation target and not the host. So `usize` is
`32` bits if you are compiling against a `32` bit system, irrelevant
of whether you are building on a `64` bit or a `32` bit system.

Const functions have various restrictions to make sure that they can be
evaluated at compile-time. It is, for example, not possible to write a random
number generator as a const function. Calling a const function at compile-time
will always yield the same result as calling it at runtime, even when called
multiple times. There's one exception to this rule: if you are doing complex
floating point operations in extreme situations, then you might get (very
slightly) different results. It is advisable to not make array lengths and enum
discriminants depend on floating point computations.


Notable features that are allowed in const contexts but not in const functions include:

* floating point operations
* floating point values are treated just like generic parameters without trait bounds beyond
`Copy`. So you cannot do anything with them but copy/move them around.

Conversely, the following are possible in a const function, but not in a const context:

* Use of generic type and lifetime parameters.
* Const contexts do allow limited use of [const generic parameters].

[arithmetic]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators
[array expressions]: expressions/array-expr.md
[array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions
Expand Down
2 changes: 1 addition & 1 deletion src/expressions/method-call-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Once a method is looked up, if it can't be called for one (or more) of those rea
If a step is reached where there is more than one possible method, such as where generic methods or traits are considered the same, then it is a compiler error.
These cases require a [disambiguating function call syntax] for method and function invocation.
> **Edition Differences**: Before the 2021 edition, during the search for visible methods, if the candidate receiver type is an [array type], methods provided by the standard library [`IntoIterator`] trait are ignored.
> **Edition differences**: Before the 2021 edition, during the search for visible methods, if the candidate receiver type is an [array type], methods provided by the standard library [`IntoIterator`] trait are ignored.
>
> The edition used for this purpose is determined by the token representing the method name.
>
Expand Down
13 changes: 11 additions & 2 deletions src/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ These conventions are documented here.

An *example term* is an example of a term being defined.

* Differences in the language by which edition the crate is compiled under are in a blockquote that start with the words "Edition Differences:" in **bold**.
* Differences in the language by which edition the crate is compiled under are in a blockquote that start with the words "Edition differences:" in **bold**.

> **Edition Differences**: In the 2015 edition, this syntax is valid that is disallowed as of the 2018 edition.
> **Edition differences**: In the 2015 edition, this syntax is valid that is disallowed as of the 2018 edition.
* Notes that contain useful information about the state of the book or point out useful, but mostly out of scope, information are in blockquotes that start with the word "Note:" in **bold**.

Expand Down Expand Up @@ -120,6 +120,15 @@ These conventions are documented here.
See [Notation] for more detail.

* Rule identifiers appear before each language rule enclosed in square brackets. These identifiers provide a way to refer to a specific rule in the language. The rule identifier uses periods to separate sections from most general to most specific ([destructors.scope.nesting.function-body] for example).

The rule name can be clicked to link to that rule.

r[example.rule.label]

> [!WARNING]
> The organization of the rules is currently in flux. For the time being, these identifier names are not stable between releases, and links to these rules may fail if they are changed. We intend to stabilize these once the organization has settled so that links to the rule names will not break between releases.
## Contributing

We welcome contributions of all kinds.
Expand Down
2 changes: 1 addition & 1 deletion src/items/associated-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ let circle_shape = Circle::new();
let bounding_box = circle_shape.bounding_box();
```

> **Edition Differences**: In the 2015 edition, it is possible to declare trait
> **Edition differences**: In the 2015 edition, it is possible to declare trait
> methods with anonymous parameters (e.g. `fn foo(u8)`). This is deprecated and
> an error as of the 2018 edition. All parameters must have an argument name.
Expand Down
6 changes: 3 additions & 3 deletions src/macros-by-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ the `expr` fragment specifier. However, `_` is matched by the `expr` fragment
specifier when it appears as a subexpression.
For the same reason, a standalone [const block] is not matched but it is matched when appearing as a subexpression.

> **Edition Differences**: Starting with the 2021 edition, `pat` fragment-specifiers match top-level or-patterns (that is, they accept [_Pattern_]).
> **Edition differences**: Starting with the 2021 edition, `pat` fragment-specifiers match top-level or-patterns (that is, they accept [_Pattern_]).
>
> Before the 2021 edition, they match exactly the same fragments as `pat_param` (that is, they accept [_PatternNoTopAlt_]).
>
Expand Down Expand Up @@ -421,7 +421,7 @@ macro_rules! call_foo {
fn foo() {}
```

> **Version & Edition Differences**: Prior to Rust 1.30, `$crate` and
> **Version & Edition differences**: Prior to Rust 1.30, `$crate` and
> `local_inner_macros` (below) were unsupported. They were added alongside
> path-based imports of macros (described above), to ensure that helper macros
> did not need to be manually imported by users of a macro-exporting crate.
Expand Down Expand Up @@ -475,7 +475,7 @@ Matchers like `$i:expr,` or `$i:expr;` would be legal, however, because `,` and
`ident`, `ty`, or `path` fragment specifier.
* All other fragment specifiers have no restrictions.

> **Edition Differences**: Before the 2021 edition, `pat` may also be followed by `|`.
> **Edition differences**: Before the 2021 edition, `pat` may also be followed by `|`.
When repetitions are involved, then the rules apply to every possible number of
expansions, taking separators into account. This means:
Expand Down
4 changes: 2 additions & 2 deletions src/names/preludes.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ new_name`, then the symbol `new_name` is instead added to the prelude.
The [`core`] crate is always added to the extern prelude. The [`std`] crate is
added as long as the [`no_std` attribute] is not specified in the crate root.

> **Edition Differences**: In the 2015 edition, crates in the extern prelude
> **Edition differences**: In the 2015 edition, crates in the extern prelude
> cannot be referenced via [use declarations], so it is generally standard
> practice to include `extern crate` declarations to bring them into scope.
>
Expand Down Expand Up @@ -132,7 +132,7 @@ module or any of its descendants.
This attribute does not affect the [language prelude].
> **Edition Differences**: In the 2015 edition, the `no_implicit_prelude`
> **Edition differences**: In the 2015 edition, the `no_implicit_prelude`
> attribute does not affect the [`macro_use` prelude], and all macros exported
> from the standard library are still included in the `macro_use` prelude.
> Starting in the 2018 edition, it will remove the `macro_use` prelude.
Expand Down
2 changes: 1 addition & 1 deletion src/names/scopes.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ type FnExample = for<'a> fn(x: Example<'a>) -> Example<'a>;
#
// The `impl Trait2` here is not allowed to refer to 'b but it is allowed to
// refer to 'a.
fn foo<'a>() -> impl for<'b> Trait1<Item = impl Trait2<'a>> {
fn foo<'a>() -> impl for<'b> Trait1<Item = impl Trait2<'a> + use<'a>> {
// ...
# Example
}
Expand Down
2 changes: 1 addition & 1 deletion src/paths.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ Paths starting with `::` are considered to be *global paths* where the segments
start being resolved from a place which differs based on edition. Each identifier in
the path must resolve to an item.

> **Edition Differences**: In the 2015 Edition, identifiers resolve from the "crate root"
> **Edition differences**: In the 2015 Edition, identifiers resolve from the "crate root"
> (`crate::` in the 2018 edition), which contains a variety of different items, including
> external crates, default crates such as `std` or `core`, and items in the top level of
> the crate (including `use` imports).
Expand Down
2 changes: 1 addition & 1 deletion src/patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ For example, `0u8..=255u8` is irrefutable.
The range of values for an integer type is the closed range from its minimum to maximum value.
The range of values for a `char` type are precisely those ranges containing all Unicode Scalar Values: `'\u{0000}'..='\u{D7FF}'` and `'\u{E000}'..='\u{10FFFF}'`.

> **Edition Differences**: Before the 2021 edition, range patterns with both a lower and upper bound may also be written using `...` in place of `..=`, with the same meaning.
> **Edition differences**: Before the 2021 edition, range patterns with both a lower and upper bound may also be written using `...` in place of `..=`, with the same meaning.
## Reference patterns

Expand Down
6 changes: 3 additions & 3 deletions src/tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ c"\u{00E6}";
c"\xC3\xA6";
```

> **Edition Differences**: C string literals are accepted in the 2021 edition or
> **Edition differences**: C string literals are accepted in the 2021 edition or
> later. In earlier additions the token `c""` is lexed as `c ""`.
#### Raw C string literals
Expand All @@ -400,7 +400,7 @@ encoding. The characters `U+0022` (double-quote) (except when followed by at
least as many `U+0023` (`#`) characters as were used to start the raw C string
literal) or `U+005C` (`\`) do not have any special meaning.

> **Edition Differences**: Raw C string literals are accepted in the 2021
> **Edition differences**: Raw C string literals are accepted in the 2021
> edition or later. In earlier additions the token `cr""` is lexed as `cr ""`,
> and `cr#""#` is lexed as `cr #""#` (which is non-grammatical).
Expand Down Expand Up @@ -735,7 +735,7 @@ Note that raw identifiers, raw string literals, and raw byte string literals may

Similarly the `r`, `b`, `br`, `c`, and `cr` prefixes used in raw string literals, byte literals, byte string literals, raw byte string literals, C string literals, and raw C string literals are not interpreted as reserved prefixes.

> **Edition Differences**: Starting with the 2021 edition, reserved prefixes are reported as an error by the lexer (in particular, they cannot be passed to macros).
> **Edition differences**: Starting with the 2021 edition, reserved prefixes are reported as an error by the lexer (in particular, they cannot be passed to macros).
>
> Before the 2021 edition, reserved prefixes are accepted by the lexer and interpreted as multiple tokens (for example, one token for the identifier or keyword, followed by a `#` token).
>
Expand Down
23 changes: 22 additions & 1 deletion src/trait-bounds.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
> &nbsp;&nbsp; _TypeParamBound_ ( `+` _TypeParamBound_ )<sup>\*</sup> `+`<sup>?</sup>
>
> _TypeParamBound_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; _Lifetime_ | _TraitBound_
> &nbsp;&nbsp; &nbsp;&nbsp; _Lifetime_ | _TraitBound_ | _UseBound_
>
> _TraitBound_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; `?`<sup>?</sup>
Expand All @@ -19,6 +19,21 @@
> _Lifetime_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [LIFETIME_OR_LABEL]\
> &nbsp;&nbsp; | `'static`
>
> _UseBound_ :\
> &nbsp;&nbsp; `use` _UseBoundGenericArgs_
>
> _UseBoundGenericArgs_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; `<` `>` \
> &nbsp;&nbsp; | `<` \
> &nbsp;&nbsp; &nbsp;&nbsp; ( _UseBoundGenericArg_ `,`)<sup>\*</sup> \
> &nbsp;&nbsp; &nbsp;&nbsp; _UseBoundGenericArg_ `,`<sup>?</sup> \
> &nbsp;&nbsp; &nbsp;&nbsp; `>`
>
> _UseBoundGenericArg_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; _Lifetime_ \
> &nbsp;&nbsp; | [IDENTIFIER][] \
> &nbsp;&nbsp; | `Self`
[Trait] and lifetime bounds provide a way for [generic items][generic] to
restrict which types and lifetimes are used as their parameters. Bounds can be
Expand Down Expand Up @@ -227,20 +242,26 @@ trait Trait<'a, T: 'a> {}
impl<'a, T> Trait<'a, T> for &'a T {}
```

## Use bounds

Certain bounds lists may include a `use<..>` bound to control which generic parameters are captured by the `impl Trait` [abstract return type]. See [precise capturing] for more details.

[IDENTIFIER]: identifiers.html
[LIFETIME_OR_LABEL]: tokens.md#lifetimes-and-loop-labels
[_GenericParams_]: items/generics.md
[_TypePath_]: paths.md#paths-in-types
[`Clone`]: special-types-and-traits.md#clone
[`Copy`]: special-types-and-traits.md#copy
[`Sized`]: special-types-and-traits.md#sized

[abstract return type]: types/impl-trait.md#abstract-return-types
[arrays]: types/array.md
[associated types]: items/associated-items.md#associated-types
[hrtb-scopes]: names/scopes.md#higher-ranked-trait-bound-scopes
[supertraits]: items/traits.md#supertraits
[generic]: items/generics.md
[higher-ranked lifetimes]: #higher-ranked-trait-bounds
[precise capturing]: types/impl-trait.md#precise-capturing
[slice]: types/slice.md
[Trait]: items/traits.md#trait-bounds
[trait object]: types/trait-object.md
Expand Down
2 changes: 1 addition & 1 deletion src/types/enum.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Enum types cannot be denoted *structurally* as types, but must be denoted by
named reference to an [`enum` item].

[^enumtype]: The `enum` type is analogous to a `data` constructor declaration in
ML, or a *pick ADT* in Limbo.
Haskell, or a *pick ADT* in Limbo.

[`enum` item]: ../items/enumerations.md
[struct expression]: ../expressions/struct-expr.md
33 changes: 30 additions & 3 deletions src/types/impl-trait.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,33 @@ Functions in traits may also use `impl Trait` as a syntax for an anonymous assoc

Every `impl Trait` in the return type of an associated function in a trait is desugared to an anonymous associated type. The return type that appears in the implementation's function signature is used to determine the value of the associated type.

### Differences between generics and `impl Trait` in return position
## Capturing

Behind each return-position `impl Trait` abstract type is some hidden concrete type. For this concrete type to use a generic parameter, that generic parameter must be *captured* by the abstract type.

## Automatic capturing

Return-position `impl Trait` abstract types automatically capture certain of the in-scope generic parameters. Everywhere, these automatically capture all in-scope type and const generic parameters.

On items of trait impls and trait definitions, these types additionally automatically capture all in-scope generic lifetime parameters, including higher-ranked ones. On free functions and on associated functions and methods of inherent impls, only the generic lifetime parameters that appear in the bounds of abstract return type are captured.

## Precise capturing

The set of generic parameters captured by a return-position `impl Trait` abstract type may be explicitly controlled with a [`use<..>` bound]. If present, only the generic parameters listed in the `use<..>` bound will be captured. E.g.:

```rust
fn capture<'a, 'b, T>(x: &'a (), y: T) -> impl Sized + use<'a, T> {
// ~~~~~~~~~~~~~~~~~~~~~~~
// Captures `'a` and `T` only.
(x, y)
}
```

Currently, only one `use<..>` bound may be present in a bounds list, such bounds are not allowed in the signature of items of a trait definition, all in-scope type and const generic parameters must be included, and all lifetime parameters that appear in other bounds of the abstract type must be included. Within the `use<..>` bound, any lifetime parameters present must appear before all type and const generic parameters, and the elided lifetime (`'_`) may be present if it is otherwise allowed to appear within the `impl Trait` return type.

Because all in-scope type parameters must be included by name, a `use<..>` bound may not be used in the signature of items that use argument-position `impl Trait`, as those items have anonymous type parameters in scope.

## Differences between generics and `impl Trait` in return position

In argument position, `impl Trait` is very similar in semantics to a generic type parameter.
However, there are significant differences between the two in return position.
Expand Down Expand Up @@ -127,9 +153,10 @@ Instead, the function chooses the return type, but only promises that it will im
`impl Trait` can only appear as a parameter or return type of a non-`extern` function.
It cannot be the type of a `let` binding, field type, or appear inside a type alias.

[closures]: closure.md
[_GenericArgs_]: ../paths.md#paths-in-expressions
[_GenericParams_]: ../items/generics.md
[_TraitBound_]: ../trait-bounds.md
[trait object]: trait-object.md
[_TypeParamBounds_]: ../trait-bounds.md
[`use<..>` bound]: ../trait-bounds.md#use-bounds
[closures]: closure.md
[trait object]: trait-object.md
Loading

0 comments on commit 3ad52f3

Please sign in to comment.