From 276954590a30efa972227207aba771157fc862fe Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 20 Aug 2025 16:16:02 +0200 Subject: [PATCH 01/33] specify s390x target features --- src/attributes/codegen.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index 24e4c2c3..bb446130 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -506,6 +506,30 @@ Feature | Implicitly Enables | Description [tail-call]: https://github.com/webassembly/tail-call [multivalue]: https://github.com/webassembly/multi-value +r[attributes.codegen.target_feature.s390x] +#### `s390x` + +On this platform the usage of `#[target_feature]` functions follows the [above restrictions][attributes.codegen.target_feature.safety-restrictions]. + +Further documentation on these features can be found in the "Additions to z/Architecture" section of Chapter 1 of the [Principles of Operation]. + +Feature | Implicitly Enables | Description +---------------------------------------|---------------------------------------|--------------------- +`vector` | | 128-bit vector instructions +`vector-enhancements-1` | `vector` | vector enhancements 1 +`vector-enhancements-2` | `vector-enhancements-1` | vector enhancements 2 +`vector-enhancements-3` | `vector-enhancements-2` | vector enhancements 3 +`vector-packed-decimal` | `vector` | vector packed-decimal +`vector-packed-decimal-enhancement` | `vector-packed-decimal` | vector packed-decimal enhancement +`vector-packed-decimal-enhancement-2` | `vector-packed-decimal-enhancement-2` | vector packed-decimal enhancement 2 +`vector-packed-decimal-enhancement-3` | `vector-packed-decimal-enhancement-3` | vector packed-decimal enhancement 3 +`nnp-assist` | `vector` | nnp assist +`miscellaneous-extensions-2` | | miscellaneous extensions 2 +`miscellaneous-extensions-3` | | miscellaneous extensions 3 +`miscellaneous-extensions-4` | | miscellaneous extensions 4 + +[Principles of Operation]: https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf + r[attributes.codegen.target_feature.info] ### Additional information @@ -516,8 +540,7 @@ that this option is not affected by the `target_feature` attribute, and is only driven by the features enabled for the entire crate. r[attributes.codegen.target_feature.remark-rt] -See the [`is_x86_feature_detected`] or [`is_aarch64_feature_detected`] macros -in the standard library for runtime feature detection on these platforms. +Whether a feature is enabled can be checked at runtime using a platform-specific macro from the standard library, for instance [`is_x86_feature_detected`] or [`is_aarch64_feature_detected`]. > [!NOTE] > `rustc` has a default set of features enabled for each target and CPU. The CPU may be chosen with the [`-C target-cpu`] flag. Individual features may be enabled or disabled for an entire crate with the [`-C target-feature`] flag. From 4ec04bcd06e9fe235653d0767dcb94130b345eda Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 20 Aug 2025 18:21:11 +0000 Subject: [PATCH 02/33] Revise `s390x` codegen text --- src/attributes/codegen.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index bb446130..e8afe711 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -509,9 +509,9 @@ Feature | Implicitly Enables | Description r[attributes.codegen.target_feature.s390x] #### `s390x` -On this platform the usage of `#[target_feature]` functions follows the [above restrictions][attributes.codegen.target_feature.safety-restrictions]. +On `s390x` targets, use of functions with the `#[target_feature]` attribute follows the [above restrictions][attributes.codegen.target_feature.safety-restrictions]. -Further documentation on these features can be found in the "Additions to z/Architecture" section of Chapter 1 of the [Principles of Operation]. +Further documentation on these features can be found in the "Additions to z/Architecture" section of Chapter 1 of the *[z/Architecture Principles of Operation]*. Feature | Implicitly Enables | Description ---------------------------------------|---------------------------------------|--------------------- @@ -528,7 +528,7 @@ Feature | Implicitly Enables | `miscellaneous-extensions-3` | | miscellaneous extensions 3 `miscellaneous-extensions-4` | | miscellaneous extensions 4 -[Principles of Operation]: https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf +[z/Architecture Principles of Operation]: https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf r[attributes.codegen.target_feature.info] ### Additional information From ea013b5badf78ea16bf23edf58483c30fe1da1ce Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Sat, 25 Oct 2025 10:49:46 +0200 Subject: [PATCH 03/33] feat: guarantee the binary representation of `isize` explicitly --- src/types/numeric.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/numeric.md b/src/types/numeric.md index 73c61991..5b796e41 100644 --- a/src/types/numeric.md +++ b/src/types/numeric.md @@ -44,7 +44,7 @@ platform's pointer type. It can represent every memory address in the process. > For more information, see the documentation for [type cast expressions], [`std::ptr`], and [provenance][std::ptr#provenance] in particular. r[type.numeric.int.size.isize] -The `isize` type is a signed integer type with the same number of bits as the +The `isize` type is a signed two's complement integer type with the same number of bits as the platform's pointer type. The theoretical upper bound on object and array size is the maximum `isize` value. This ensures that `isize` can be used to calculate differences between pointers into an object or array and can address every byte From 07be87efda16ceeeae3c3bc8e1da767af5dfc780 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 10 Nov 2025 10:24:09 +0200 Subject: [PATCH 04/33] const_eval.md: be more clear where link leads to Having just "Struct" as the link makes it look like the target is about structs and not just struct expressions --- src/const_eval.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/const_eval.md b/src/const_eval.md index 7cb85dc2..04146adf 100644 --- a/src/const_eval.md +++ b/src/const_eval.md @@ -55,7 +55,7 @@ r[const-eval.const-expr.array] * [Array expressions]. r[const-eval.const-expr.constructor] -* [Struct] expressions. +* [Struct expressions]. r[const-eval.const-expr.block] * [Block expressions], including `unsafe` and `const` blocks. @@ -332,7 +332,7 @@ The types of a const function's parameters and return type are restricted to tho [range expressions]: expressions/range-expr.md [slice]: types/slice.md [statics]: items/static-items.md -[struct]: expressions/struct-expr.md +[Struct expressions]: expressions/struct-expr.md [temporary lifetime extension]: destructors.scope.lifetime-extension [tuple enum variant]: items/enumerations.md [tuple expressions]: expressions/tuple-expr.md From 7e7ae6cb0ab1d53818b34b91dafc9851f6f2fca0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 13:58:15 -0700 Subject: [PATCH 05/33] Unwrap the no_std attribute --- src/names/preludes.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 97c1ba77..c94b5bc2 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -80,15 +80,10 @@ r[names.preludes.extern.no_std] ### The `no_std` attribute r[names.preludes.extern.no_std.intro] -By default, the standard library is automatically included in the crate root -module. The [`std`] crate is added to the root, along with an implicit -[`macro_use` attribute] pulling in all macros exported from `std` into the -[`macro_use` prelude]. Both [`core`] and [`std`] are added to the [extern -prelude]. +By default, the standard library is automatically included in the crate root module. The [`std`] crate is added to the root, along with an implicit [`macro_use` attribute] pulling in all macros exported from `std` into the [`macro_use` prelude]. Both [`core`] and [`std`] are added to the [extern prelude]. r[names.preludes.extern.no_std.allowed-positions] -The *`no_std` [attribute]* may be applied at the crate level to prevent the -[`std`] crate from being automatically added into scope. +The *`no_std` [attribute]* may be applied at the crate level to prevent the [`std`] crate from being automatically added into scope. It does three things: @@ -97,8 +92,7 @@ r[names.preludes.extern.no_std.extern] r[names.preludes.extern.no_std.module] * Affects which module is used to make up the [standard library prelude] (as described above). r[names.preludes.extern.no_std.core] -* Injects the [`core`] crate into the crate root instead of [`std`], and pulls - in all macros exported from `core` in the [`macro_use` prelude]. +* Injects the [`core`] crate into the crate root instead of [`std`], and pulls in all macros exported from `core` in the [`macro_use` prelude]. > [!NOTE] > Using the core prelude over the standard prelude is useful when either the crate is targeting a platform that does not support the standard library or is purposefully not using the capabilities of the standard library. Those capabilities are mainly dynamic memory allocation (e.g. `Box` and `Vec`) and file and network capabilities (e.g. `std::fs` and `std::io`). From a5a160db984dc35c63110a74a1917b33d5536927 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 14:01:40 -0700 Subject: [PATCH 06/33] Add names.preludes.extern.no_std.syntax --- src/names/preludes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/names/preludes.md b/src/names/preludes.md index c94b5bc2..0d44cdf4 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -82,6 +82,9 @@ r[names.preludes.extern.no_std] r[names.preludes.extern.no_std.intro] By default, the standard library is automatically included in the crate root module. The [`std`] crate is added to the root, along with an implicit [`macro_use` attribute] pulling in all macros exported from `std` into the [`macro_use` prelude]. Both [`core`] and [`std`] are added to the [extern prelude]. +r[names.preludes.extern.no_std.syntax] +The `no_std` attribute uses the [MetaWord] syntax and thus does not take any inputs. + r[names.preludes.extern.no_std.allowed-positions] The *`no_std` [attribute]* may be applied at the crate level to prevent the [`std`] crate from being automatically added into scope. From acb4347d8e95f015949106d534051b0a65400128 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:31:05 -0700 Subject: [PATCH 07/33] Remove duplicate link definition --- src/names/preludes.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 0d44cdf4..daa6b30e 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -157,7 +157,6 @@ r[names.preludes.no_implicit_prelude.edition2018] [`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute [`macro_use` prelude]: #macro_use-prelude [`no_std` attribute]: #the-no_std-attribute -[`no_std` attribute]: #the-no_std-attribute [attribute]: ../attributes.md [Boolean type]: ../types/boolean.md [Built-in attributes]: ../attributes.md#built-in-attributes-index From dea61cb30e0819012faf51736509582c7a6aceb9 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:32:19 -0700 Subject: [PATCH 08/33] Add example to no_std intro --- src/names/preludes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/names/preludes.md b/src/names/preludes.md index daa6b30e..87faf24c 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -82,6 +82,12 @@ r[names.preludes.extern.no_std] r[names.preludes.extern.no_std.intro] By default, the standard library is automatically included in the crate root module. The [`std`] crate is added to the root, along with an implicit [`macro_use` attribute] pulling in all macros exported from `std` into the [`macro_use` prelude]. Both [`core`] and [`std`] are added to the [extern prelude]. +> [!EXAMPLE] +> +> ```rust,ignore +> #![no_std] +> ``` + r[names.preludes.extern.no_std.syntax] The `no_std` attribute uses the [MetaWord] syntax and thus does not take any inputs. From 4f50d5234e22c4cca071f246608916dc964be528 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:33:00 -0700 Subject: [PATCH 09/33] Move note and warning to the intro These don't really belong where they are, and are just generally helpful things about the attribute. --- src/names/preludes.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 87faf24c..17549f83 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -88,6 +88,12 @@ By default, the standard library is automatically included in the crate root mod > #![no_std] > ``` +> [!NOTE] +> Using `no_std` is useful when either the crate is targeting a platform that does not support the standard library or is purposefully not using the capabilities of the standard library. Those capabilities are mainly dynamic memory allocation (e.g. `Box` and `Vec`) and file and network capabilities (e.g. `std::fs` and `std::io`). + +> [!WARNING] +> Using `no_std` does not prevent the standard library from being linked in. It is still valid to put `extern crate std;` into the crate and dependencies can also link it in. + r[names.preludes.extern.no_std.syntax] The `no_std` attribute uses the [MetaWord] syntax and thus does not take any inputs. @@ -103,11 +109,7 @@ r[names.preludes.extern.no_std.module] r[names.preludes.extern.no_std.core] * Injects the [`core`] crate into the crate root instead of [`std`], and pulls in all macros exported from `core` in the [`macro_use` prelude]. -> [!NOTE] -> Using the core prelude over the standard prelude is useful when either the crate is targeting a platform that does not support the standard library or is purposefully not using the capabilities of the standard library. Those capabilities are mainly dynamic memory allocation (e.g. `Box` and `Vec`) and file and network capabilities (e.g. `std::fs` and `std::io`). -> [!WARNING] -> Using `no_std` does not prevent the standard library from being linked in. It is still valid to put `extern crate std;` into the crate and dependencies can also link it in. r[names.preludes.lang] ## Language prelude From e464933c11bfe9ea02b09ae07791bb52242f774b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:37:55 -0700 Subject: [PATCH 10/33] Rewrite no_std The current text was a little bit of a mess and had some subtle inaccuracies. This reworks so that the intro follows the template, and just generally introduces the attribute. `allowed-positions` now just specifies the allowed positions. I reworked the behavior changes caused by no_std into proper separate rules. `std` is not injected into the crate root anymore starting with edition 2018. --- src/names/preludes.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 17549f83..3c38f7b3 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -80,7 +80,7 @@ r[names.preludes.extern.no_std] ### The `no_std` attribute r[names.preludes.extern.no_std.intro] -By default, the standard library is automatically included in the crate root module. The [`std`] crate is added to the root, along with an implicit [`macro_use` attribute] pulling in all macros exported from `std` into the [`macro_use` prelude]. Both [`core`] and [`std`] are added to the [extern prelude]. +The *`no_std` [attribute][attributes]* is used to prevent the automatic linking of the [`std`] crate, deferring to [`core`] instead. > [!EXAMPLE] > @@ -98,18 +98,16 @@ r[names.preludes.extern.no_std.syntax] The `no_std` attribute uses the [MetaWord] syntax and thus does not take any inputs. r[names.preludes.extern.no_std.allowed-positions] -The *`no_std` [attribute]* may be applied at the crate level to prevent the [`std`] crate from being automatically added into scope. +The `no_std` attribute may only be applied to the crate root. -It does three things: -r[names.preludes.extern.no_std.extern] -* Prevents `std` from being added to the [extern prelude](#extern-prelude). r[names.preludes.extern.no_std.module] -* Affects which module is used to make up the [standard library prelude] (as described above). -r[names.preludes.extern.no_std.core] -* Injects the [`core`] crate into the crate root instead of [`std`], and pulls in all macros exported from `core` in the [`macro_use` prelude]. +The `no_std` attribute changes the [standard library prelude] to use the `core` prelude instead of `std`. +r[names.preludes.extern.no_std.inject] +By default, the [`std`] crate is injected into the [extern prelude], and all macros exported from `std` are added to the [`macro_use` prelude]. +If the `no_std` attribute is specified, then the [`core`] crate is used instead of `std`, and similarly all macros exported from `core` are placed into the [`macro_use` prelude]. r[names.preludes.lang] ## Language prelude From d6e0a9fc9e4db338cfc496c1a8089f11fc3909e8 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:41:28 -0700 Subject: [PATCH 11/33] Add a rule for `std` injection in edition 2018 I do not know how this was missing, I've looked at it a million times. I feel like I was maybe missing something, but I really can't find anything that directly refers to this, nor can I find any open issues. I believe this is now done with this relatively subtle bit: https://github.com/rust-lang/rust/blob/4d08223c054cf5a56d9761ca925fd46ffebe7115/compiler/rustc_builtin_macros/src/standard_library_imports.rs#L42 In the past it used to use a different approach of emulating `extern crate std as _;`: https://github.com/rust-lang/rust/blob/c8cf9f5a025bb475804b5a90f54aca310b952526/src/libsyntax_ext/standard_library_imports.rs#L42-L46 --- src/names/preludes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/names/preludes.md b/src/names/preludes.md index 3c38f7b3..628e5fb2 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -109,6 +109,10 @@ By default, the [`std`] crate is injected into the [extern prelude], and all mac If the `no_std` attribute is specified, then the [`core`] crate is used instead of `std`, and similarly all macros exported from `core` are placed into the [`macro_use` prelude]. +r[names.preludes.extern.no_std.edition2018] +> [!EDITION-2018] +> Before the 2018 edition, `std` is also injected into the crate root. `core` is injected instead of `std` if `no_std` is specified. Starting with the 2018 edition, these are not injected into the crate root. + r[names.preludes.lang] ## Language prelude From f7d9d8442c8be8c82501ba30e78d4c3a640f62dd Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:41:36 -0700 Subject: [PATCH 12/33] Add names.preludes.extern.no_std.duplicates --- src/names/preludes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/names/preludes.md b/src/names/preludes.md index 628e5fb2..188a67e3 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -100,6 +100,11 @@ The `no_std` attribute uses the [MetaWord] syntax and thus does not take any inp r[names.preludes.extern.no_std.allowed-positions] The `no_std` attribute may only be applied to the crate root. +r[names.preludes.extern.no_std.duplicates] +Duplicate instances of the `no_std` attribute have no effect. + +> [!NOTE] +> `rustc` currently warns on subsequent duplicate `no_std` attributes. r[names.preludes.extern.no_std.module] The `no_std` attribute changes the [standard library prelude] to use the `core` prelude instead of `std`. From 97ea13093dca26dc9af49dbfb7830b3d2c2800af Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 22 Sep 2025 13:22:46 -0700 Subject: [PATCH 13/33] Minor update of `no_std` More closely align with the template, and some minor word tweaks. --- src/names/preludes.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 188a67e3..d8204f27 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -76,6 +76,7 @@ See https://github.com/rust-lang/rust/issues/57288 for more about the alloc/test limitation. --> + r[names.preludes.extern.no_std] ### The `no_std` attribute @@ -95,16 +96,16 @@ The *`no_std` [attribute][attributes]* is used to prevent the automatic linking > Using `no_std` does not prevent the standard library from being linked in. It is still valid to put `extern crate std;` into the crate and dependencies can also link it in. r[names.preludes.extern.no_std.syntax] -The `no_std` attribute uses the [MetaWord] syntax and thus does not take any inputs. +The `no_std` attribute uses the [MetaWord] syntax. r[names.preludes.extern.no_std.allowed-positions] The `no_std` attribute may only be applied to the crate root. r[names.preludes.extern.no_std.duplicates] -Duplicate instances of the `no_std` attribute have no effect. +The `no_std` attribute may be used any number of times on a form. > [!NOTE] -> `rustc` currently warns on subsequent duplicate `no_std` attributes. +> `rustc` lints against any use following the first. r[names.preludes.extern.no_std.module] The `no_std` attribute changes the [standard library prelude] to use the `core` prelude instead of `std`. From 9d79e59adaf149a333709bf075ff71a08bb9f8ea Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 9 Nov 2025 01:56:38 +0000 Subject: [PATCH 14/33] Align `no_std` intro language better and reword We had said here that the `no_std` attribute is used to "prevent the automatic linking of the std crate", but then further down we say, "using `no_std` does not prevent the standard library from being linked in". The important distinction here is the word "automatically", but that gets a bit lost due to reusing the "prevent" phrasing. Probably "prevent" is just too strong a word to use when what we're really saying is that we're causing something to not happen automatically. Let's make that more clear and increase sentence parallelism. --- src/names/preludes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index d8204f27..a8efb837 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -81,7 +81,7 @@ r[names.preludes.extern.no_std] ### The `no_std` attribute r[names.preludes.extern.no_std.intro] -The *`no_std` [attribute][attributes]* is used to prevent the automatic linking of the [`std`] crate, deferring to [`core`] instead. +The *`no_std` [attribute][attributes]* causes the [`std`] crate to not be linked automatically, deferring to the [`core`] crate instead. > [!EXAMPLE] > From ae893d6e01e2f581c0999b3adebeffbcf423da91 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 11 Nov 2025 21:28:35 +0000 Subject: [PATCH 15/33] Revise `no_std` text to increase parallelism Some sentences here could be improved with more sentence parallelism and a bit of reordering, so let's do that. --- src/names/preludes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index a8efb837..000afa1e 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -108,16 +108,16 @@ The `no_std` attribute may be used any number of times on a form. > `rustc` lints against any use following the first. r[names.preludes.extern.no_std.module] -The `no_std` attribute changes the [standard library prelude] to use the `core` prelude instead of `std`. +The `no_std` attribute changes the [standard library prelude] to use the `core` prelude instead of the `std` prelude. r[names.preludes.extern.no_std.inject] By default, the [`std`] crate is injected into the [extern prelude], and all macros exported from `std` are added to the [`macro_use` prelude]. -If the `no_std` attribute is specified, then the [`core`] crate is used instead of `std`, and similarly all macros exported from `core` are placed into the [`macro_use` prelude]. +If the `no_std` attribute is specified, then the [`core`] crate is used instead of the `std` crate, and similarly all macros exported from `core` are placed into the [`macro_use` prelude]. r[names.preludes.extern.no_std.edition2018] > [!EDITION-2018] -> Before the 2018 edition, `std` is also injected into the crate root. `core` is injected instead of `std` if `no_std` is specified. Starting with the 2018 edition, these are not injected into the crate root. +> Before the 2018 edition, `std` is injected into the crate root by default. If `no_std` is specified, `core` is injected instead. Starting with the 2018 edition, regardless of `no_std` being specified, neither is injected into the crate root. r[names.preludes.lang] ## Language prelude From 8d7877ec0d388c065d2a8b3b109191300a116c02 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 11 Nov 2025 21:51:02 +0000 Subject: [PATCH 16/33] Revise `no_std` intro WRT the preludes We had text in the intro about "deferring to the core crate instead", but it may not have been sufficiently clear what we mean exactly by that. Let's talk specifically about how `no_std` causes us to use the `core` crate for the standard library prelude and for the `macro_use` prelude. --- src/names/preludes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 000afa1e..321a8a08 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -81,7 +81,7 @@ r[names.preludes.extern.no_std] ### The `no_std` attribute r[names.preludes.extern.no_std.intro] -The *`no_std` [attribute][attributes]* causes the [`std`] crate to not be linked automatically, deferring to the [`core`] crate instead. +The *`no_std` [attribute][attributes]* causes the [`std`] crate to not be linked automatically, the [standard library prelude] to instead use the `core` prelude, and the [`macro_use` prelude] to instead use the macros exported from the `core` crate. > [!EXAMPLE] > @@ -183,7 +183,7 @@ r[names.preludes.no_implicit_prelude.edition2018] [Machine-dependent integer types]: ../types/numeric.md#machine-dependent-integer-types [Macro namespace]: namespaces.md [name resolution]: name-resolution.md -[Standard library prelude]: #standard-library-prelude +[standard library prelude]: names.preludes.std [Textual types]: ../types/textual.md [tool attributes]: ../attributes.md#tool-attributes [Tool prelude]: #tool-prelude From b15b601de6441282e61c314251dff28dd5b3de4f Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 11 Nov 2025 22:19:16 +0000 Subject: [PATCH 17/33] Revise `no_std` warning We want to highlight how using `no_std` doesn't prevent `std` from being linked. Let's revise and elaborate this text for clarity. --- src/names/preludes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 321a8a08..bca08f75 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -93,7 +93,7 @@ The *`no_std` [attribute][attributes]* causes the [`std`] crate to not be linked > Using `no_std` is useful when either the crate is targeting a platform that does not support the standard library or is purposefully not using the capabilities of the standard library. Those capabilities are mainly dynamic memory allocation (e.g. `Box` and `Vec`) and file and network capabilities (e.g. `std::fs` and `std::io`). > [!WARNING] -> Using `no_std` does not prevent the standard library from being linked in. It is still valid to put `extern crate std;` into the crate and dependencies can also link it in. +> Using `no_std` does not prevent the standard library from being linked. It is still valid to write `extern crate std` in the crate or in one of its dependencies; this will cause the compiler to link the `std` crate into the program. r[names.preludes.extern.no_std.syntax] The `no_std` attribute uses the [MetaWord] syntax. From 97f3e33bb42c00b974ca2bc1272389e05f29be32 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 11 Nov 2025 22:25:25 +0000 Subject: [PATCH 18/33] Revise `no_std` text WRT `macro_use` The text here could be read in such a way as to imply that `no_std` affected whether or not `core` was added to the extern prelude, but that isn't the case. Let's make it clear that this section is about what is added to the `macro_use` prelude and speak to that directly. --- src/names/preludes.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index bca08f75..63d08af1 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -110,10 +110,8 @@ The `no_std` attribute may be used any number of times on a form. r[names.preludes.extern.no_std.module] The `no_std` attribute changes the [standard library prelude] to use the `core` prelude instead of the `std` prelude. -r[names.preludes.extern.no_std.inject] -By default, the [`std`] crate is injected into the [extern prelude], and all macros exported from `std` are added to the [`macro_use` prelude]. - -If the `no_std` attribute is specified, then the [`core`] crate is used instead of the `std` crate, and similarly all macros exported from `core` are placed into the [`macro_use` prelude]. +r[names.preludes.extern.no_std.macro_use] +By default, all macros exported from the `std` crate are added to the [`macro_use` prelude]. If the `no_std` attribute is specified, then all macros exported from the `core` crate are placed into the [`macro_use` prelude] instead. r[names.preludes.extern.no_std.edition2018] > [!EDITION-2018] From 2f10103ec00a15b3b4a1ff83bb108ce3b45e8078 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:43:05 -0700 Subject: [PATCH 19/33] Unwrap no_implicit_prelude --- src/names/preludes.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 63d08af1..0d6ce56e 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -155,10 +155,7 @@ r[names.preludes.no_implicit_prelude] ## The `no_implicit_prelude` attribute r[names.preludes.no_implicit_prelude.intro] -The *`no_implicit_prelude` [attribute]* may be applied at the crate level or -on a module to indicate that it should not automatically bring the [standard -library prelude], [extern prelude], or [tool prelude] into scope for that -module or any of its descendants. +The *`no_implicit_prelude` [attribute]* may be applied at the crate level or on a module to indicate that it should not automatically bring the [standard library prelude], [extern prelude], or [tool prelude] into scope for that module or any of its descendants. r[names.preludes.no_implicit_prelude.lang] This attribute does not affect the [language prelude]. From 0fe507dddf07517a812bcab77029a6cc8f930641 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:54:34 -0700 Subject: [PATCH 20/33] Add an example for no_implicit_prelude --- src/names/preludes.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/names/preludes.md b/src/names/preludes.md index 0d6ce56e..364724fd 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -157,6 +157,18 @@ r[names.preludes.no_implicit_prelude] r[names.preludes.no_implicit_prelude.intro] The *`no_implicit_prelude` [attribute]* may be applied at the crate level or on a module to indicate that it should not automatically bring the [standard library prelude], [extern prelude], or [tool prelude] into scope for that module or any of its descendants. +> [!EXAMPLE] +> ```rust +> // It can be applied to the crate root to apply to all modules. +> #![no_implicit_prelude] +> +> // Or it can be applied to a module to only affect that module or any of its descendants. +> #[no_implicit_prelude] +> mod example { +> // ... +> } +> ``` + r[names.preludes.no_implicit_prelude.lang] This attribute does not affect the [language prelude]. From b5e3e2680af1432f166a8a472d070bd03e4c2bf1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:55:11 -0700 Subject: [PATCH 21/33] Add explicit rules for no_implicit_prelude This is to follow the attribute template. --- src/names/preludes.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/names/preludes.md b/src/names/preludes.md index 364724fd..db5eedc8 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -169,6 +169,21 @@ The *`no_implicit_prelude` [attribute]* may be applied at the crate level or on > } > ``` +r[names.preludes.no_implicit_prelude.syntax] +The `no_implicit_prelude` attribute uses the [MetaWord] syntax and thus does not take any inputs. + +r[names.preludes.no_implicit_prelude.allowed-positions] +The `no_implicit_prelude` attribute may only be applied to the crate level or a module. + +> [!NOTE] +> `rustc` currently warns in other positions, but this may be rejected in the future. + +r[names.preludes.no_implicit_prelude.duplicates] +Duplicate instances of the `no_implicit_prelude` attribute have no effect. + +> [!NOTE] +> `rustc` currently warns on subsequent duplicate `no_implicit_prelude` attributes. + r[names.preludes.no_implicit_prelude.lang] This attribute does not affect the [language prelude]. From a2b8f937e4f83a62316efb2815f0be95c91326f5 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:56:23 -0700 Subject: [PATCH 22/33] Rewrite no_implicit_prelude to move to a specific rule This rewrites the intro to be a little more general, and moves the description of the behavior to a specific rule that can be cited. --- src/names/preludes.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index db5eedc8..4f2ae167 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -155,7 +155,7 @@ r[names.preludes.no_implicit_prelude] ## The `no_implicit_prelude` attribute r[names.preludes.no_implicit_prelude.intro] -The *`no_implicit_prelude` [attribute]* may be applied at the crate level or on a module to indicate that it should not automatically bring the [standard library prelude], [extern prelude], or [tool prelude] into scope for that module or any of its descendants. +The *`no_implicit_prelude` [attribute]* is used to prevent implicit preludes from being brought into scope. > [!EXAMPLE] > ```rust @@ -184,6 +184,9 @@ Duplicate instances of the `no_implicit_prelude` attribute have no effect. > [!NOTE] > `rustc` currently warns on subsequent duplicate `no_implicit_prelude` attributes. +r[names.preludes.no_implicit_prelude.excluded-preludes] +The `no_implicit_prelude` attribute prevents the [standard library prelude], [extern prelude], and the [tool prelude] from being brought into scope for the module or any of its descendants. + r[names.preludes.no_implicit_prelude.lang] This attribute does not affect the [language prelude]. From 0ed80f7bc2df8db56a7300ebbb943fbdaf5e3e90 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 31 May 2025 15:57:08 -0700 Subject: [PATCH 23/33] Be explicit in the wording here --- src/names/preludes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 4f2ae167..1fc4fb10 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -188,7 +188,7 @@ r[names.preludes.no_implicit_prelude.excluded-preludes] The `no_implicit_prelude` attribute prevents the [standard library prelude], [extern prelude], and the [tool prelude] from being brought into scope for the module or any of its descendants. r[names.preludes.no_implicit_prelude.lang] -This attribute does not affect the [language prelude]. +The `no_implicit_prelude` attribute does not affect the [language prelude]. r[names.preludes.no_implicit_prelude.edition2018] > [!EDITION-2018] From 70fa8bd0fc196dcac2481bbf55d738184112e22a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 22 Sep 2025 13:24:41 -0700 Subject: [PATCH 24/33] Minor update of `no_implicit_prelude` More closely align with the template, and some minor word tweaks. --- src/names/preludes.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 1fc4fb10..4351d162 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -151,6 +151,7 @@ r[names.preludes.tool.intro] The tool prelude includes tool names for external tools in the [type namespace]. See the [tool attributes] section for more details. + r[names.preludes.no_implicit_prelude] ## The `no_implicit_prelude` attribute @@ -170,19 +171,19 @@ The *`no_implicit_prelude` [attribute]* is used to prevent implicit preludes fro > ``` r[names.preludes.no_implicit_prelude.syntax] -The `no_implicit_prelude` attribute uses the [MetaWord] syntax and thus does not take any inputs. +The `no_implicit_prelude` attribute uses the [MetaWord] syntax. r[names.preludes.no_implicit_prelude.allowed-positions] The `no_implicit_prelude` attribute may only be applied to the crate level or a module. > [!NOTE] -> `rustc` currently warns in other positions, but this may be rejected in the future. +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. r[names.preludes.no_implicit_prelude.duplicates] -Duplicate instances of the `no_implicit_prelude` attribute have no effect. +The `no_implicit_prelude` attribute may be used any number of times on a form. > [!NOTE] -> `rustc` currently warns on subsequent duplicate `no_implicit_prelude` attributes. +> `rustc` lints against any use following the first. r[names.preludes.no_implicit_prelude.excluded-preludes] The `no_implicit_prelude` attribute prevents the [standard library prelude], [extern prelude], and the [tool prelude] from being brought into scope for the module or any of its descendants. From 9ca5c57e2535a770e399ef2a9f154df07c58506e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 8 Nov 2025 19:05:50 -0800 Subject: [PATCH 25/33] Fix no_implicit_prelude to document the *current* edition in the main text This follows our style guide where the main text should document the current edition, and the edition blocks should note the differences to previous editions. --- src/names/preludes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 4351d162..d97aa53d 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -186,7 +186,7 @@ The `no_implicit_prelude` attribute may be used any number of times on a form. > `rustc` lints against any use following the first. r[names.preludes.no_implicit_prelude.excluded-preludes] -The `no_implicit_prelude` attribute prevents the [standard library prelude], [extern prelude], and the [tool prelude] from being brought into scope for the module or any of its descendants. +The `no_implicit_prelude` attribute prevents the [standard library prelude], [extern prelude], [`macro_use` prelude], and the [tool prelude] from being brought into scope for the module or any of its descendants. r[names.preludes.no_implicit_prelude.lang] The `no_implicit_prelude` attribute does not affect the [language prelude]. From 69707f462a8f20b39d919087b2a3f34b9b3c4959 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 11 Nov 2025 23:19:00 +0000 Subject: [PATCH 26/33] Wrap and reword `no_implicit_prelude` code comments One of the comments in the example stretched out a bit far; let's wrap that and reword the comments in the example for clarity and flow. --- src/names/preludes.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index d97aa53d..e2bcda3d 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -160,10 +160,12 @@ The *`no_implicit_prelude` [attribute]* is used to prevent implicit preludes fro > [!EXAMPLE] > ```rust -> // It can be applied to the crate root to apply to all modules. +> // The attribute can be applied to the crate root to affect +> // all modules. > #![no_implicit_prelude] > -> // Or it can be applied to a module to only affect that module or any of its descendants. +> // Or it can be applied to a module to only affect that module +> // and its descendants. > #[no_implicit_prelude] > mod example { > // ... From 60b75862e1541dc79e6d99d76e05f8b6ca035fa2 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 11 Nov 2025 23:21:51 +0000 Subject: [PATCH 27/33] Revise `no_implicit_prelude.allowed-positions` text It's more clear to say either that something can be applied "at the crate level" or "to the crate" than "to the crate level". Let's pick the latter and adjust for better grammatical parallelism. --- src/names/preludes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index e2bcda3d..bdc92096 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -176,7 +176,7 @@ r[names.preludes.no_implicit_prelude.syntax] The `no_implicit_prelude` attribute uses the [MetaWord] syntax. r[names.preludes.no_implicit_prelude.allowed-positions] -The `no_implicit_prelude` attribute may only be applied to the crate level or a module. +The `no_implicit_prelude` attribute may only be applied to the crate or to a module. > [!NOTE] > `rustc` ignores use in other positions but lints against it. This may become an error in the future. From ee8065669e8f91643fa8e4f502220efbb49c2501 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 11 Nov 2025 23:24:40 +0000 Subject: [PATCH 28/33] Revise `no_implicit_prelude.excluded-preludes` text Rather than saying "or any of its descendants", we can say "and its descendants" to express the same thing more concisely. Let's do that. --- src/names/preludes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index bdc92096..65a3700b 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -188,7 +188,7 @@ The `no_implicit_prelude` attribute may be used any number of times on a form. > `rustc` lints against any use following the first. r[names.preludes.no_implicit_prelude.excluded-preludes] -The `no_implicit_prelude` attribute prevents the [standard library prelude], [extern prelude], [`macro_use` prelude], and the [tool prelude] from being brought into scope for the module or any of its descendants. +The `no_implicit_prelude` attribute prevents the [standard library prelude], [extern prelude], [`macro_use` prelude], and the [tool prelude] from being brought into scope for the module and its descendants. r[names.preludes.no_implicit_prelude.lang] The `no_implicit_prelude` attribute does not affect the [language prelude]. From a5a9f03bf8f9da3d5241881f42870c883eb315a8 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 11 Nov 2025 23:26:43 +0000 Subject: [PATCH 29/33] Bring `no_implicit_prelude.edition2018` into present The remainder of this note is in the present tense, so saying that something "will" happen starting in the 2018 edition makes it sound as though that will happen in the future, even if what we mean is that the compiler "will" do it in the 2018 edition and later. Let's use the present tense here in emphatic form to distinguish this, and let's expand "it" for clarity. --- src/names/preludes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/names/preludes.md b/src/names/preludes.md index 65a3700b..3a2c3ff1 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -195,7 +195,7 @@ The `no_implicit_prelude` attribute does not affect the [language prelude]. r[names.preludes.no_implicit_prelude.edition2018] > [!EDITION-2018] -> 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. +> 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, the attribute does remove the `macro_use` prelude. [`extern crate`]: ../items/extern-crates.md [`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute From eecf819a7c158d78635e9a1ad4fb8a3ab3b1ffd2 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 20 Aug 2025 16:03:11 +0200 Subject: [PATCH 30/33] cool beans --- src/trait-bounds.md | 103 +++++++++++++++++++-------------------- src/types.md | 11 +++++ src/types/alias-types.md | 34 +++++++++++++ 3 files changed, 95 insertions(+), 53 deletions(-) create mode 100644 src/types/alias-types.md diff --git a/src/trait-bounds.md b/src/trait-bounds.md index f31265fb..dad48487 100644 --- a/src/trait-bounds.md +++ b/src/trait-bounds.md @@ -44,67 +44,64 @@ certain common cases: `trait A { type B: Copy; }` is equivalent to `trait A where Self::B: Copy { type B; }`. +r[bound.global] + +A bound which does not use the item's parameters or any higher-ranked lifetimes are considered global. + +An error is emitted if a global bound cannot be satisfied in an empty environment. + r[bound.satisfaction] -Bounds on an item must be satisfied when using the item. When type checking and -borrow checking a generic item, the bounds can be used to determine that a -trait is implemented for a type. For example, given `Ty: Trait` -* In the body of a generic function, methods from `Trait` can be called on `Ty` - values. Likewise associated constants on the `Trait` can be used. -* Associated types from `Trait` can be used. -* Generic functions and types with a `T: Trait` bounds can be used with `Ty` - being used for `T`. +The bounds of an item must be satisfied when using that item. -```rust -# type Surface = i32; -trait Shape { - fn draw(&self, surface: Surface); - fn name() -> &'static str; -} +r[bound.satisfaction.impl] -fn draw_twice(surface: Surface, sh: T) { - sh.draw(surface); // Can call method because T: Shape - sh.draw(surface); -} +- a trait bound can be satisfied by using an implementation of that trait +- an impl is applicable if, after instantiating its generic parameters with inference variables + - TODO: how to talk about "instantiate with infer vars"... + - the self type and trait arguments are equal to the trait bound, + - the where-bounds of the impl can be recursively satisfied -fn copy_and_draw_twice(surface: Surface, sh: T) where T: Shape { - let shape_copy = sh; // doesn't move sh because T: Copy - draw_twice(surface, sh); // Can use generic function because T: Shape -} +[bound.satisfaction.impl.builtin] -struct Figure(S, S); +There exists impls which are automatically generated by the compiler. -fn name_figure( - figure: Figure, // Type Figure is well-formed because U: Shape -) { - println!( - "Figure of two {}", - U::name(), // Can use associated function - ); -} -``` +- `Sized`,`Copy`, `Clone`,... -r[bound.trivial] -Bounds that don't use the item's parameters or [higher-ranked lifetimes] are checked when the item is defined. -It is an error for such a bound to be false. - -r[bound.special] -[`Copy`], [`Clone`], and [`Sized`] bounds are also checked for certain generic types when using the item, even if the use does not provide a concrete type. -It is an error to have `Copy` or `Clone` as a bound on a mutable reference, [trait object], or [slice]. -It is an error to have `Sized` as a bound on a trait object or slice. - -```rust,compile_fail -struct A<'a, T> -where - i32: Default, // Allowed, but not useful - i32: Iterator, // Error: `i32` is not an iterator - &'a mut T: Copy, // (at use) Error: the trait bound is not satisfied - [T]: Sized, // (at use) Error: size cannot be known at compilation -{ - f: &'a T, -} -struct UsesA<'a, T>(A<'a, T>); -``` + +- alternative: mention this in item-kind impl + +[bound.satisfaction.impl.builtin.trait-object] + +Trait objects implement their trait if TODO: lookup conditions, something something project bounds make sense + +[bound.satisfaction.bounds] + +While inside of a generic item, trait bounds can be satisfied by using the where-bounds of the current item as the item is able to assume that its bounds are satisfied. For this, higher-ranked where-bounds can be instantiated with inference variables. The where-bound is then equated with the trait bound that needs to be satisfied. + +[bound.satisfaction.alias-bounds] + +- if an alias cannot be normalized in the current environment, trait bounds using this alias as a self type can be proven by using its item bounds +- TODO: alias bounds from nested self-types github.com/rust-lang/rust/pull/120752 + + +[bound.satisfaction.candidate-preference] + +> This is purely descriptive. Candidate preference behavior may change in future releases and must not be relied upon for correctness or soundness. + +If there are multiple ways to satisfy a trait bound, some groups of candidate are preferred over others. In case a single group has multiple different candidates, the bound remains ambiguous. Candidate preference has the following order +- builtin implementations of `Sized` +- if there are any non-global where-bounds, all where-bounds +- alias-bounds +- impls + - In case the goal trait bound does not contain any inference variables, we prefer builtin trait object impls over user-written impls. TODO: that's unsound jank +- global where-bounds (only relevant if it does not hold) + +> note: this candidate preference can result in incorrect errors and type mismatches, e.g. ... + +[bound.satisfaction.cycles] + +In case satisfying a bound requires recursively satisfying the same bound, we've encountered a *cycle*. TODO: terminology is iffy here .... can just drop this again r[bound.trait-object] Trait and lifetime bounds are also used to name [trait objects]. diff --git a/src/types.md b/src/types.md index de67050a..86cd4ebc 100644 --- a/src/types.md +++ b/src/types.md @@ -149,6 +149,17 @@ enum List { let a: List = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil)))); ``` +## Equality of types + +Equality and subtyping of types is generally structural. If the outermost type constructors are the same, +the fields are pairwise related. The only exceptions from this rule are higher ranked types and alias types + +higher ranked types: +uwu, instantiate binder with placeholders, eq + +aliases +normalized to a rigid type, then equated as normal + [Array]: types/array.md [Boolean]: types/boolean.md [Closures]: types/closure.md diff --git a/src/types/alias-types.md b/src/types/alias-types.md new file mode 100644 index 00000000..7985c157 --- /dev/null +++ b/src/types/alias-types.md @@ -0,0 +1,34 @@ +r[type.alias] + +- associated types +- opaque types + - link from "impl-trait type" to this or param + +r[type.alias.rigid] + +Aliases might be treated as rigid in their current environment. In this case they behave like other rigid types. + +r[type.alias.normalization] + +Alias types can be normalized to their underlying type. +- for associated types this is the type provided by the corresponding impl +- opaque types + +r[type.alias.normalization.assoc-type] + +Similar to how trait bounds get satisfied, associated types can be normalized via +multiple different candidates + +- impl (also builtin) +- projection bound in the environment TODO: where do we talk about them +- alias bound of their self type + +candidate preference: +- normalizing an alias relies on the candidate group used to prove their corresponding trait bound +- if corresponding trait bound has been proven via a where-bound or an alias-bound, we do not consider impls + - if there is no remaining candidate, the associated type is rigid + +For all applicable candidates we +- prefer where-bounds +- then alias bounds +- then impls From a686c045782aac9fc4ff1b0fbebfe656060e150a Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 27 Aug 2025 09:04:26 +0200 Subject: [PATCH 31/33] nyaa --- src/trait-bounds.md | 2 +- src/types.md | 23 ++++++++++++++++++----- src/types/alias-types.md | 3 ++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/trait-bounds.md b/src/trait-bounds.md index dad48487..23845126 100644 --- a/src/trait-bounds.md +++ b/src/trait-bounds.md @@ -64,7 +64,7 @@ r[bound.satisfaction.impl] [bound.satisfaction.impl.builtin] -There exists impls which are automatically generated by the compiler. +There exist impls which are automatically generated by the compiler. - `Sized`,`Copy`, `Clone`,... diff --git a/src/types.md b/src/types.md index 86cd4ebc..9d3f9516 100644 --- a/src/types.md +++ b/src/types.md @@ -151,14 +151,27 @@ let a: List = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil)))); ## Equality of types +r[types.equality] + Equality and subtyping of types is generally structural. If the outermost type constructors are the same, -the fields are pairwise related. The only exceptions from this rule are higher ranked types and alias types +corresponding generic arguments are compared. The only exceptions from this rule are higher ranked types and alias types. + +r[types.equality.aliases] + +Aliases are compared by first normalizing them to a *rigid* type? and then equating their type constructors and recursing into their generic arguments. + +r[types.equality.higher-ranked] + +Function pointers and trait objects may be higher-ranked. + +r[types.equality.higher-ranked.sub] + +Subtyping is checked by instantiating the `for` of the subtype with inference variables and the `for` of the supertype with placeholders before relating them as normal. + +r[types.equality.higher-ranked.eq] -higher ranked types: -uwu, instantiate binder with placeholders, eq +Equality is checked by both instantiating the `for` of the lhs with inference variables and the `for` of the rhs with placeholders before equating them, and also doing the opposite. -aliases -normalized to a rigid type, then equated as normal [Array]: types/array.md [Boolean]: types/boolean.md diff --git a/src/types/alias-types.md b/src/types/alias-types.md index 7985c157..d10ab761 100644 --- a/src/types/alias-types.md +++ b/src/types/alias-types.md @@ -6,7 +6,8 @@ r[type.alias] r[type.alias.rigid] -Aliases might be treated as rigid in their current environment. In this case they behave like other rigid types. +Aliases might be treated as *rigid* in their current environment. In this case they behave like other types. +Their equality is structural, *rigid* aliases are only equal if both have the same type constructor and equal corresponding arguments. r[type.alias.normalization] From 62d1539213c4f1997bdf9c930c313c5d0f708f5e Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 10 Sep 2025 16:19:35 +0200 Subject: [PATCH 32/33] Update src/trait-bounds.md --- src/trait-bounds.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trait-bounds.md b/src/trait-bounds.md index 23845126..514fa3bd 100644 --- a/src/trait-bounds.md +++ b/src/trait-bounds.md @@ -46,7 +46,7 @@ certain common cases: r[bound.global] -A bound which does not use the item's parameters or any higher-ranked lifetimes are considered global. +Bounds which does not use the item's parameters or any higher-ranked lifetimes are considered global. An error is emitted if a global bound cannot be satisfied in an empty environment. From c35b7288be4b52f85aefc9dc16cc3db7b44743b9 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 17 Sep 2025 13:27:38 +0200 Subject: [PATCH 33/33] rarw --- src/items/generics.md | 6 +++++ src/trait-bounds.md | 56 ++++++++++++++++++++++++++++++------------- src/types.md | 9 +++---- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/items/generics.md b/src/items/generics.md index a8cb27ba..807ef87b 100644 --- a/src/items/generics.md +++ b/src/items/generics.md @@ -310,6 +310,12 @@ struct Foo<#[my_flexible_clone(unbounded)] H> { } ``` +r[items.generics.instantiation] +When using an item its generic parameters have to get instantiated. This replaces all occurances of the parameter with either the explicitly provided argument or a new unconstrained inference variable. + +Instantiating the generic parameters of an item generally requires proving its where clauses. + + [array repeat expression]: ../expressions/array-expr.md [arrays]: ../types/array.md [slices]: ../types/slice.md diff --git a/src/trait-bounds.md b/src/trait-bounds.md index 514fa3bd..15a4fec1 100644 --- a/src/trait-bounds.md +++ b/src/trait-bounds.md @@ -56,13 +56,11 @@ The bounds of an item must be satisfied when using that item. r[bound.satisfaction.impl] -- a trait bound can be satisfied by using an implementation of that trait -- an impl is applicable if, after instantiating its generic parameters with inference variables - - TODO: how to talk about "instantiate with infer vars"... - - the self type and trait arguments are equal to the trait bound, - - the where-bounds of the impl can be recursively satisfied +A trait bound can be satisfied by using an implementation of that trait. An implementation is applicable if, +after instantiating its generic parameters with new inference variables, the self type and trait arguments are +equal to the trait bound and the where-bounds of the impl can be recursively satisfied. -[bound.satisfaction.impl.builtin] +r[bound.satisfaction.impl.builtin] There exist impls which are automatically generated by the compiler. @@ -71,21 +69,51 @@ There exist impls which are automatically generated by the compiler. - alternative: mention this in item-kind impl -[bound.satisfaction.impl.builtin.trait-object] +r[bound.satisfaction.impl.builtin.trait-object] Trait objects implement their trait if TODO: lookup conditions, something something project bounds make sense -[bound.satisfaction.bounds] +r[bound.satisfaction.bounds] While inside of a generic item, trait bounds can be satisfied by using the where-bounds of the current item as the item is able to assume that its bounds are satisfied. For this, higher-ranked where-bounds can be instantiated with inference variables. The where-bound is then equated with the trait bound that needs to be satisfied. -[bound.satisfaction.alias-bounds] +r[bound.satisfaction.alias-bounds] -- if an alias cannot be normalized in the current environment, trait bounds using this alias as a self type can be proven by using its item bounds -- TODO: alias bounds from nested self-types github.com/rust-lang/rust/pull/120752 +If an alias type is rigid in the current environment, trait bounds using this alias as a self type can be satisfied by using its item bounds. + +```rust +trait Trait { + type Assoc: Clone; +} + +fn foo(x: &T::Assoc) -> T::Assoc { + // The where-bound `T::Assoc: Clone` is satisfied using the `Clone` item-bound. + x.clone() +} +``` + +r[bound.satisfaction.alias-bounds.nested] + +We also consider the item bounds of the self type of aliases to satisfy trait bounds. + +```rust +trait Trait { + type Assoc: Iterator + where + ::Item: Clone; + // equivalent to + // type Assoc: Iterator; +} + +fn item_is_clone(iter: T::Assoc) { + for item in iter { + let _ = item.clone(); + } +} +``` -[bound.satisfaction.candidate-preference] +r[bound.satisfaction.candidate-preference] > This is purely descriptive. Candidate preference behavior may change in future releases and must not be relied upon for correctness or soundness. @@ -99,10 +127,6 @@ If there are multiple ways to satisfy a trait bound, some groups of candidate ar > note: this candidate preference can result in incorrect errors and type mismatches, e.g. ... -[bound.satisfaction.cycles] - -In case satisfying a bound requires recursively satisfying the same bound, we've encountered a *cycle*. TODO: terminology is iffy here .... can just drop this again - r[bound.trait-object] Trait and lifetime bounds are also used to name [trait objects]. diff --git a/src/types.md b/src/types.md index 9d3f9516..70507606 100644 --- a/src/types.md +++ b/src/types.md @@ -153,12 +153,14 @@ let a: List = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil)))); r[types.equality] -Equality and subtyping of types is generally structural. If the outermost type constructors are the same, -corresponding generic arguments are compared. The only exceptions from this rule are higher ranked types and alias types. +Equality and subtyping of types is generally structural; if the outermost type constructors are the same, +their corresponding generic arguments are pairwise compared. We say types with this equality behavior are *rigid*. The only exceptions from this rule are higher ranked types and alias types. + +r[types.equality.rigid] r[types.equality.aliases] -Aliases are compared by first normalizing them to a *rigid* type? and then equating their type constructors and recursing into their generic arguments. +Aliases are compared by first normalizing them to a *rigid* type and then equating their type constructors and recursing into their generic arguments. r[types.equality.higher-ranked] @@ -172,7 +174,6 @@ r[types.equality.higher-ranked.eq] Equality is checked by both instantiating the `for` of the lhs with inference variables and the `for` of the rhs with placeholders before equating them, and also doing the opposite. - [Array]: types/array.md [Boolean]: types/boolean.md [Closures]: types/closure.md