Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch warning blocks to use admonitions #1595

Merged
merged 7 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions mdbook-spec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ static RULE_RE: Lazy<Regex> = 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<Regex> = Lazy::new(|| {
Regex::new(r"(?m)^ *> \[!(?<admon>[^]]+)\]\n(?<blockquote>(?: *> .*\n)+)").unwrap()
Regex::new(r"(?m)^ *> \[!(?<admon>[^]]+)\]\n(?<blockquote>(?: *>.*\n)+)").unwrap()
});

pub fn handle_preprocessing(pre: &dyn Preprocessor) -> Result<(), Error> {
Expand Down Expand Up @@ -131,15 +131,30 @@ 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"];
let initial_spaces = blockquote.chars().position(|ch| ch != ' ').unwrap_or(0);
let space = &blockquote[..initial_spaces];
format!(
"<div class=\"{lower}\">\n\n{}\n\n</div>\n",
&caps["blockquote"]
"{space}<div class=\"{lower}\">\n\
\n\
{space}> ***{term}:***\n\
{blockquote}\n\
\n\
{space}</div>\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"
Expand Down
17 changes: 4 additions & 13 deletions src/behavior-considered-undefined.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +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*.

<div class="warning">

***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.

</div>
> [!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
Expand Down
7 changes: 2 additions & 5 deletions src/conditional-compilation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<div class="warning">

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.

</div>
> [!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`

Expand Down
13 changes: 5 additions & 8 deletions src/expressions/method-call-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.


<div class="warning">

***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.

</div>
> [!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
Expand Down
25 changes: 9 additions & 16 deletions src/expressions/operator-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<div class="warning">

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.

</div>
> [!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:

Expand Down Expand Up @@ -642,14 +638,11 @@ fn example() {

Like assignment expressions, compound assignment expressions always produce [the unit value][unit].

<div class="warning">

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.

</div>
> [!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
Expand Down
17 changes: 5 additions & 12 deletions src/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<div class="warning">

Warning:
This book is incomplete. Documenting everything takes a while.
See the [GitHub issues] for what is not documented in this book.

</div>
> [!WARNING]
> This book is incomplete. Documenting everything takes a while.
> See the [GitHub issues] for what is not documented in this book.

## Rust releases

Expand Down Expand Up @@ -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.

<div class="warning">

Warning: This is an example warning.

</div>
> [!WARNING]
> This is an example warning.

* Code snippets inline in the text are inside `<code>` tags.

Expand Down
10 changes: 2 additions & 8 deletions src/items/external-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,14 +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.

<div class="warning">

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.

</div>
> [!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.

<!-- ignore: Only works on x86 Windows -->
```rust,ignore
Expand Down
9 changes: 2 additions & 7 deletions src/names/preludes.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +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`).

<div class="warning">

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.

</div>
> [!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

Expand Down
9 changes: 2 additions & 7 deletions src/patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +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.

<div class="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.

</div>
> [!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.

Expand Down
22 changes: 4 additions & 18 deletions src/type-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,8 @@ for field in struct.fields_in_declaration_order() {
struct.size = current_offset + padding_needed_for(current_offset, struct.alignment);
```

<div class="warning">

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`].

</div>
> [!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
Expand Down Expand Up @@ -308,17 +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.

<div class="warning">

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.

</div>
> [!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

Expand Down
40 changes: 20 additions & 20 deletions theme/reference.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,46 @@ the parenthetical. So for this example, you'd use
}

/*
Warnings and notes:
Warnings are defined using admonitions in blockquotes:

Write the <div>s on their own line. E.g.
> [!WARNING]
> This is bad!

<div class="warning">

Warning: This is bad!

</div>
*/
main .warning p {
padding: 10px 20px;
margin: 20px 0;
main .warning blockquote {
padding: 0px;
}

main .warning blockquote p {
padding: 0px 20px;
margin: 10px 0;
}

main .warning p::before {
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;
}

Expand Down