From c274cef58c4165c249d0949d51761c4e5ba99aa0 Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Tue, 26 Sep 2023 13:33:18 +0200 Subject: [PATCH] Skip some untranslatable code blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This builds on the work of @dyoo in /~https://github.com/google/mdbook-i18n-helpers/pull/69: by adding a special `` comment, we can skip the following code block. I also modified a few code blocks to remove translatable text: variable names are not expected to be translated, so it’s fine to have a line with `println!("foo: {foo}")` in the code block. Part of #1257. --- src/basic-syntax/compound-types.md | 6 ++++-- src/basic-syntax/functions.md | 1 + src/basic-syntax/references-dangling.md | 1 + src/basic-syntax/references.md | 1 + src/basic-syntax/scalar-types.md | 2 ++ src/basic-syntax/scopes-shadowing.md | 1 + src/basic-syntax/slices.md | 1 + src/basic-syntax/static-and-const.md | 3 ++- src/basic-syntax/type-inference.md | 2 ++ src/basic-syntax/variables.md | 1 + src/control-flow/blocks.md | 4 +++- src/control-flow/break-continue.md | 1 + src/control-flow/for-expressions.md | 1 + src/control-flow/if-let-expressions.md | 1 + src/control-flow/loop-expressions.md | 3 ++- src/control-flow/while-expressions.md | 3 ++- src/control-flow/while-let-expressions.md | 1 + src/enums/sizes.md | 13 +++++++------ src/exercises/day-1/for-loops.md | 2 ++ src/exercises/day-1/implicit-conversions.md | 1 + src/memory-management/scope-based.md | 1 + src/ownership.md | 1 + src/ownership/borrowing.md | 2 ++ src/ownership/copy-clone.md | 2 ++ src/ownership/lifetimes-function-calls.md | 6 ++++-- src/ownership/moved-strings-rust.md | 1 + src/ownership/shared-unique-borrows.md | 1 + 27 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/basic-syntax/compound-types.md b/src/basic-syntax/compound-types.md index 9b66f5920b26..5502fabe4533 100644 --- a/src/basic-syntax/compound-types.md +++ b/src/basic-syntax/compound-types.md @@ -7,6 +7,7 @@ Array assignment and access: + ```rust,editable fn main() { let mut a: [i8; 10] = [42; 10]; @@ -17,11 +18,12 @@ fn main() { Tuple assignment and access: + ```rust,editable fn main() { let t: (i8, bool) = (7, true); - println!("1st index: {}", t.0); - println!("2nd index: {}", t.1); + println!("t.0: {}", t.0); + println!("t.1: {}", t.1); } ``` diff --git a/src/basic-syntax/functions.md b/src/basic-syntax/functions.md index 3858f5e92a78..603c9fb56f16 100644 --- a/src/basic-syntax/functions.md +++ b/src/basic-syntax/functions.md @@ -2,6 +2,7 @@ A Rust version of the famous [FizzBuzz](https://en.wikipedia.org/wiki/Fizz_buzz) interview question: + ```rust,editable fn main() { print_fizzbuzz_to(20); diff --git a/src/basic-syntax/references-dangling.md b/src/basic-syntax/references-dangling.md index deb8c18b8a78..a6115c1b90c4 100644 --- a/src/basic-syntax/references-dangling.md +++ b/src/basic-syntax/references-dangling.md @@ -2,6 +2,7 @@ Rust will statically forbid dangling references: + ```rust,editable,compile_fail fn main() { let ref_x: &i32; diff --git a/src/basic-syntax/references.md b/src/basic-syntax/references.md index b03fd6316f4f..727dedec40fc 100644 --- a/src/basic-syntax/references.md +++ b/src/basic-syntax/references.md @@ -2,6 +2,7 @@ Like C++, Rust has references: + ```rust,editable fn main() { let mut x: i32 = 10; diff --git a/src/basic-syntax/scalar-types.md b/src/basic-syntax/scalar-types.md index 059de2bc40e4..65bc2f45881f 100644 --- a/src/basic-syntax/scalar-types.md +++ b/src/basic-syntax/scalar-types.md @@ -24,6 +24,7 @@ There are a few syntaxes which are not shown above: == "\\\\n"`. You can embed double-quotes by using an equal amount of `#` on either side of the quotes: + ```rust,editable fn main() { println!(r#"link"#); @@ -33,6 +34,7 @@ There are a few syntaxes which are not shown above: - Byte strings allow you to create a `&[u8]` value directly: + ```rust,editable fn main() { println!("{:?}", b"abc"); diff --git a/src/basic-syntax/scopes-shadowing.md b/src/basic-syntax/scopes-shadowing.md index 2009178b11e2..ba9c7e3a3147 100644 --- a/src/basic-syntax/scopes-shadowing.md +++ b/src/basic-syntax/scopes-shadowing.md @@ -27,6 +27,7 @@ fn main() { * Shadowing looks obscure at first, but is convenient for holding on to values after `.unwrap()`. * The following code demonstrates why the compiler can't simply reuse memory locations when shadowing an immutable variable in a scope, even if the type does not change. + ```rust,editable fn main() { let a = 1; diff --git a/src/basic-syntax/slices.md b/src/basic-syntax/slices.md index edab4573bb78..48d63d6c3eb8 100644 --- a/src/basic-syntax/slices.md +++ b/src/basic-syntax/slices.md @@ -2,6 +2,7 @@ A slice gives you a view into a larger collection: + ```rust,editable fn main() { let mut a: [i32; 6] = [10, 20, 30, 40, 50, 60]; diff --git a/src/basic-syntax/static-and-const.md b/src/basic-syntax/static-and-const.md index 2d437302d22b..2fbd3f5c0bda 100644 --- a/src/basic-syntax/static-and-const.md +++ b/src/basic-syntax/static-and-const.md @@ -8,6 +8,7 @@ cannot be moved or reallocated during the execution of the program. Constant variables are evaluated at compile time and their values are inlined wherever they are used: + ```rust,editable const DIGEST_SIZE: usize = 3; const ZERO: Option = Some(42); @@ -22,7 +23,7 @@ fn compute_digest(text: &str) -> [u8; DIGEST_SIZE] { fn main() { let digest = compute_digest("Hello"); - println!("Digest: {digest:?}"); + println!("digest: {digest:?}"); } ``` diff --git a/src/basic-syntax/type-inference.md b/src/basic-syntax/type-inference.md index 526e3b21a661..30fa3566d5b0 100644 --- a/src/basic-syntax/type-inference.md +++ b/src/basic-syntax/type-inference.md @@ -2,6 +2,7 @@ Rust will look at how the variable is _used_ to determine the type: + ```rust,editable fn takes_u32(x: u32) { println!("u32: {x}"); @@ -31,6 +32,7 @@ The compiler does the job for us and helps us write more concise code. The following code tells the compiler to copy into a certain generic container without the code ever explicitly specifying the contained type, using `_` as a placeholder: + ```rust,editable fn main() { let mut v = Vec::new(); diff --git a/src/basic-syntax/variables.md b/src/basic-syntax/variables.md index 82ec653a0529..f2fd2f7ebb63 100644 --- a/src/basic-syntax/variables.md +++ b/src/basic-syntax/variables.md @@ -3,6 +3,7 @@ Rust provides type safety via static typing. Variable bindings are immutable by default: + ```rust,editable fn main() { let x: i32 = 10; diff --git a/src/control-flow/blocks.md b/src/control-flow/blocks.md index c734837d7d9b..c9a19d0c3cf3 100644 --- a/src/control-flow/blocks.md +++ b/src/control-flow/blocks.md @@ -4,6 +4,7 @@ A block in Rust contains a sequence of expressions. Each block has a value and a type, which are those of the last expression of the block: + ```rust,editable fn main() { let x = { @@ -28,13 +29,14 @@ If the last expression ends with `;`, then the resulting value and type is `()`. The same rule is used for functions: the value of the function body is the return value: + ```rust,editable fn double(x: i32) -> i32 { x + x } fn main() { - println!("doubled: {}", double(7)); + println!("double: {}", double(7)); } ``` diff --git a/src/control-flow/break-continue.md b/src/control-flow/break-continue.md index aac48a4ca05d..1b562dc3f0ac 100644 --- a/src/control-flow/break-continue.md +++ b/src/control-flow/break-continue.md @@ -7,6 +7,7 @@ the next iteration use [`continue`](https://doc.rust-lang.org/reference/expressi Both `continue` and `break` can optionally take a label argument which is used to break out of nested loops: + ```rust,editable fn main() { let v = vec![10, 20, 30]; diff --git a/src/control-flow/for-expressions.md b/src/control-flow/for-expressions.md index e6ae73eae743..61a42a2f4bfa 100644 --- a/src/control-flow/for-expressions.md +++ b/src/control-flow/for-expressions.md @@ -4,6 +4,7 @@ The [`for` loop](https://doc.rust-lang.org/std/keyword.for.html) is closely related to the [`while let` loop](while-let-expressions.md). It will automatically call `into_iter()` on the expression and then iterate over it: + ```rust,editable fn main() { let v = vec![10, 20, 30]; diff --git a/src/control-flow/if-let-expressions.md b/src/control-flow/if-let-expressions.md index c84cc38c21cb..a03a6207dc8c 100644 --- a/src/control-flow/if-let-expressions.md +++ b/src/control-flow/if-let-expressions.md @@ -25,6 +25,7 @@ Rust. * Unlike `match`, `if let` does not support guard clauses for pattern matching. * Since 1.65, a similar [let-else](https://doc.rust-lang.org/rust-by-example/flow_control/let_else.html) construct allows to do a destructuring assignment, or if it fails, execute a block which is required to abort normal control flow (with `panic`/`return`/`break`/`continue`): + ```rust,editable fn main() { println!("{:?}", second_word_to_upper("foo bar")); diff --git a/src/control-flow/loop-expressions.md b/src/control-flow/loop-expressions.md index faaecdb4f951..3a92b1dd6d06 100644 --- a/src/control-flow/loop-expressions.md +++ b/src/control-flow/loop-expressions.md @@ -5,6 +5,7 @@ which creates an endless loop. Here you must either `break` or `return` to stop the loop: + ```rust,editable fn main() { let mut x = 10; @@ -18,7 +19,7 @@ fn main() { break; } } - println!("Final x: {x}"); + println!("x: {x}"); } ``` diff --git a/src/control-flow/while-expressions.md b/src/control-flow/while-expressions.md index 1ad351e4cbc0..fc3f267f9606 100644 --- a/src/control-flow/while-expressions.md +++ b/src/control-flow/while-expressions.md @@ -3,6 +3,7 @@ The [`while` keyword](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-loops) works very similar to other languages: + ```rust,editable fn main() { let mut x = 10; @@ -13,7 +14,7 @@ fn main() { 3 * x + 1 }; } - println!("Final x: {x}"); + println!("x: {x}"); } ``` diff --git a/src/control-flow/while-let-expressions.md b/src/control-flow/while-let-expressions.md index a93883c9b134..98b17687197c 100644 --- a/src/control-flow/while-let-expressions.md +++ b/src/control-flow/while-let-expressions.md @@ -3,6 +3,7 @@ Like with `if let`, there is a [`while let`](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-pattern-loops) variant which repeatedly tests a value against a pattern: + ```rust,editable fn main() { let v = vec![10, 20, 30]; diff --git a/src/enums/sizes.md b/src/enums/sizes.md index 1c94b0bd68f4..ae04c08af85b 100644 --- a/src/enums/sizes.md +++ b/src/enums/sizes.md @@ -31,6 +31,7 @@ Key Points: * You can control the discriminant if needed (e.g., for compatibility with C): + ```rust,editable #[repr(u32)] enum Bar { @@ -67,6 +68,7 @@ Key Points: Example code if you want to show how the bitwise representation *may* look like in practice. It's important to note that the compiler provides no guarantees regarding this representation, therefore this is totally unsafe. + ```rust,editable use std::mem::transmute; @@ -77,25 +79,23 @@ Key Points: } fn main() { - // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise - // representation of types. unsafe { - println!("Bitwise representation of bool"); + println!("bool:"); dbg_bits!(false, u8); dbg_bits!(true, u8); - println!("Bitwise representation of Option"); + println!("Option:"); dbg_bits!(None::, u8); dbg_bits!(Some(false), u8); dbg_bits!(Some(true), u8); - println!("Bitwise representation of Option>"); + println!("Option>:"); dbg_bits!(Some(Some(false)), u8); dbg_bits!(Some(Some(true)), u8); dbg_bits!(Some(None::), u8); dbg_bits!(None::>, u8); - println!("Bitwise representation of Option<&i32>"); + println!("Option<&i32>:"); dbg_bits!(None::<&i32>, usize); dbg_bits!(Some(&0i32), usize); } @@ -104,6 +104,7 @@ Key Points: More complex example if you want to discuss what happens when we chain more than 256 `Option`s together. + ```rust,editable #![recursion_limit = "1000"] diff --git a/src/exercises/day-1/for-loops.md b/src/exercises/day-1/for-loops.md index c1bfa69e03f7..994f611e8a46 100644 --- a/src/exercises/day-1/for-loops.md +++ b/src/exercises/day-1/for-loops.md @@ -8,6 +8,7 @@ let array = [10, 20, 30]; You can print such an array by asking for its debug representation with `{:?}`: + ```rust,editable fn main() { let array = [10, 20, 30]; @@ -38,6 +39,7 @@ fn main() { Use the above to write a function `pretty_print` which pretty-print a matrix and a function `transpose` which will transpose a matrix (turn rows into columns): + ```bob ⎛⎡1 2 3⎤⎞ ⎡1 4 7⎤ "transpose"⎜⎢4 5 6⎥⎟ "=="⎢2 5 8⎥ diff --git a/src/exercises/day-1/implicit-conversions.md b/src/exercises/day-1/implicit-conversions.md index c2fe972ac54c..9c69dd77d352 100644 --- a/src/exercises/day-1/implicit-conversions.md +++ b/src/exercises/day-1/implicit-conversions.md @@ -3,6 +3,7 @@ Rust will not automatically apply _implicit conversions_ between types ([unlike C++][3]). You can see this in a program like this: + ```rust,editable,compile_fail fn multiply(x: i16, y: i16) -> i16 { x * y diff --git a/src/memory-management/scope-based.md b/src/memory-management/scope-based.md index 3cbf34b56c46..20f3eb4e4999 100644 --- a/src/memory-management/scope-based.md +++ b/src/memory-management/scope-based.md @@ -24,6 +24,7 @@ void say_hello(std::unique_ptr person) { Special move constructors are used when passing ownership to a function: + ```c++ std::unique_ptr person = find_person("Carla"); say_hello(std::move(person)); diff --git a/src/ownership.md b/src/ownership.md index db7830140b0d..47dd62e0a423 100644 --- a/src/ownership.md +++ b/src/ownership.md @@ -3,6 +3,7 @@ All variable bindings have a _scope_ where they are valid and it is an error to use a variable outside its scope: + ```rust,editable,compile_fail struct Point(i32, i32); diff --git a/src/ownership/borrowing.md b/src/ownership/borrowing.md index 767c6dd2c435..c88c154d3b99 100644 --- a/src/ownership/borrowing.md +++ b/src/ownership/borrowing.md @@ -3,6 +3,7 @@ Instead of transferring ownership when calling a function, you can let a function _borrow_ the value: + ```rust,editable #[derive(Debug)] struct Point(i32, i32); @@ -27,6 +28,7 @@ fn main() { Notes on stack returns: * Demonstrate that the return from `add` is cheap because the compiler can eliminate the copy operation. Change the above code to print stack addresses and run it on the [Playground] or look at the assembly in [Godbolt](https://rust.godbolt.org/). In the "DEBUG" optimization level, the addresses should change, while they stay the same when changing to the "RELEASE" setting: + ```rust,editable #[derive(Debug)] struct Point(i32, i32); diff --git a/src/ownership/copy-clone.md b/src/ownership/copy-clone.md index 43b7c69a0866..4a8ccb5484f1 100644 --- a/src/ownership/copy-clone.md +++ b/src/ownership/copy-clone.md @@ -2,6 +2,7 @@ While move semantics are the default, certain types are copied by default: + ```rust,editable fn main() { let x = 42; @@ -15,6 +16,7 @@ These types implement the `Copy` trait. You can opt-in your own types to use copy semantics: + ```rust,editable #[derive(Copy, Clone, Debug)] struct Point(i32, i32); diff --git a/src/ownership/lifetimes-function-calls.md b/src/ownership/lifetimes-function-calls.md index 43bbc5ef857c..24d9c1989f34 100644 --- a/src/ownership/lifetimes-function-calls.md +++ b/src/ownership/lifetimes-function-calls.md @@ -2,6 +2,7 @@ In addition to borrowing its arguments, a function can return a borrowed value: + ```rust,editable #[derive(Debug)] struct Point(i32, i32); @@ -14,7 +15,7 @@ fn main() { let p1: Point = Point(10, 10); let p2: Point = Point(20, 20); let p3: &Point = left_most(&p1, &p2); - println!("left-most point: {:?}", p3); + println!("p3: {p3:?}"); } ``` @@ -29,6 +30,7 @@ fn main() { In the above example, try the following: * Move the declaration of `p2` and `p3` into a new scope (`{ ... }`), resulting in the following code: + ```rust,ignore #[derive(Debug)] struct Point(i32, i32); @@ -44,7 +46,7 @@ In the above example, try the following: let p2: Point = Point(20, 20); p3 = left_most(&p1, &p2); } - println!("left-most point: {:?}", p3); + println!("p3: {p3:?}"); } ``` Note how this does not compile since `p3` outlives `p2`. diff --git a/src/ownership/moved-strings-rust.md b/src/ownership/moved-strings-rust.md index b3c0659244df..b33c7bf8fc76 100644 --- a/src/ownership/moved-strings-rust.md +++ b/src/ownership/moved-strings-rust.md @@ -1,5 +1,6 @@ # Moved Strings in Rust + ```rust,editable fn main() { let s1: String = String::from("Rust"); diff --git a/src/ownership/shared-unique-borrows.md b/src/ownership/shared-unique-borrows.md index 6c8419b55487..57c48e0255e0 100644 --- a/src/ownership/shared-unique-borrows.md +++ b/src/ownership/shared-unique-borrows.md @@ -5,6 +5,7 @@ Rust puts constraints on the ways you can borrow values: * You can have one or more `&T` values at any given time, _or_ * You can have exactly one `&mut T` value. + ```rust,editable,compile_fail fn main() { let mut a: i32 = 10;