From 3de8d786249d82fba0827ccfd307af71ef92675a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 28 Aug 2024 17:13:17 -0700 Subject: [PATCH 1/7] Allow admonition blockquotes with blank lines This fixes an issue where if an admonition blockquote had multiple paragraphs, it would incorrectly interpret it as multiple blockquotes, and break the formatting. The problem is that the regex was expecting at least one space after the `>`. I vaguely recall doing this intentionally, but I don't remember now why I did it this way, and I can't find any problems with this approach. --- mdbook-spec/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdbook-spec/src/lib.rs b/mdbook-spec/src/lib.rs index 1a8a919dc..0c3cb4d14 100644 --- a/mdbook-spec/src/lib.rs +++ b/mdbook-spec/src/lib.rs @@ -19,7 +19,7 @@ static RULE_RE: Lazy = Lazy::new(|| Regex::new(r"(?m)^r\[([^]]+)]$").unwr /// The Regex for the syntax for blockquotes that have a specific CSS class, /// like `> [!WARNING]`. static ADMONITION_RE: Lazy = Lazy::new(|| { - Regex::new(r"(?m)^ *> \[!(?[^]]+)\]\n(?
(?: *> .*\n)+)").unwrap() + Regex::new(r"(?m)^ *> \[!(?[^]]+)\]\n(?
(?: *>.*\n)+)").unwrap() }); pub fn handle_preprocessing(pre: &dyn Preprocessor) -> Result<(), Error> { From 65c7bc2d4be35e0e596415e6d0f4802da42b1bc6 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 28 Aug 2024 17:18:05 -0700 Subject: [PATCH 2/7] Include the admonition term at the start of the admonition This adds the term ("Warning") at the beginning of the admonition with a standardized styling (bold italics, with a colon). This ensures uniform styling. --- mdbook-spec/src/lib.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/mdbook-spec/src/lib.rs b/mdbook-spec/src/lib.rs index 0c3cb4d14..01924ac54 100644 --- a/mdbook-spec/src/lib.rs +++ b/mdbook-spec/src/lib.rs @@ -131,15 +131,28 @@ impl Spec { ADMONITION_RE .replace_all(&chapter.content, |caps: &Captures<'_>| { let lower = caps["admon"].to_lowercase(); + let term = to_initial_case(&caps["admon"]); + let blockquote = &caps["blockquote"]; format!( - "
\n\n{}\n\n
\n", - &caps["blockquote"] + "
\n\ + \n\ + > ***{term}:***\n\ + {blockquote}\n\ + \n\ +
\n", ) }) .to_string() } } +fn to_initial_case(s: &str) -> String { + let mut chars = s.chars(); + let first = chars.next().expect("not empty").to_uppercase(); + let rest = chars.as_str().to_lowercase(); + format!("{first}{rest}") +} + impl Preprocessor for Spec { fn name(&self) -> &str { "spec" From de2c4a1f5cce4b847dcd71b1d1e4d347f3f7fc85 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 28 Aug 2024 17:19:23 -0700 Subject: [PATCH 3/7] Fix indented admonitions This fixes the formatting for admonitions when they are indented. The code was missing the indentation for the parts that it was adding, which made it overall inconsistent and fail to render correctly. --- mdbook-spec/src/lib.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mdbook-spec/src/lib.rs b/mdbook-spec/src/lib.rs index 01924ac54..cef370a25 100644 --- a/mdbook-spec/src/lib.rs +++ b/mdbook-spec/src/lib.rs @@ -133,13 +133,15 @@ impl Spec { let lower = caps["admon"].to_lowercase(); let term = to_initial_case(&caps["admon"]); let blockquote = &caps["blockquote"]; + let initial_spaces = blockquote.chars().position(|ch| ch != ' ').unwrap_or(0); + let space = &blockquote[..initial_spaces]; format!( - "
\n\ + "{space}
\n\ \n\ - > ***{term}:***\n\ + {space}> ***{term}:***\n\ {blockquote}\n\ \n\ -
\n", + {space}
\n", ) }) .to_string() From 9d40c46f6b01ff2d73af618b47d3d85d36a94804 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 29 Aug 2024 08:04:33 -0700 Subject: [PATCH 4/7] De-wrap warning blocks --- src/behavior-considered-undefined.md | 8 +------- src/items/external-blocks.md | 5 +---- src/names/preludes.md | 4 +--- src/patterns.md | 4 +--- src/type-layout.md | 12 ++---------- 5 files changed, 6 insertions(+), 27 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index a03951d3a..757d0cd16 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -14,13 +14,7 @@ undefined behavior, it is *unsound*.
-***Warning:*** The following list is not exhaustive; it may grow or shrink. -There is no formal model of Rust's semantics for what is and is not allowed in -unsafe code, so there may be more behavior considered unsafe. We also reserve -the right to make some of the behavior in that list defined in the future. In -other words, this list does not say that anything will *definitely* always be -undefined in all future Rust version (but we might make such commitments for -some list items in the future). +***Warning:*** The following list is not exhaustive; it may grow or shrink. There is no formal model of Rust's semantics for what is and is not allowed in unsafe code, so there may be more behavior considered unsafe. We also reserve the right to make some of the behavior in that list defined in the future. In other words, this list does not say that anything will *definitely* always be undefined in all future Rust version (but we might make such commitments for some list items in the future). Please read the [Rustonomicon] before writing unsafe code. diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index bb59af898..6223e322e 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -294,10 +294,7 @@ that symbol rather than having to look it up by name.
-Warning: `link_ordinal` should only be used in cases where the ordinal of the -symbol is known to be stable: if the ordinal of a symbol is not explicitly set -when its containing binary is built then one will be automatically assigned to -it, and that assigned ordinal may change between builds of the binary. +Warning: `link_ordinal` should only be used in cases where the ordinal of the symbol is known to be stable: if the ordinal of a symbol is not explicitly set when its containing binary is built then one will be automatically assigned to it, and that assigned ordinal may change between builds of the binary.
diff --git a/src/names/preludes.md b/src/names/preludes.md index 7e6b7d45d..1e1756b61 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -93,9 +93,7 @@ The *`no_std` [attribute]* may be applied at the crate level to prevent the
-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. +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.
diff --git a/src/patterns.md b/src/patterns.md index 479bb6233..585b3987d 100644 --- a/src/patterns.md +++ b/src/patterns.md @@ -144,9 +144,7 @@ Since negative numbers are not [literals], literal patterns also accept an optio
-C string and raw C string literals are accepted in literal patterns, but `&CStr` -doesn't implement structural equality (`#[derive(Eq, PartialEq)]`) and therefore -any such `match` on a `&CStr` will be rejected with a type error. +C string and raw C string literals are accepted in literal patterns, but `&CStr` doesn't implement structural equality (`#[derive(Eq, PartialEq)]`) and therefore any such `match` on a `&CStr` will be rejected with a type error.
diff --git a/src/type-layout.md b/src/type-layout.md index f558b5af3..0af79de06 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -256,9 +256,7 @@ struct.size = current_offset + padding_needed_for(current_offset, struct.alignme
-Warning: This pseudocode uses a naive algorithm that ignores overflow issues for -the sake of clarity. To perform memory layout computations in actual code, use -[`Layout`]. +Warning: This pseudocode uses a naive algorithm that ignores overflow issues for the sake of clarity. To perform memory layout computations in actual code, use [`Layout`].
@@ -310,13 +308,7 @@ the default `enum` size and alignment for the target platform's C ABI.
-Warning: There are crucial differences between an `enum` in the C language and -Rust's [field-less enums] with this representation. An `enum` in C is -mostly a `typedef` plus some named constants; in other words, an object of an -`enum` type can hold any integer value. For example, this is often used for -bitflags in `C`. In contrast, Rust’s [field-less enums] can only legally hold -the discriminant values, everything else is [undefined behavior]. Therefore, -using a field-less enum in FFI to model a C `enum` is often wrong. +Warning: There are crucial differences between an `enum` in the C language and Rust's [field-less enums] with this representation. An `enum` in C is mostly a `typedef` plus some named constants; in other words, an object of an `enum` type can hold any integer value. For example, this is often used for bitflags in `C`. In contrast, Rust’s [field-less enums] can only legally hold the discriminant values, everything else is [undefined behavior]. Therefore, using a field-less enum in FFI to model a C `enum` is often wrong.
From 5cb05674ee383824cb236a58ec6f75bc75d612e1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 28 Aug 2024 17:36:31 -0700 Subject: [PATCH 5/7] Switch warnings from div to blockquote admonitions This switches the custom div-based warnings to the admonition syntax provided by the mdbook-spec extension. --- src/behavior-considered-undefined.md | 11 ++++------- src/conditional-compilation.md | 7 ++----- src/expressions/method-call-expr.md | 13 +++++-------- src/expressions/operator-expr.md | 25 +++++++++---------------- src/introduction.md | 17 +++++------------ src/items/external-blocks.md | 7 ++----- src/names/preludes.md | 7 ++----- src/patterns.md | 7 ++----- src/type-layout.md | 14 ++++---------- 9 files changed, 35 insertions(+), 73 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 757d0cd16..e60fe473a 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -12,13 +12,10 @@ behaviors. `unsafe` code that satisfies this property for any safe client is called *sound*; if `unsafe` code can be misused by safe code to exhibit undefined behavior, it is *unsound*. -
- -***Warning:*** The following list is not exhaustive; it may grow or shrink. There is no formal model of Rust's semantics for what is and is not allowed in unsafe code, so there may be more behavior considered unsafe. We also reserve the right to make some of the behavior in that list defined in the future. In other words, this list does not say that anything will *definitely* always be undefined in all future Rust version (but we might make such commitments for some list items in the future). - -Please read the [Rustonomicon] before writing unsafe code. - -
+> [!WARNING] +> The following list is not exhaustive; it may grow or shrink. There is no formal model of Rust's semantics for what is and is not allowed in unsafe code, so there may be more behavior considered unsafe. We also reserve the right to make some of the behavior in that list defined in the future. In other words, this list does not say that anything will *definitely* always be undefined in all future Rust version (but we might make such commitments for some list items in the future). +> +> Please read the [Rustonomicon] before writing unsafe code. * Data races. * Accessing (loading from or storing to) a place that is [dangling] or [based on diff --git a/src/conditional-compilation.md b/src/conditional-compilation.md index e445475dc..f73f8354a 100644 --- a/src/conditional-compilation.md +++ b/src/conditional-compilation.md @@ -55,11 +55,8 @@ configuration option from within the source code of the crate being compiled. > by [Cargo][cargo-feature] for specifying compile-time options and optional > dependencies. -
- -Warning: Arbitrarily-set configuration options can clash with compiler-set configuration options. For example, it is possible to do `rustc --cfg "unix" program.rs` while compiling to a Windows target, and have both `unix` and `windows` configuration options set at the same time. Doing this would be unwise. - -
+> [!WARNING] +> Arbitrarily-set configuration options can clash with compiler-set configuration options. For example, it is possible to do `rustc --cfg "unix" program.rs` while compiling to a Windows target, and have both `unix` and `windows` configuration options set at the same time. Doing this would be unwise. ### `target_arch` diff --git a/src/expressions/method-call-expr.md b/src/expressions/method-call-expr.md index ca7f18502..9535cd207 100644 --- a/src/expressions/method-call-expr.md +++ b/src/expressions/method-call-expr.md @@ -73,14 +73,11 @@ These cases require a [disambiguating function call syntax] for method and funct > This special case may be removed in the future. -
- -***Warning:*** For [trait objects], if there is an inherent method of the same name as a trait method, it will give a compiler error when trying to call the method in a method call expression. -Instead, you can call the method using [disambiguating function call syntax], in which case it calls the trait method, not the inherent method. -There is no way to call the inherent method. -Just don't define inherent methods on trait objects with the same name as a trait method and you'll be fine. - -
+> [!WARNING] +> For [trait objects], if there is an inherent method of the same name as a trait method, it will give a compiler error when trying to call the method in a method call expression. +> Instead, you can call the method using [disambiguating function call syntax], in which case it calls the trait method, not the inherent method. +> There is no way to call the inherent method. +> Just don't define inherent methods on trait objects with the same name as a trait method and you'll be fine. [_CallParams_]: call-expr.md [_Expression_]: ../expressions.md diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index ea3984158..a9e91f0a6 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -455,14 +455,10 @@ If the integer type is smaller than the pointer type, the address may be truncat Casting from an integer to a raw pointer interprets the integer as a memory address and produces a pointer referencing that memory. -
- -Warning: -This interacts with the Rust memory model, which is still under development. -A pointer obtained from this cast may suffer additional restrictions even if it is bitwise equal to a valid pointer. -Dereferencing such a pointer may be [undefined behavior] if aliasing rules are not followed. - -
+> [!WARNING] +> This interacts with the Rust memory model, which is still under development. +> A pointer obtained from this cast may suffer additional restrictions even if it is bitwise equal to a valid pointer. +> Dereferencing such a pointer may be [undefined behavior] if aliasing rules are not followed. A trivial example of sound address arithmetic: @@ -642,14 +638,11 @@ fn example() { Like assignment expressions, compound assignment expressions always produce [the unit value][unit]. -
- -Warning: The evaluation order of operands swaps depending on the types of the operands: -with primitive types the right-hand side will get evaluated first, while with non-primitive types the left-hand side will get evaluated first. -Try not to write code that depends on the evaluation order of operands in compound assignment expressions. -See [this test] for an example of using this dependency. - -
+> [!WARNING] +> The evaluation order of operands swaps depending on the types of the operands: +> with primitive types the right-hand side will get evaluated first, while with non-primitive types the left-hand side will get evaluated first. +> Try not to write code that depends on the evaluation order of operands in compound assignment expressions. +> See [this test] for an example of using this dependency. [copies or moves]: ../expressions.md#moved-and-copied-types [dropping]: ../destructors.md diff --git a/src/introduction.md b/src/introduction.md index 2bf5bebbc..d19b699cc 100644 --- a/src/introduction.md +++ b/src/introduction.md @@ -7,13 +7,9 @@ It provides three kinds of material: - Chapters that informally describe the memory model, concurrency model, runtime services, linkage model, and debugging facilities. - Appendix chapters providing rationale and references to languages that influenced the design. -
- -Warning: -This book is incomplete. Documenting everything takes a while. -See the [GitHub issues] for what is not documented in this book. - -
+> [!WARNING] +> This book is incomplete. Documenting everything takes a while. +> See the [GitHub issues] for what is not documented in this book. ## Rust releases @@ -92,11 +88,8 @@ These conventions are documented here. * Warnings that show unsound behavior in the language or possibly confusing interactions of language features are in a special warning box. -
- - Warning: This is an example warning. - -
+ > [!WARNING] + > This is an example warning. * Code snippets inline in the text are inside `` tags. diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 6223e322e..dbd55fb33 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -292,11 +292,8 @@ to link against. An ordinal is a unique number per symbol exported by a dynamic library on Windows and can be used when the library is being loaded to find that symbol rather than having to look it up by name. -
- -Warning: `link_ordinal` should only be used in cases where the ordinal of the symbol is known to be stable: if the ordinal of a symbol is not explicitly set when its containing binary is built then one will be automatically assigned to it, and that assigned ordinal may change between builds of the binary. - -
+> [!WARNING] +> `link_ordinal` should only be used in cases where the ordinal of the symbol is known to be stable: if the ordinal of a symbol is not explicitly set when its containing binary is built then one will be automatically assigned to it, and that assigned ordinal may change between builds of the binary. ```rust,ignore diff --git a/src/names/preludes.md b/src/names/preludes.md index 1e1756b61..6aa761c92 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -91,11 +91,8 @@ The *`no_std` [attribute]* may be applied at the crate level to prevent the > 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. - -
+> [!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. ## Language prelude diff --git a/src/patterns.md b/src/patterns.md index 585b3987d..305699a74 100644 --- a/src/patterns.md +++ b/src/patterns.md @@ -142,11 +142,8 @@ if let (a, 3) = (1, 2) { // "(a, 3)" is refutable, and will not match _Literal patterns_ match exactly the same value as what is created by the literal. Since negative numbers are not [literals], literal patterns also accept an optional minus sign before the literal, which acts like the negation operator. -
- -C string and raw C string literals are accepted in literal patterns, but `&CStr` doesn't implement structural equality (`#[derive(Eq, PartialEq)]`) and therefore any such `match` on a `&CStr` will be rejected with a type error. - -
+> [!WARNING] +> C string and raw C string literals are accepted in literal patterns, but `&CStr` doesn't implement structural equality (`#[derive(Eq, PartialEq)]`) and therefore any such `match` on a `&CStr` will be rejected with a type error. Literal patterns are always refutable. diff --git a/src/type-layout.md b/src/type-layout.md index 0af79de06..1f4b6b1a2 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -254,11 +254,8 @@ for field in struct.fields_in_declaration_order() { struct.size = current_offset + padding_needed_for(current_offset, struct.alignment); ``` -
- -Warning: This pseudocode uses a naive algorithm that ignores overflow issues for the sake of clarity. To perform memory layout computations in actual code, use [`Layout`]. - -
+> [!WARNING] +> This pseudocode uses a naive algorithm that ignores overflow issues for the sake of clarity. To perform memory layout computations in actual code, use [`Layout`]. > Note: This algorithm can produce zero-sized structs. In C, an empty struct > declaration like `struct Foo { }` is illegal. However, both gcc and clang @@ -306,11 +303,8 @@ the default `enum` size and alignment for the target platform's C ABI. > really a "best guess". In particular, this may be incorrect when the C code > of interest is compiled with certain flags. -
- -Warning: There are crucial differences between an `enum` in the C language and Rust's [field-less enums] with this representation. An `enum` in C is mostly a `typedef` plus some named constants; in other words, an object of an `enum` type can hold any integer value. For example, this is often used for bitflags in `C`. In contrast, Rust’s [field-less enums] can only legally hold the discriminant values, everything else is [undefined behavior]. Therefore, using a field-less enum in FFI to model a C `enum` is often wrong. - -
+> [!WARNING] +> There are crucial differences between an `enum` in the C language and Rust's [field-less enums] with this representation. An `enum` in C is mostly a `typedef` plus some named constants; in other words, an object of an `enum` type can hold any integer value. For example, this is often used for bitflags in `C`. In contrast, Rust’s [field-less enums] can only legally hold the discriminant values, everything else is [undefined behavior]. Therefore, using a field-less enum in FFI to model a C `enum` is often wrong. #### `#[repr(C)]` Enums With Fields From 5cbf08b3a3629dfa00fdab5958cb34ce75e06113 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 28 Aug 2024 17:36:54 -0700 Subject: [PATCH 6/7] Update comment now that warnings use admonitions --- theme/reference.css | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/theme/reference.css b/theme/reference.css index 04b62151b..5042abdcf 100644 --- a/theme/reference.css +++ b/theme/reference.css @@ -11,15 +11,11 @@ the parenthetical. So for this example, you'd use } /* -Warnings and notes: +Warnings are defined using admonitions in blockquotes: -Write the
s on their own line. E.g. +> [!WARNING] +> This is bad! -
- -Warning: This is bad! - -
*/ main .warning p { padding: 10px 20px; From 4b0cb6ce268baa476cbd802e1ad95c3679bf949b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 28 Aug 2024 17:38:37 -0700 Subject: [PATCH 7/7] Fix CSS styling for warning admonitions Now that warnings are wrapped in blockquotes, the CSS needs to be adjusted for that. This also includes a minor fix for the `::before` rule so that it only applies to the first paragraph in a multi-paragraph warning. --- theme/reference.css | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/theme/reference.css b/theme/reference.css index 5042abdcf..cbc7aca8a 100644 --- a/theme/reference.css +++ b/theme/reference.css @@ -17,36 +17,40 @@ Warnings are defined using admonitions in blockquotes: > This is bad! */ -main .warning p { - padding: 10px 20px; - margin: 20px 0; +main .warning blockquote { + padding: 0px; } -main .warning p::before { +main .warning blockquote p { + padding: 0px 20px; + margin: 10px 0; +} + +main .warning blockquote p:first-child::before { content: "⚠️ "; } -.light main .warning p, -.rust main .warning p { +.light main .warning blockquote, +.rust main .warning blockquote { border: 2px solid red; background: #ffcece; } -.rust main .warning p { +.rust main .warning blockquote { /* overrides previous declaration */ border-color: #961717; } -.coal main .warning p, -.navy main .warning p, -.ayu main .warning p { +.coal main .warning blockquote, +.navy main .warning blockquote, +.ayu main .warning blockquote { background: #542626; } /* Make the links higher contrast on dark themes */ -.coal main .warning p a, -.navy main .warning p a, -.ayu main .warning p a { +.coal main .warning blockquote p a, +.navy main .warning blockquote p a, +.ayu main .warning blockquote p a { color: #80d0d0; }