diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:32 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:32 +0000 |
commit | 4547b622d8d29df964fa2914213088b148c498fc (patch) | |
tree | 9fc6b25f3c3add6b745be9a2400a6e96140046e9 /src/doc | |
parent | Releasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz rustc-4547b622d8d29df964fa2914213088b148c498fc.zip |
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
137 files changed, 1306 insertions, 902 deletions
diff --git a/src/doc/book/.github/ISSUE_TEMPLATE/bug_report.md b/src/doc/book/.github/ISSUE_TEMPLATE/bug_report.md index c1157112f..2423c4cd4 100644 --- a/src/doc/book/.github/ISSUE_TEMPLATE/bug_report.md +++ b/src/doc/book/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,8 +3,12 @@ name: Bug report about: Create a report to help us improve --- -- [ ] I have checked the latest `main` branch to see if this has already been fixed -- [ ] I have searched existing issues and pull requests for duplicates +- I have searched open and closed issues and pull requests for duplicates, using these search terms: + - + - + - +- I have checked the latest `main` branch to see if this has already been fixed, in this file: + - URL to the section(s) of the book with this problem: diff --git a/src/doc/book/.github/workflows/main.yml b/src/doc/book/.github/workflows/main.yml index d5b3249be..64ab49c51 100644 --- a/src/doc/book/.github/workflows/main.yml +++ b/src/doc/book/.github/workflows/main.yml @@ -12,12 +12,12 @@ jobs: - name: Install Rust run: | rustup set profile minimal - rustup toolchain install 1.62 -c rust-docs - rustup default 1.62 + rustup toolchain install 1.65 -c rust-docs + rustup default 1.65 - name: Install mdbook run: | mkdir bin - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.14/mdbook-v0.4.14-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin echo "$(pwd)/bin" >> ${GITHUB_PATH} - name: Report versions run: | @@ -41,7 +41,7 @@ jobs: - name: Install mdbook run: | mkdir bin - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.14/mdbook-v0.4.14-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin echo "$(pwd)/bin" >> ${GITHUB_PATH} - name: Install aspell run: sudo apt-get install aspell diff --git a/src/doc/book/README.md b/src/doc/book/README.md index 91c64ce25..94e1a004a 100644 --- a/src/doc/book/README.md +++ b/src/doc/book/README.md @@ -30,7 +30,7 @@ rust-lang/rust uses in [this file][rust-mdbook]. To get it: [rust-mdbook]: https://github.com/rust-lang/rust/blob/master/src/tools/rustbook/Cargo.toml ```bash -$ cargo install mdbook --vers [version-num] +$ cargo install mdbook --version <version_num> ``` ## Building diff --git a/src/doc/book/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt b/src/doc/book/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt index fbc0cec33..70a0c930c 100644 --- a/src/doc/book/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt +++ b/src/doc/book/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt @@ -11,10 +11,13 @@ error[E0308]: mismatched types --> src/main.rs:22:21 | 22 | match guess.cmp(&secret_number) { - | ^^^^^^^^^^^^^^ expected struct `String`, found integer + | --- ^^^^^^^^^^^^^^ expected struct `String`, found integer + | | + | arguments to this function are incorrect | = note: expected reference `&String` found reference `&{integer}` +note: associated function defined here For more information about this error, try `rustc --explain E0308`. error: could not compile `guessing_game` due to previous error diff --git a/src/doc/book/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt b/src/doc/book/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt index a5a85f4f6..6ae56e09d 100644 --- a/src/doc/book/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt +++ b/src/doc/book/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt @@ -1,5 +1,11 @@ $ cargo run Compiling functions v0.1.0 (file:///projects/functions) +error: expected expression, found `let` statement + --> src/main.rs:2:14 + | +2 | let x = (let y = 6); + | ^^^ + error: expected expression, found statement (`let`) --> src/main.rs:2:14 | @@ -27,8 +33,8 @@ help: remove these parentheses | 2 - let x = (let y = 6); 2 + let x = let y = 6; - | + | For more information about this error, try `rustc --explain E0658`. warning: `functions` (bin "functions") generated 1 warning -error: could not compile `functions` due to 2 previous errors; 1 warning emitted +error: could not compile `functions` due to 3 previous errors; 1 warning emitted diff --git a/src/doc/book/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt b/src/doc/book/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt index d9807cee0..8a11cccd5 100644 --- a/src/doc/book/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt +++ b/src/doc/book/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt @@ -4,7 +4,12 @@ error[E0282]: type annotations needed --> src/main.rs:2:9 | 2 | let guess = "42".parse().expect("Not a number!"); - | ^^^^^ consider giving `guess` a type + | ^^^^^ + | +help: consider giving `guess` an explicit type + | +2 | let guess: _ = "42".parse().expect("Not a number!"); + | +++ For more information about this error, try `rustc --explain E0282`. error: could not compile `no_type_annotations` due to previous error diff --git a/src/doc/book/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt b/src/doc/book/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt index 6435eeb44..05987f7c8 100644 --- a/src/doc/book/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt +++ b/src/doc/book/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt @@ -7,11 +7,11 @@ error[E0382]: borrow of moved value: `s1` | -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait 3 | let s2 = s1; | -- value moved here -4 | +4 | 5 | println!("{}, world!", s1); | ^^ value borrowed here after move | - = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) For more information about this error, try `rustc --explain E0382`. error: could not compile `ownership` due to previous error diff --git a/src/doc/book/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt b/src/doc/book/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt index 71c29f68f..8820d2d69 100644 --- a/src/doc/book/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt +++ b/src/doc/book/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt @@ -7,7 +7,7 @@ error[E0499]: cannot borrow `s` as mutable more than once at a time | ------ first mutable borrow occurs here 5 | let r2 = &mut s; | ^^^^^^ second mutable borrow occurs here -6 | +6 | 7 | println!("{}, {}", r1, r2); | -- first borrow later used here diff --git a/src/doc/book/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt b/src/doc/book/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt index df94c30e9..d1e9db2c4 100644 --- a/src/doc/book/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt +++ b/src/doc/book/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt @@ -8,7 +8,7 @@ error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immuta 5 | let r2 = &s; // no problem 6 | let r3 = &mut s; // BIG PROBLEM | ^^^^^^ mutable borrow occurs here -7 | +7 | 8 | println!("{}, {}, and {}", r1, r2, r3); | -- immutable borrow later used here diff --git a/src/doc/book/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt b/src/doc/book/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt index fddca683b..b466a3dce 100644 --- a/src/doc/book/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt +++ b/src/doc/book/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt @@ -10,7 +10,7 @@ error[E0106]: missing lifetime specifier help: consider using the `'static` lifetime | 5 | fn dangle() -> &'static String { - | ~~~~~~~~ + | +++++++ For more information about this error, try `rustc --explain E0106`. error: could not compile `ownership` due to previous error diff --git a/src/doc/book/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt b/src/doc/book/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt index 62dc4ad52..ab0c41f4d 100644 --- a/src/doc/book/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt +++ b/src/doc/book/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt @@ -5,10 +5,10 @@ error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immuta | 16 | let word = first_word(&s); | -- immutable borrow occurs here -17 | +17 | 18 | s.clear(); // error! | ^^^^^^^^^ mutable borrow occurs here -19 | +19 | 20 | println!("the first word is: {}", word); | ---- immutable borrow later used here diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs index e0f7a6cd3..122d25164 100644 --- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs +++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs @@ -8,9 +8,9 @@ struct User { // ANCHOR: here fn main() { let user1 = User { - email: String::from("someone@example.com"), - username: String::from("someusername123"), active: true, + username: String::from("someusername123"), + email: String::from("someone@example.com"), sign_in_count: 1, }; } diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs index 7a078e7e8..35eea8a9a 100644 --- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs +++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs @@ -8,9 +8,9 @@ struct User { // ANCHOR: here fn main() { let mut user1 = User { - email: String::from("someone@example.com"), - username: String::from("someusername123"), active: true, + username: String::from("someusername123"), + email: String::from("someone@example.com"), sign_in_count: 1, }; diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs index aa7823af4..8614561c1 100644 --- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs +++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs @@ -8,9 +8,9 @@ struct User { // ANCHOR: here fn build_user(email: String, username: String) -> User { User { - email: email, - username: username, active: true, + username: username, + email: email, sign_in_count: 1, } } diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs index 8d84a3060..c893c86a9 100644 --- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs +++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs @@ -8,9 +8,9 @@ struct User { // ANCHOR: here fn build_user(email: String, username: String) -> User { User { - email, - username, active: true, + username, + email, sign_in_count: 1, } } diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt index b761fccd6..7d3bfcdac 100644 --- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt +++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt @@ -8,7 +8,7 @@ error[E0277]: `Rectangle` doesn't implement `std::fmt::Display` | = help: the trait `std::fmt::Display` is not implemented for `Rectangle` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) For more information about this error, try `rustc --explain E0277`. error: could not compile `rectangles` due to previous error diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt index 69c8b38a6..58cb842bf 100644 --- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt +++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt @@ -8,7 +8,7 @@ error[E0277]: `Rectangle` doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `Rectangle` = note: add `#[derive(Debug)]` to `Rectangle` or manually `impl Debug for Rectangle` - = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Rectangle` with `#[derive(Debug)]` | 1 | #[derive(Debug)] diff --git a/src/doc/book/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt b/src/doc/book/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt index c5a6c51bb..bec72849a 100644 --- a/src/doc/book/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt +++ b/src/doc/book/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt @@ -1,18 +1,18 @@ $ cargo run Compiling enums v0.1.0 (file:///projects/enums) error[E0004]: non-exhaustive patterns: `None` not covered - --> src/main.rs:3:15 - | -3 | match x { - | ^ pattern `None` not covered - | + --> src/main.rs:3:15 + | +3 | match x { + | ^ pattern `None` not covered + | note: `Option<i32>` defined here - = note: the matched value is of type `Option<i32>` + = note: the matched value is of type `Option<i32>` help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -4 ~ Some(i) => Some(i + 1), -5 ~ None => todo!(), - | + | +4 ~ Some(i) => Some(i + 1), +5 ~ None => todo!(), + | For more information about this error, try `rustc --explain E0004`. error: could not compile `enums` due to previous error diff --git a/src/doc/book/listings/ch08-common-collections/listing-08-06/output.txt b/src/doc/book/listings/ch08-common-collections/listing-08-06/output.txt index ab512a9e6..3104205f3 100644 --- a/src/doc/book/listings/ch08-common-collections/listing-08-06/output.txt +++ b/src/doc/book/listings/ch08-common-collections/listing-08-06/output.txt @@ -5,12 +5,12 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immuta | 4 | let first = &v[0]; | - immutable borrow occurs here -5 | +5 | 6 | v.push(6); | ^^^^^^^^^ mutable borrow occurs here -7 | -8 | println!("The first element is: {}", first); - | ----- immutable borrow later used here +7 | +8 | println!("The first element is: {first}"); + | ----- immutable borrow later used here For more information about this error, try `rustc --explain E0502`. error: could not compile `collections` due to previous error diff --git a/src/doc/book/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt b/src/doc/book/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt index 98d1f183a..35db879c9 100644 --- a/src/doc/book/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt +++ b/src/doc/book/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt @@ -2,5 +2,5 @@ $ cargo run Compiling collections v0.1.0 (file:///projects/collections) Finished dev [unoptimized + debuginfo] target(s) in 0.43s Running `target/debug/collections` -thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside 'З' (bytes 0..2) of `Здравствуйте`', library/core/src/str/mod.rs:127:5 +thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside 'З' (bytes 0..2) of `Здравствуйте`', src/main.rs:4:14 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/src/doc/book/listings/ch09-error-handling/listing-09-10/output.txt b/src/doc/book/listings/ch09-error-handling/listing-09-10/output.txt index 26e4ff8cc..75b9cf2e3 100644 --- a/src/doc/book/listings/ch09-error-handling/listing-09-10/output.txt +++ b/src/doc/book/listings/ch09-error-handling/listing-09-10/output.txt @@ -3,11 +3,10 @@ $ cargo run error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) --> src/main.rs:4:48 | -3 | / fn main() { -4 | | let greeting_file = File::open("hello.txt")?; - | | ^ cannot use the `?` operator in a function that returns `()` -5 | | } - | |_- this function should return `Result` or `Option` to accept `?` +3 | fn main() { + | --------- this function should return `Result` or `Option` to accept `?` +4 | let greeting_file = File::open("hello.txt")?; + | ^ cannot use the `?` operator in a function that returns `()` | = help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()` diff --git a/src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt b/src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt index b63bf83a1..ad7327209 100644 --- a/src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt +++ b/src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt @@ -7,7 +7,7 @@ error[E0597]: `x` does not live long enough | ^^ borrowed value does not live long enough 7 | } | - `x` dropped here while still borrowed -8 | +8 | 9 | println!("r: {}", r); | - borrow later used here diff --git a/src/doc/book/listings/ch11-writing-automated-tests/listing-11-03/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/listing-11-03/output.txt index 0c2fd0327..2fa5cf077 100644 --- a/src/doc/book/listings/ch11-writing-automated-tests/listing-11-03/output.txt +++ b/src/doc/book/listings/ch11-writing-automated-tests/listing-11-03/output.txt @@ -19,4 +19,4 @@ failures: test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch11-writing-automated-tests/listing-11-10/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/listing-11-10/output.txt index 0512cd59f..681cfbb81 100644 --- a/src/doc/book/listings/ch11-writing-automated-tests/listing-11-10/output.txt +++ b/src/doc/book/listings/ch11-writing-automated-tests/listing-11-10/output.txt @@ -22,4 +22,4 @@ failures: test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt index fdeb597e3..7c62822f7 100644 --- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt +++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt @@ -19,4 +19,4 @@ failures: test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt index 0af0401e3..28e2414be 100644 --- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt +++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt @@ -20,4 +20,4 @@ failures: test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt index 3049543a7..3366e3ace 100644 --- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt +++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt @@ -18,4 +18,4 @@ failures: test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt index d2ba1961b..cebebdaee 100644 --- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt +++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt @@ -18,4 +18,4 @@ failures: test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt index f59dddec4..9318d4ce0 100644 --- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt +++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt @@ -16,4 +16,4 @@ failures: test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt index c8cba98fe..c176e88b8 100644 --- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt +++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt @@ -20,4 +20,4 @@ failures: test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt index 8caaeda06..4ececf245 100644 --- a/src/doc/book/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt +++ b/src/doc/book/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt @@ -31,4 +31,4 @@ failures: test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch12-an-io-project/listing-12-16/output.txt b/src/doc/book/listings/ch12-an-io-project/listing-12-16/output.txt index d0cda6024..3c34e3945 100644 --- a/src/doc/book/listings/ch12-an-io-project/listing-12-16/output.txt +++ b/src/doc/book/listings/ch12-an-io-project/listing-12-16/output.txt @@ -20,4 +20,4 @@ failures: test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch13-functional-features/listing-13-03/output.txt b/src/doc/book/listings/ch13-functional-features/listing-13-03/output.txt index 37d83618a..68838deff 100644 --- a/src/doc/book/listings/ch13-functional-features/listing-13-03/output.txt +++ b/src/doc/book/listings/ch13-functional-features/listing-13-03/output.txt @@ -4,9 +4,16 @@ error[E0308]: mismatched types --> src/main.rs:5:29 | 5 | let n = example_closure(5); - | ^- help: try using a conversion method: `.to_string()` - | | - | expected struct `String`, found integer + | --------------- ^- help: try using a conversion method: `.to_string()` + | | | + | | expected struct `String`, found integer + | arguments to this function are incorrect + | +note: closure parameter defined here + --> src/main.rs:2:28 + | +2 | let example_closure = |x| x; + | ^ For more information about this error, try `rustc --explain E0308`. error: could not compile `closure-example` due to previous error diff --git a/src/doc/book/listings/ch13-functional-features/listing-13-08/output.txt b/src/doc/book/listings/ch13-functional-features/listing-13-08/output.txt index 7a39ac618..a91053766 100644 --- a/src/doc/book/listings/ch13-functional-features/listing-13-08/output.txt +++ b/src/doc/book/listings/ch13-functional-features/listing-13-08/output.txt @@ -3,16 +3,13 @@ $ cargo run error[E0507]: cannot move out of `value`, a captured variable in an `FnMut` closure --> src/main.rs:18:30 | -15 | let value = String::from("by key called"); - | ----- captured outer variable -16 | -17 | list.sort_by_key(|r| { - | ______________________- -18 | | sort_operations.push(value); - | | ^^^^^ move occurs because `value` has type `String`, which does not implement the `Copy` trait -19 | | r.width -20 | | }); - | |_____- captured by this `FnMut` closure +15 | let value = String::from("by key called"); + | ----- captured outer variable +16 | +17 | list.sort_by_key(|r| { + | --- captured by this `FnMut` closure +18 | sort_operations.push(value); + | ^^^^^ move occurs because `value` has type `String`, which does not implement the `Copy` trait For more information about this error, try `rustc --explain E0507`. error: could not compile `rectangles` due to previous error diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt index 437d74b5c..d5522cd53 100644 --- a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt @@ -13,15 +13,5 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` repre 2 | Cons(i32, Box<List>), | ++++ + -error[E0391]: cycle detected when computing drop-check constraints for `List` - --> src/main.rs:1:1 - | -1 | enum List { - | ^^^^^^^^^ - | - = note: ...which immediately requires computing drop-check constraints for `List` again - = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, constness: NotConst }, value: List } }` - -Some errors have detailed explanations: E0072, E0391. -For more information about an error, try `rustc --explain E0072`. -error: could not compile `cons-list` due to 2 previous errors +For more information about this error, try `rustc --explain E0072`. +error: could not compile `cons-list` due to previous error diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt index c44e69f13..3749c845c 100644 --- a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt @@ -18,4 +18,4 @@ failures: test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` diff --git a/src/doc/book/listings/ch16-fearless-concurrency/listing-16-09/output.txt b/src/doc/book/listings/ch16-fearless-concurrency/listing-16-09/output.txt index 0795a3a4f..db8518537 100644 --- a/src/doc/book/listings/ch16-fearless-concurrency/listing-16-09/output.txt +++ b/src/doc/book/listings/ch16-fearless-concurrency/listing-16-09/output.txt @@ -10,7 +10,7 @@ error[E0382]: borrow of moved value: `val` 10 | println!("val is {}", val); | ^^^ value borrowed here after move | - = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) For more information about this error, try `rustc --explain E0382`. error: could not compile `message-passing` due to previous error diff --git a/src/doc/book/listings/ch16-fearless-concurrency/listing-16-14/output.txt b/src/doc/book/listings/ch16-fearless-concurrency/listing-16-14/output.txt index 9546e1e48..0634b86e5 100644 --- a/src/doc/book/listings/ch16-fearless-concurrency/listing-16-14/output.txt +++ b/src/doc/book/listings/ch16-fearless-concurrency/listing-16-14/output.txt @@ -1,20 +1,26 @@ $ cargo run Compiling shared-state v0.1.0 (file:///projects/shared-state) error[E0277]: `Rc<Mutex<i32>>` cannot be sent between threads safely - --> src/main.rs:11:22 - | -11 | let handle = thread::spawn(move || { - | ______________________^^^^^^^^^^^^^_- - | | | - | | `Rc<Mutex<i32>>` cannot be sent between threads safely -12 | | let mut num = counter.lock().unwrap(); -13 | | -14 | | *num += 1; -15 | | }); - | |_________- within this `[closure@src/main.rs:11:36: 15:10]` - | - = help: within `[closure@src/main.rs:11:36: 15:10]`, the trait `Send` is not implemented for `Rc<Mutex<i32>>` - = note: required because it appears within the type `[closure@src/main.rs:11:36: 15:10]` + --> src/main.rs:11:36 + | +11 | let handle = thread::spawn(move || { + | ------------- ^------ + | | | + | ______________________|_____________within this `[closure@src/main.rs:11:36: 11:43]` + | | | + | | required by a bound introduced by this call +12 | | let mut num = counter.lock().unwrap(); +13 | | +14 | | *num += 1; +15 | | }); + | |_________^ `Rc<Mutex<i32>>` cannot be sent between threads safely + | + = help: within `[closure@src/main.rs:11:36: 11:43]`, the trait `Send` is not implemented for `Rc<Mutex<i32>>` +note: required because it's used within this closure + --> src/main.rs:11:36 + | +11 | let handle = thread::spawn(move || { + | ^^^^^^^ note: required by a bound in `spawn` For more information about this error, try `rustc --explain E0277`. diff --git a/src/doc/book/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt b/src/doc/book/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt index f7be53b9a..301a9a44a 100644 --- a/src/doc/book/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt +++ b/src/doc/book/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt @@ -5,7 +5,7 @@ error[E0382]: use of moved value: `v` | 4 | let v = vec![1, 2, 3]; | - move occurs because `v` has type `Vec<i32>`, which does not implement the `Copy` trait -5 | +5 | 6 | let handle = thread::spawn(move || { | ------- value moved into closure here 7 | println!("Here's a vector: {:?}", v); diff --git a/src/doc/book/listings/ch17-oop/listing-17-10/output.txt b/src/doc/book/listings/ch17-oop/listing-17-10/output.txt index 74330fa0a..e0a455f3b 100644 --- a/src/doc/book/listings/ch17-oop/listing-17-10/output.txt +++ b/src/doc/book/listings/ch17-oop/listing-17-10/output.txt @@ -7,7 +7,7 @@ error[E0277]: the trait bound `String: Draw` is not satisfied | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Draw` is not implemented for `String` | = help: the trait `Draw` is implemented for `Button` - = note: required for the cast to the object type `dyn Draw` + = note: required for the cast from `String` to the object type `dyn Draw` For more information about this error, try `rustc --explain E0277`. error: could not compile `gui` due to previous error diff --git a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-08/output.txt b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-08/output.txt index 72274d07c..0fd5373b8 100644 --- a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-08/output.txt +++ b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-08/output.txt @@ -1,19 +1,19 @@ $ cargo run Compiling patterns v0.1.0 (file:///projects/patterns) error[E0005]: refutable pattern in local binding: `None` not covered - --> src/main.rs:3:9 - | -3 | let Some(x) = some_option_value; - | ^^^^^^^ pattern `None` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + --> src/main.rs:3:9 + | +3 | let Some(x) = some_option_value; + | ^^^^^^^ pattern `None` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html note: `Option<i32>` defined here - = note: the matched value is of type `Option<i32>` + = note: the matched value is of type `Option<i32>` help: you might want to use `if let` to ignore the variant that isn't matched - | -3 | let x = if let Some(x) = some_option_value { x } else { todo!() }; - | ++++++++++ ++++++++++++++++++++++ + | +3 | let x = if let Some(x) = some_option_value { x } else { todo!() }; + | ++++++++++ ++++++++++++++++++++++ For more information about this error, try `rustc --explain E0005`. error: could not compile `patterns` due to previous error diff --git a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs index 4ddef0aaf..a3138b227 100644 --- a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs +++ b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs @@ -13,15 +13,13 @@ fn main() { println!("The Quit variant has no data to destructure."); } Message::Move { x, y } => { - println!( - "Move in the x direction {x} and in the y direction {y}" - ); + println!("Move in the x direction {x} and in the y direction {y}"); } Message::Write(text) => { println!("Text message: {text}"); } - Message::ChangeColor(r, g, b) => println!( - "Change the color to red {r}, green {g}, and blue {b}", - ), + Message::ChangeColor(r, g, b) => { + println!("Change the color to red {r}, green {g}, and blue {b}",) + } } } diff --git a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs index 4c958601b..1e7ad5f19 100644 --- a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs +++ b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs @@ -17,9 +17,9 @@ fn main() { Message::ChangeColor(Color::Rgb(r, g, b)) => { println!("Change color to red {r}, green {g}, and blue {b}"); } - Message::ChangeColor(Color::Hsv(h, s, v)) => println!( - "Change color to hue {h}, saturation {s}, value {v}" - ), + Message::ChangeColor(Color::Hsv(h, s, v)) => { + println!("Change color to hue {h}, saturation {s}, value {v}") + } _ => (), } } diff --git a/src/doc/book/listings/ch19-advanced-features/listing-19-20/output.txt b/src/doc/book/listings/ch19-advanced-features/listing-19-20/output.txt index 684508245..a3b281e3f 100644 --- a/src/doc/book/listings/ch19-advanced-features/listing-19-20/output.txt +++ b/src/doc/book/listings/ch19-advanced-features/listing-19-20/output.txt @@ -1,12 +1,18 @@ $ cargo run Compiling traits-example v0.1.0 (file:///projects/traits-example) -error[E0283]: type annotations needed +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> src/main.rs:20:43 | +2 | fn baby_name() -> String; + | ------------------------- `Animal::baby_name` defined here +... 20 | println!("A baby dog is called a {}", Animal::baby_name()); - | ^^^^^^^^^^^^^^^^^ cannot infer type + | ^^^^^^^^^^^^^^^^^ cannot call associated function of trait | - = note: cannot satisfy `_: Animal` +help: use the fully-qualified path to the only available implementation + | +20 | println!("A baby dog is called a {}", <::Dog as Animal>::baby_name()); + | +++++++++ + -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0790`. error: could not compile `traits-example` due to previous error diff --git a/src/doc/book/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt b/src/doc/book/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt index d6fffc967..104f2cf0f 100644 --- a/src/doc/book/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt +++ b/src/doc/book/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt @@ -7,7 +7,7 @@ error[E0746]: return type cannot have an unboxed trait object | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> -help: use `impl Fn(i32) -> i32` as the return type, as all return paths are of type `[closure@src/lib.rs:2:5: 2:14]`, which implements `Fn(i32) -> i32` +help: use `impl Fn(i32) -> i32` as the return type, as all return paths are of type `[closure@src/lib.rs:2:5: 2:8]`, which implements `Fn(i32) -> i32` | 1 | fn returns_closure() -> impl Fn(i32) -> i32 { | ~~~~~~~~~~~~~~~~~~~ diff --git a/src/doc/book/listings/ch20-web-server/listing-20-22/output.txt b/src/doc/book/listings/ch20-web-server/listing-20-22/output.txt index 4402092e9..a6c9e8d3b 100644 --- a/src/doc/book/listings/ch20-web-server/listing-20-22/output.txt +++ b/src/doc/book/listings/ch20-web-server/listing-20-22/output.txt @@ -1,13 +1,13 @@ $ cargo check Checking hello v0.1.0 (file:///projects/hello) error[E0507]: cannot move out of `worker.thread` which is behind a mutable reference - --> src/lib.rs:52:13 - | -52 | worker.thread.join().unwrap(); - | ^^^^^^^^^^^^^ ------ `worker.thread` moved due to this method call - | | - | move occurs because `worker.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait - | + --> src/lib.rs:52:13 + | +52 | worker.thread.join().unwrap(); + | ^^^^^^^^^^^^^ ------ `worker.thread` moved due to this method call + | | + | move occurs because `worker.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait + | note: this function takes ownership of the receiver `self`, which moves `worker.thread` For more information about this error, try `rustc --explain E0507`. diff --git a/src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt b/src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt index 34d30fe05..e4c0eeb2a 100644 --- a/src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt +++ b/src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt @@ -5,6 +5,12 @@ error[E0599]: no method named `join` found for enum `Option` in the current scop | 52 | worker.thread.join().unwrap(); | ^^^^ method not found in `Option<JoinHandle<()>>` + | +note: the method `join` exists on the type `JoinHandle<()>` +help: consider using `Option::expect` to unwrap the `JoinHandle<()>` value, panicking if the value is an `Option::None` + | +52 | worker.thread.expect("REASON").join().unwrap(); + | +++++++++++++++++ error[E0308]: mismatched types --> src/lib.rs:72:22 diff --git a/src/doc/book/rust-toolchain b/src/doc/book/rust-toolchain index 0a03ace41..5b6cd6b3c 100644 --- a/src/doc/book/rust-toolchain +++ b/src/doc/book/rust-toolchain @@ -1 +1 @@ -1.62 +1.65 diff --git a/src/doc/book/src/ch05-00-structs.md b/src/doc/book/src/ch05-00-structs.md index ff540b77d..d41482579 100644 --- a/src/doc/book/src/ch05-00-structs.md +++ b/src/doc/book/src/ch05-00-structs.md @@ -11,4 +11,4 @@ We’ll demonstrate how to define and instantiate structs. We’ll discuss how t define associated functions, especially the kind of associated functions called *methods*, to specify behavior associated with a struct type. Structs and enums (discussed in Chapter 6) are the building blocks for creating new types in your -program’s domain to take full advantage of Rust’s compile time type checking. +program’s domain to take full advantage of Rust’s compile-time type checking. diff --git a/src/doc/book/src/ch05-01-defining-structs.md b/src/doc/book/src/ch05-01-defining-structs.md index 7a50f99a5..d258d89cc 100644 --- a/src/doc/book/src/ch05-01-defining-structs.md +++ b/src/doc/book/src/ch05-01-defining-structs.md @@ -13,6 +13,8 @@ grouped together. Then, inside curly brackets, we define the names and types of the pieces of data, which we call *fields*. For example, Listing 5-1 shows a struct that stores information about a user account. +<span class="filename">Filename: src/main.rs</span> + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs:here}} ``` @@ -21,14 +23,16 @@ struct that stores information about a user account. To use a struct after we’ve defined it, we create an *instance* of that struct by specifying concrete values for each of the fields. We create an instance by -stating the name of the struct and then add curly brackets containing `key: -value` pairs, where the keys are the names of the fields and the values are the +stating the name of the struct and then add curly brackets containing *key: +value* pairs, where the keys are the names of the fields and the values are the data we want to store in those fields. We don’t have to specify the fields in the same order in which we declared them in the struct. In other words, the struct definition is like a general template for the type, and instances fill in that template with particular data to create values of the type. For example, we can declare a particular user as shown in Listing 5-2. +<span class="filename">Filename: src/main.rs</span> + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs:here}} ``` @@ -42,6 +46,8 @@ mutable, we can change a value by using the dot notation and assigning into a particular field. Listing 5-3 shows how to change the value in the `email` field of a mutable `User` instance. +<span class="filename">Filename: src/main.rs</span> + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs:here}} ``` @@ -58,6 +64,8 @@ Listing 5-4 shows a `build_user` function that returns a `User` instance with the given email and username. The `active` field gets the value of `true`, and the `sign_in_count` gets a value of `1`. +<span class="filename">Filename: src/main.rs</span> + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs:here}} ``` @@ -70,20 +78,24 @@ fields, but having to repeat the `email` and `username` field names and variables is a bit tedious. If the struct had more fields, repeating each name would get even more annoying. Luckily, there’s a convenient shorthand! +<!-- Old heading. Do not remove or links may break. --> <a id="using-the-field-init-shorthand-when-variables-and-fields-have-the-same-name"></a> + ### Using the Field Init Shorthand Because the parameter names and the struct field names are exactly the same in Listing 5-4, we can use the *field init shorthand* syntax to rewrite -`build_user` so that it behaves exactly the same but doesn’t have the -repetition of `email` and `username`, as shown in Listing 5-5. +`build_user` so it behaves exactly the same but doesn’t have the repetition of +`username` and `email`, as shown in Listing 5-5. + +<span class="filename">Filename: src/main.rs</span> ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs:here}} ``` <span class="caption">Listing 5-5: A `build_user` function that uses field init -shorthand because the `email` and `username` parameters have the same name as +shorthand because the `username` and `email` parameters have the same name as struct fields</span> Here, we’re creating a new instance of the `User` struct, which has a field @@ -92,7 +104,7 @@ named `email`. We want to set the `email` field’s value to the value in the the `email` parameter have the same name, we only need to write `email` rather than `email: email`. -### Creating Instances From Other Instances With Struct Update Syntax +### Creating Instances from Other Instances with Struct Update Syntax It’s often useful to create a new instance of a struct that includes most of the values from another instance, but changes some. You can do this using @@ -102,6 +114,8 @@ First, in Listing 5-6 we show how to create a new `User` instance in `user2` regularly, without the update syntax. We set a new value for `email` but otherwise use the same values from `user1` that we created in Listing 5-2. +<span class="filename">Filename: src/main.rs</span> + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs:here}} ``` @@ -113,12 +127,14 @@ Using struct update syntax, we can achieve the same effect with less code, as shown in Listing 5-7. The syntax `..` specifies that the remaining fields not explicitly set should have the same value as the fields in the given instance. +<span class="filename">Filename: src/main.rs</span> + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs:here}} ``` <span class="caption">Listing 5-7: Using struct update syntax to set a new -`email` value for a `User` instance but use the rest of the values from +`email` value for a `User` instance but to use the rest of the values from `user1`</span> The code in Listing 5-7 also creates an instance in `user2` that has a @@ -129,35 +145,37 @@ corresponding fields in `user1`, but we can choose to specify values for as many fields as we want in any order, regardless of the order of the fields in the struct’s definition. -Note that the struct update syntax uses `=` like an assignment; this is -because it moves the data, just as we saw in the [“Ways Variables and Data -Interact: Move”][move]<!-- ignore --> section. In this example, we can no -longer use `user1` after creating `user2` because the `String` in the +Note that the struct update syntax uses `=` like an assignment; this is because +it moves the data, just as we saw in the [“Variables and Data Interacting with +Move”][move]<!-- ignore --> section. In this example, we can no longer use +`user1` as a whole after creating `user2` because the `String` in the `username` field of `user1` was moved into `user2`. If we had given `user2` new `String` values for both `email` and `username`, and thus only used the `active` and `sign_in_count` values from `user1`, then `user1` would still be -valid after creating `user2`. The types of `active` and `sign_in_count` are -types that implement the `Copy` trait, so the behavior we discussed in the -[“Stack-Only Data: Copy”][copy]<!-- ignore --> section would apply. +valid after creating `user2`. Both `active` and `sign_in_count` are types that +implement the `Copy` trait, so the behavior we discussed in the [“Stack-Only +Data: Copy”][copy]<!-- ignore --> section would apply. -### Using Tuple Structs without Named Fields to Create Different Types +### Using Tuple Structs Without Named Fields to Create Different Types -Rust also supports structs that look similar to tuples, called *tuple -structs*. Tuple structs have the added meaning the struct name provides but -don’t have names associated with their fields; rather, they just have the types -of the fields. Tuple structs are useful when you want to give the whole tuple a -name and make the tuple a different type from other tuples, and when naming each +Rust also supports structs that look similar to tuples, called *tuple structs*. +Tuple structs have the added meaning the struct name provides but don’t have +names associated with their fields; rather, they just have the types of the +fields. Tuple structs are useful when you want to give the whole tuple a name +and make the tuple a different type from other tuples, and when naming each field as in a regular struct would be verbose or redundant. To define a tuple struct, start with the `struct` keyword and the struct name -followed by the types in the tuple. For example, here we define and use -two tuple structs named `Color` and `Point`: +followed by the types in the tuple. For example, here we define and use two +tuple structs named `Color` and `Point`: + +<span class="filename">Filename: src/main.rs</span> ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs}} ``` -Note that the `black` and `origin` values are different types, because they’re +Note that the `black` and `origin` values are different types because they’re instances of different tuple structs. Each struct you define is its own type, even though the fields within the struct might have the same types. For example, a function that takes a parameter of type `Color` cannot take a @@ -176,12 +194,14 @@ have any data that you want to store in the type itself. We’ll discuss traits in Chapter 10. Here’s an example of declaring and instantiating a unit struct named `AlwaysEqual`: +<span class="filename">Filename: src/main.rs</span> + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/src/main.rs}} ``` -To define `AlwaysEqual`, we use the `struct` keyword, the name we want, then a -semicolon. No need for curly brackets or parentheses! Then we can get an +To define `AlwaysEqual`, we use the `struct` keyword, the name we want, and +then a semicolon. No need for curly brackets or parentheses! Then we can get an instance of `AlwaysEqual` in the `subject` variable in a similar way: using the name we defined, without any curly brackets or parentheses. Imagine that later we’ll implement behavior for this type such that every instance of @@ -217,9 +237,9 @@ implement them on any type, including unit-like structs. > > fn main() { > let user1 = User { -> email: "someone@example.com", -> username: "someusername123", > active: true, +> username: "someusername123", +> email: "someone@example.com", > sign_in_count: 1, > }; > } @@ -273,5 +293,5 @@ paste above add `> ` before every line --> [tuples]: ch03-02-data-types.html#the-tuple-type -[move]: ch04-01-what-is-ownership.html#ways-variables-and-data-interact-move +[move]: ch04-01-what-is-ownership.html#variables-and-data-interacting-with-move [copy]: ch04-01-what-is-ownership.html#stack-only-data-copy diff --git a/src/doc/book/src/ch05-02-example-structs.md b/src/doc/book/src/ch05-02-example-structs.md index 5d33d9cb1..b2416b743 100644 --- a/src/doc/book/src/ch05-02-example-structs.md +++ b/src/doc/book/src/ch05-02-example-structs.md @@ -82,8 +82,8 @@ parts, as shown in Listing 5-10. Here we’ve defined a struct and named it `Rectangle`. Inside the curly brackets, we defined the fields as `width` and `height`, both of which have -type `u32`. Then in `main`, we created a particular instance of `Rectangle` -that has a width of 30 and a height of 50. +type `u32`. Then, in `main`, we created a particular instance of `Rectangle` +that has a width of `30` and a height of `50`. Our `area` function is now defined with one parameter, which we’ve named `rectangle`, whose type is an immutable borrow of a struct `Rectangle` @@ -126,7 +126,7 @@ When we compile this code, we get an error with this core message: The `println!` macro can do many kinds of formatting, and by default, the curly brackets tell `println!` to use formatting known as `Display`: output intended for direct end user consumption. The primitive types we’ve seen so far -implement `Display` by default, because there’s only one way you’d want to show +implement `Display` by default because there’s only one way you’d want to show a `1` or any other primitive type to a user. But with structs, the way `println!` should format the output is less clear because there are more display possibilities: Do you want commas or not? Do you want to print the @@ -182,8 +182,8 @@ following output: Nice! It’s not the prettiest output, but it shows the values of all the fields for this instance, which would definitely help during debugging. When we have larger structs, it’s useful to have output that’s a bit easier to read; in -those cases, we can use `{:#?}` instead of `{:?}` in the `println!` string. -In this example, using the `{:#?}` style will output: +those cases, we can use `{:#?}` instead of `{:?}` in the `println!` string. In +this example, using the `{:#?}` style will output the following: ```console {{#include ../listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/output.txt}} @@ -191,15 +191,15 @@ In this example, using the `{:#?}` style will output: Another way to print out a value using the `Debug` format is to use the [`dbg!` macro][dbg]<!-- ignore -->, which takes ownership of an expression (as opposed -to `println!` that takes a reference), prints the file and line number of where -that `dbg!` macro call occurs in your code along with the resulting value of -that expression, and returns ownership of the value. +to `println!`, which takes a reference), prints the file and line number of +where that `dbg!` macro call occurs in your code along with the resultant value +of that expression, and returns ownership of the value. > Note: Calling the `dbg!` macro prints to the standard error console stream -> (`stderr`), as opposed to `println!` which prints to the standard output +> (`stderr`), as opposed to `println!`, which prints to the standard output > console stream (`stdout`). We’ll talk more about `stderr` and `stdout` in the -> [“Writing Error Messages to Standard Error Instead of Standard -> Output” section in Chapter 12][err]<!-- ignore -->. +> [“Writing Error Messages to Standard Error Instead of Standard Output” +> section in Chapter 12][err]<!-- ignore -->. Here’s an example where we’re interested in the value that gets assigned to the `width` field, as well as the value of the whole struct in `rect1`: @@ -218,8 +218,8 @@ Here’s what the output of this example looks like: {{#include ../listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/output.txt}} ``` -We can see the first bit of output came from *src/main.rs* line 10, where we’re -debugging the expression `30 * scale`, and its resulting value is 60 (the +We can see the first bit of output came from *src/main.rs* line 10 where we’re +debugging the expression `30 * scale`, and its resultant value is `60` (the `Debug` formatting implemented for integers is to print only their value). The `dbg!` call on line 14 of *src/main.rs* outputs the value of `&rect1`, which is the `Rectangle` struct. This output uses the pretty `Debug` formatting of the @@ -235,10 +235,10 @@ attributes other than `derive`; for more information, see [the “Attributes” section of the Rust Reference][attributes]. Our `area` function is very specific: it only computes the area of rectangles. -It would be helpful to tie this behavior more closely to our `Rectangle` -struct, because it won’t work with any other type. Let’s look at how we can -continue to refactor this code by turning the `area` function into an `area` -*method* defined on our `Rectangle` type. +It would be helpful to tie this behavior more closely to our `Rectangle` struct +because it won’t work with any other type. Let’s look at how we can continue to +refactor this code by turning the `area` function into an `area` *method* +defined on our `Rectangle` type. [the-tuple-type]: ch03-02-data-types.html#the-tuple-type [app-c]: appendix-03-derivable-traits.md diff --git a/src/doc/book/src/ch05-03-method-syntax.md b/src/doc/book/src/ch05-03-method-syntax.md index e300d0104..d25e55b18 100644 --- a/src/doc/book/src/ch05-03-method-syntax.md +++ b/src/doc/book/src/ch05-03-method-syntax.md @@ -4,9 +4,10 @@ name, they can have parameters and a return value, and they contain some code that’s run when the method is called from somewhere else. Unlike functions, methods are defined within the context of a struct (or an enum or a trait -object, which we cover in Chapters 6 and 17, respectively), and their first -parameter is always `self`, which represents the instance of the struct the -method is being called on. +object, which we cover in [Chapter 6][enums]<!-- ignore --> and [Chapter +17][trait-objects]<!-- ignore -->, respectively), and their first parameter is +always `self`, which represents the instance of the struct the method is being +called on. ### Defining Methods @@ -39,28 +40,30 @@ type `Self` is an alias for the type that the `impl` block is for. Methods must have a parameter named `self` of type `Self` for their first parameter, so Rust lets you abbreviate this with only the name `self` in the first parameter spot. Note that we still need to use the `&` in front of the `self` shorthand to -indicate this method borrows the `Self` instance, just as we did in `rectangle: -&Rectangle`. Methods can take ownership of `self`, borrow `self` immutably as -we’ve done here, or borrow `self` mutably, just as they can any other parameter. - -We’ve chosen `&self` here for the same reason we used `&Rectangle` in the -function version: we don’t want to take ownership, and we just want to read the -data in the struct, not write to it. If we wanted to change the instance that -we’ve called the method on as part of what the method does, we’d use `&mut -self` as the first parameter. Having a method that takes ownership of the -instance by using just `self` as the first parameter is rare; this technique is -usually used when the method transforms `self` into something else and you want -to prevent the caller from using the original instance after the transformation. - -The main reason for using methods instead of functions, in addition to providing -method syntax and not having to repeat the type of `self` in every method’s -signature, is for organization. We’ve put all the things we can do with an -instance of a type in one `impl` block rather than making future users of our -code search for capabilities of `Rectangle` in various places in the library we -provide. +indicate that this method borrows the `Self` instance, just as we did in +`rectangle: &Rectangle`. Methods can take ownership of `self`, borrow `self` +immutably, as we’ve done here, or borrow `self` mutably, just as they can any +other parameter. + +We chose `&self` here for the same reason we used `&Rectangle` in the function +version: we don’t want to take ownership, and we just want to read the data in +the struct, not write to it. If we wanted to change the instance that we’ve +called the method on as part of what the method does, we’d use `&mut self` as +the first parameter. Having a method that takes ownership of the instance by +using just `self` as the first parameter is rare; this technique is usually +used when the method transforms `self` into something else and you want to +prevent the caller from using the original instance after the transformation. + +The main reason for using methods instead of functions, in addition to +providing method syntax and not having to repeat the type of `self` in every +method’s signature, is for organization. We’ve put all the things we can do +with an instance of a type in one `impl` block rather than making future users +of our code search for capabilities of `Rectangle` in various places in the +library we provide. Note that we can choose to give a method the same name as one of the struct’s -fields. For example, we can define a method on `Rectangle` also named `width`: +fields. For example, we can define a method on `Rectangle` that is also named +`width`: <span class="filename">Filename: src/main.rs</span> @@ -69,19 +72,20 @@ fields. For example, we can define a method on `Rectangle` also named `width`: ``` Here, we’re choosing to make the `width` method return `true` if the value in -the instance’s `width` field is greater than 0, and `false` if the value is 0: -we can use a field within a method of the same name for any purpose. In `main`, -when we follow `rect1.width` with parentheses, Rust knows we mean the method -`width`. When we don’t use parentheses, Rust knows we mean the field `width`. - -Often, but not always, when we give methods with the same name as a field we -want it to only return the value in the field and do nothing else. Methods like -this are called *getters*, and Rust does not implement them automatically for -struct fields as some other languages do. Getters are useful because you can -make the field private but the method public and thus enable read-only access -to that field as part of the type’s public API. We will be discussing what -public and private are and how to designate a field or method as public or -private in Chapter 7. +the instance’s `width` field is greater than `0` and `false` if the value is +`0`: we can use a field within a method of the same name for any purpose. In +`main`, when we follow `rect1.width` with parentheses, Rust knows we mean the +method `width`. When we don’t use parentheses, Rust knows we mean the field +`width`. + +Often, but not always, when we give a method the same name as a field we want +it to only return the value in the field and do nothing else. Methods like this +are called *getters*, and Rust does not implement them automatically for struct +fields as some other languages do. Getters are useful because you can make the +field private but the method public, and thus enable read-only access to that +field as part of the type’s public API. We will discuss what public and private +are and how to designate a field or method as public or private in [Chapter +7][public]<!-- ignore -->. > ### Where’s the `->` Operator? > @@ -131,11 +135,11 @@ private in Chapter 7. ### Methods with More Parameters Let’s practice using methods by implementing a second method on the `Rectangle` -struct. This time, we want an instance of `Rectangle` to take another instance +struct. This time we want an instance of `Rectangle` to take another instance of `Rectangle` and return `true` if the second `Rectangle` can fit completely -within `self` (the first `Rectangle`); otherwise it should return `false`. That -is, once we’ve defined the `can_hold` method, we want to be able to write the -program shown in Listing 5-14. +within `self` (the first `Rectangle`); otherwise, it should return `false`. +That is, once we’ve defined the `can_hold` method, we want to be able to write +the program shown in Listing 5-14. <span class="filename">Filename: src/main.rs</span> @@ -146,8 +150,8 @@ program shown in Listing 5-14. <span class="caption">Listing 5-14: Using the as-yet-unwritten `can_hold` method</span> -And the expected output would look like the following, because both dimensions -of `rect2` are smaller than the dimensions of `rect1` but `rect3` is wider than +The expected output would look like the following because both dimensions of +`rect2` are smaller than the dimensions of `rect1`, but `rect3` is wider than `rect1`: ```text @@ -165,7 +169,7 @@ read `rect2` (rather than write, which would mean we’d need a mutable borrow), and we want `main` to retain ownership of `rect2` so we can use it again after calling the `can_hold` method. The return value of `can_hold` will be a Boolean, and the implementation will check whether the width and height of -`self` are both greater than the width and height of the other `Rectangle`, +`self` are greater than the width and height of the other `Rectangle`, respectively. Let’s add the new `can_hold` method to the `impl` block from Listing 5-13, shown in Listing 5-15. @@ -213,13 +217,14 @@ is `Rectangle`. To call this associated function, we use the `::` syntax with the struct name; `let sq = Rectangle::square(3);` is an example. This function is namespaced by the struct: the `::` syntax is used for both associated functions and -namespaces created by modules. We’ll discuss modules in Chapter 7. +namespaces created by modules. We’ll discuss modules in [Chapter +7][modules]<!-- ignore -->. ### Multiple `impl` Blocks Each struct is allowed to have multiple `impl` blocks. For example, Listing -5-15 is equivalent to the code shown in Listing 5-16, which has each method -in its own `impl` block. +5-15 is equivalent to the code shown in Listing 5-16, which has each method in +its own `impl` block. ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs:here}} @@ -243,3 +248,8 @@ structs have. But structs aren’t the only way you can create custom types: let’s turn to Rust’s enum feature to add another tool to your toolbox. + +[enums]: ch06-00-enums.html +[trait-objects]: ch17-02-trait-objects.md +[public]: ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html#exposing-paths-with-the-pub-keyword +[modules]: ch07-02-defining-modules-to-control-scope-and-privacy.html diff --git a/src/doc/book/src/ch06-00-enums.md b/src/doc/book/src/ch06-00-enums.md index e207aa7bd..8a7faa9f3 100644 --- a/src/doc/book/src/ch06-00-enums.md +++ b/src/doc/book/src/ch06-00-enums.md @@ -1,7 +1,7 @@ # Enums and Pattern Matching -In this chapter we’ll look at *enumerations*, also referred to as *enums*. -Enums allow you to define a type by enumerating its possible *variants*. First, +In this chapter, we’ll look at *enumerations*, also referred to as *enums*. +Enums allow you to define a type by enumerating its possible *variants*. First we’ll define and use an enum to show how an enum can encode meaning along with data. Next, we’ll explore a particularly useful enum, called `Option`, which expresses that a value can be either something or nothing. Then we’ll look at diff --git a/src/doc/book/src/ch06-01-defining-an-enum.md b/src/doc/book/src/ch06-01-defining-an-enum.md index cb5d73097..eacd091bd 100644 --- a/src/doc/book/src/ch06-01-defining-an-enum.md +++ b/src/doc/book/src/ch06-01-defining-an-enum.md @@ -15,7 +15,7 @@ variants, which is where enumeration gets its name. Any IP address can be either a version four or a version six address, but not both at the same time. That property of IP addresses makes the enum data -structure appropriate, because an enum value can only be one of its variants. +structure appropriate because an enum value can only be one of its variants. Both version four and version six addresses are still fundamentally IP addresses, so they should be treated as the same type when the code is handling situations that apply to any kind of IP address. @@ -85,7 +85,7 @@ variants will have associated `String` values: ``` We attach data to each variant of the enum directly, so there is no need for an -extra struct. Here it’s also easier to see another detail of how enums work: +extra struct. Here, it’s also easier to see another detail of how enums work: the name of each enum variant that we define also becomes a function that constructs an instance of the enum. That is, `IpAddr::V4()` is a function call that takes a `String` argument and returns an instance of the `IpAddr` type. We @@ -93,7 +93,7 @@ automatically get this constructor function defined as a result of defining the enum. There’s another advantage to using an enum rather than a struct: each variant -can have different types and amounts of associated data. Version four type IP +can have different types and amounts of associated data. Version four IP addresses will always have four numeric components that will have values between 0 and 255. If we wanted to store `V4` addresses as four `u8` values but still express `V6` addresses as one `String` value, we wouldn’t be able to with @@ -150,7 +150,7 @@ different amounts and types of values</span> This enum has four variants with different types: * `Quit` has no data associated with it at all. -* `Move` has named fields like a struct does. +* `Move` has named fields, like a struct does. * `Write` includes a single `String`. * `ChangeColor` includes three `i32` values. @@ -164,7 +164,7 @@ variants hold: {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs:here}} ``` -But if we used the different structs, which each have their own type, we +But if we used the different structs, each of which has its own type, we couldn’t as easily define a function to take any of these kinds of messages as we could with the `Message` enum defined in Listing 6-2, which is a single type. @@ -190,8 +190,8 @@ This section explores a case study of `Option`, which is another enum defined by the standard library. The `Option` type encodes the very common scenario in which a value could be something or it could be nothing. -For example, if you request the first of a list containing items, you would get -a value. If you request the first item of an empty list, you would get nothing. +For example, if you request the first item in a non-empty list, you would get +a value. If you request the first item in an empty list, you would get nothing. Expressing this concept in terms of the type system means the compiler can check whether you’ve handled all the cases you should be handling; this functionality can prevent bugs that are extremely common in other programming @@ -243,11 +243,11 @@ prefix. The `Option<T>` enum is still just a regular enum, and `Some(T)` and The `<T>` syntax is a feature of Rust we haven’t talked about yet. It’s a generic type parameter, and we’ll cover generics in more detail in Chapter 10. -For now, all you need to know is that `<T>` means the `Some` variant of the -`Option` enum can hold one piece of data of any type, and that each concrete -type that gets used in place of `T` makes the overall `Option<T>` type a -different type. Here are some examples of using `Option` values to hold number -types and string types: +For now, all you need to know is that `<T>` means that the `Some` variant of +the `Option` enum can hold one piece of data of any type, and that each +concrete type that gets used in place of `T` makes the overall `Option<T>` type +a different type. Here are some examples of using `Option` values to hold +number types and string types: ```rust {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs:here}} @@ -262,20 +262,20 @@ type that the corresponding `Some` variant will hold by looking only at a `Option<i32>`. When we have a `Some` value, we know that a value is present and the value is -held within the `Some`. When we have a `None` value, in some sense, it means -the same thing as null: we don’t have a valid value. So why is having -`Option<T>` any better than having null? +held within the `Some`. When we have a `None` value, in some sense it means the +same thing as null: we don’t have a valid value. So why is having `Option<T>` +any better than having null? In short, because `Option<T>` and `T` (where `T` can be any type) are different types, the compiler won’t let us use an `Option<T>` value as if it were -definitely a valid value. For example, this code won’t compile because it’s +definitely a valid value. For example, this code won’t compile, because it’s trying to add an `i8` to an `Option<i8>`: ```rust,ignore,does_not_compile {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/src/main.rs:here}} ``` -If we run this code, we get an error message like this: +If we run this code, we get an error message like this one: ```console {{#include ../listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt}} @@ -292,8 +292,7 @@ using the value. In other words, you have to convert an `Option<T>` to a `T` before you can perform `T` operations with it. Generally, this helps catch one of the most -common issues with null: assuming that something isn’t null when it actually -is. +common issues with null: assuming that something isn’t null when it actually is. Eliminating the risk of incorrectly assuming a not-null value helps you to be more confident in your code. In order to have a value that can possibly be @@ -304,20 +303,21 @@ when the value is null. Everywhere that a value has a type that isn’t an deliberate design decision for Rust to limit null’s pervasiveness and increase the safety of Rust code. -So, how do you get the `T` value out of a `Some` variant when you have a value -of type `Option<T>` so you can use that value? The `Option<T>` enum has a large -number of methods that are useful in a variety of situations; you can check -them out in [its documentation][docs]<!-- ignore -->. Becoming familiar with -the methods on `Option<T>` will be extremely useful in your journey with Rust. +So how do you get the `T` value out of a `Some` variant when you have a value +of type `Option<T>` so that you can use that value? The `Option<T>` enum has a +large number of methods that are useful in a variety of situations; you can +check them out in [its documentation][docs]<!-- ignore -->. Becoming familiar +with the methods on `Option<T>` will be extremely useful in your journey with +Rust. In general, in order to use an `Option<T>` value, you want to have code that will handle each variant. You want some code that will run only when you have a `Some(T)` value, and this code is allowed to use the inner `T`. You want some -other code to run if you have a `None` value, and that code doesn’t have a `T` -value available. The `match` expression is a control flow construct that does -just this when used with enums: it will run different code depending on which -variant of the enum it has, and that code can use the data inside the matching -value. +other code to run only if you have a `None` value, and that code doesn’t have a +`T` value available. The `match` expression is a control flow construct that +does just this when used with enums: it will run different code depending on +which variant of the enum it has, and that code can use the data inside the +matching value. [IpAddr]: ../std/net/enum.IpAddr.html [option]: ../std/option/enum.Option.html diff --git a/src/doc/book/src/ch06-02-match.md b/src/doc/book/src/ch06-02-match.md index 2dfe6c34b..6a510df40 100644 --- a/src/doc/book/src/ch06-02-match.md +++ b/src/doc/book/src/ch06-02-match.md @@ -1,13 +1,15 @@ +<!-- Old heading. Do not remove or links may break. --> <a id="the-match-control-flow-operator"></a> ## The `match` Control Flow Construct -Rust has an extremely powerful control flow construct called `match` that allows -you to compare a value against a series of patterns and then execute code based -on which pattern matches. Patterns can be made up of literal values, variable -names, wildcards, and many other things; Chapter 18 covers all the different -kinds of patterns and what they do. The power of `match` comes from the -expressiveness of the patterns and the fact that the compiler confirms that all -possible cases are handled. +Rust has an extremely powerful control flow construct called `match` that +allows you to compare a value against a series of patterns and then execute +code based on which pattern matches. Patterns can be made up of literal values, +variable names, wildcards, and many other things; [Chapter +18][ch18-00-patterns]<!-- ignore --> covers all the different kinds of patterns +and what they do. The power of `match` comes from the expressiveness of the +patterns and the fact that the compiler confirms that all possible cases are +handled. Think of a `match` expression as being like a coin-sorting machine: coins slide down a track with variously sized holes along it, and each coin falls through @@ -16,9 +18,9 @@ through each pattern in a `match`, and at the first pattern the value “fits, the value falls into the associated code block to be used during execution. Speaking of coins, let’s use them as an example using `match`! We can write a -function that takes an unknown United States coin and, in a similar way as the -counting machine, determines which coin it is and returns its value in cents, as -shown here in Listing 6-3. +function that takes an unknown US coin and, in a similar way as the counting +machine, determines which coin it is and returns its value in cents, as shown +in Listing 6-3. ```rust {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs:here}} @@ -27,25 +29,25 @@ shown here in Listing 6-3. <span class="caption">Listing 6-3: An enum and a `match` expression that has the variants of the enum as its patterns</span> -Let’s break down the `match` in the `value_in_cents` function. First, we list +Let’s break down the `match` in the `value_in_cents` function. First we list the `match` keyword followed by an expression, which in this case is the value -`coin`. This seems very similar to an expression used with `if`, but there’s a -big difference: with `if`, the expression needs to return a Boolean value, but -here, it can return any type. The type of `coin` in this example is the `Coin` -enum that we defined on the first line. +`coin`. This seems very similar to a conditional expression used with `if`, but +there’s a big difference: with `if`, the condition needs to evaluate to a +Boolean value, but here it can be any type. The type of `coin` in this example +is the `Coin` enum that we defined on the first line. Next are the `match` arms. An arm has two parts: a pattern and some code. The first arm here has a pattern that is the value `Coin::Penny` and then the `=>` operator that separates the pattern and the code to run. The code in this case is just the value `1`. Each arm is separated from the next with a comma. -When the `match` expression executes, it compares the resulting value against +When the `match` expression executes, it compares the resultant value against the pattern of each arm, in order. If a pattern matches the value, the code associated with that pattern is executed. If that pattern doesn’t match the value, execution continues to the next arm, much as in a coin-sorting machine. We can have as many arms as we need: in Listing 6-3, our `match` has four arms. -The code associated with each arm is an expression, and the resulting value of +The code associated with each arm is an expression, and the resultant value of the expression in the matching arm is the value that gets returned for the entire `match` expression. @@ -60,7 +62,7 @@ returns the last value of the block, `1`: {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs:here}} ``` -### Patterns that Bind to Values +### Patterns That Bind to Values Another useful feature of match arms is that they can bind to the parts of the values that match the pattern. This is how we can extract values out of enum @@ -70,8 +72,8 @@ As an example, let’s change one of our enum variants to hold data inside it. From 1999 through 2008, the United States minted quarters with different designs for each of the 50 states on one side. No other coins got state designs, so only quarters have this extra value. We can add this information to -our `enum` by changing the `Quarter` variant to include a `UsState` value stored -inside it, which we’ve done here in Listing 6-4. +our `enum` by changing the `Quarter` variant to include a `UsState` value +stored inside it, which we’ve done in Listing 6-4. ```rust {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs:here}} @@ -82,8 +84,8 @@ also holds a `UsState` value</span> Let’s imagine that a friend is trying to collect all 50 state quarters. While we sort our loose change by coin type, we’ll also call out the name of the -state associated with each quarter so if it’s one our friend doesn’t have, they -can add it to their collection. +state associated with each quarter so that if it’s one our friend doesn’t have, +they can add it to their collection. In the match expression for this code, we add a variable called `state` to the pattern that matches values of the variant `Coin::Quarter`. When a @@ -104,10 +106,10 @@ state value out of the `Coin` enum variant for `Quarter`. ### Matching with `Option<T>` In the previous section, we wanted to get the inner `T` value out of the `Some` -case when using `Option<T>`; we can also handle `Option<T>` using `match` as we -did with the `Coin` enum! Instead of comparing coins, we’ll compare the -variants of `Option<T>`, but the way that the `match` expression works remains -the same. +case when using `Option<T>`; we can also handle `Option<T>` using `match`, as +we did with the `Coin` enum! Instead of comparing coins, we’ll compare the +variants of `Option<T>`, but the way the `match` expression works remains the +same. Let’s say we want to write a function that takes an `Option<i32>` and, if there’s a value inside, adds 1 to that value. If there isn’t a value inside, @@ -126,26 +128,26 @@ an `Option<i32>`</span> Let’s examine the first execution of `plus_one` in more detail. When we call `plus_one(five)`, the variable `x` in the body of `plus_one` will have the -value `Some(5)`. We then compare that against each match arm. +value `Some(5)`. We then compare that against each match arm: ```rust,ignore {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:first_arm}} ``` The `Some(5)` value doesn’t match the pattern `None`, so we continue to the -next arm. +next arm: ```rust,ignore {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:second_arm}} ``` -Does `Some(5)` match `Some(i)`? Why yes it does! We have the same variant. The -`i` binds to the value contained in `Some`, so `i` takes the value `5`. The -code in the match arm is then executed, so we add 1 to the value of `i` and -create a new `Some` value with our total `6` inside. +Does `Some(5)` match `Some(i)`? It does! We have the same variant. The `i` +binds to the value contained in `Some`, so `i` takes the value `5`. The code in +the match arm is then executed, so we add 1 to the value of `i` and create a +new `Some` value with our total `6` inside. Now let’s consider the second call of `plus_one` in Listing 6-5, where `x` is -`None`. We enter the `match` and compare to the first arm. +`None`. We enter the `match` and compare to the first arm: ```rust,ignore {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:first_arm}} @@ -179,7 +181,7 @@ error: {{#include ../listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt}} ``` -Rust knows that we didn’t cover every possible case and even knows which +Rust knows that we didn’t cover every possible case, and even knows which pattern we forgot! Matches in Rust are *exhaustive*: we must exhaust every last possibility in order for the code to be valid. Especially in the case of `Option<T>`, when Rust prevents us from forgetting to explicitly handle the @@ -202,10 +204,10 @@ this example: {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs:here}} ``` -For the first two arms, the patterns are the literal values 3 and 7. For the -last arm that covers every other possible value, the pattern is the variable -we’ve chosen to name `other`. The code that runs for the `other` arm uses the -variable by passing it to the `move_player` function. +For the first two arms, the patterns are the literal values `3` and `7`. For +the last arm that covers every other possible value, the pattern is the +variable we’ve chosen to name `other`. The code that runs for the `other` arm +uses the variable by passing it to the `move_player` function. This code compiles, even though we haven’t listed all the possible values a `u8` can have, because the last pattern will match all values not specifically @@ -230,7 +232,7 @@ can change our code to use `_` instead of the variable named `other`: This example also meets the exhaustiveness requirement because we’re explicitly ignoring all other values in the last arm; we haven’t forgotten anything. -Finally, we’ll change the rules of the game one more time, so that nothing else +Finally, we’ll change the rules of the game one more time so that nothing else happens on your turn if you roll anything other than a 3 or a 7. We can express that by using the unit value (the empty tuple type we mentioned in [“The Tuple Type”][tuples]<!-- ignore --> section) as the code that goes with the `_` arm: diff --git a/src/doc/book/src/ch06-03-if-let.md b/src/doc/book/src/ch06-03-if-let.md index 07634e162..c9bfbf3c7 100644 --- a/src/doc/book/src/ch06-03-if-let.md +++ b/src/doc/book/src/ch06-03-if-let.md @@ -2,8 +2,9 @@ The `if let` syntax lets you combine `if` and `let` into a less verbose way to handle values that match one pattern while ignoring the rest. Consider the -program in Listing 6-6 that matches on an `Option<u8>` value in the `config_max` -variable but only wants to execute code if the value is the `Some` variant. +program in Listing 6-6 that matches on an `Option<u8>` value in the +`config_max` variable but only wants to execute code if the value is the `Some` +variant. ```rust {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-06/src/main.rs:here}} @@ -29,7 +30,7 @@ The syntax `if let` takes a pattern and an expression separated by an equal sign. It works the same way as a `match`, where the expression is given to the `match` and the pattern is its first arm. In this case, the pattern is `Some(max)`, and the `max` binds to the value inside the `Some`. We can then -use `max` in the body of the `if let` block in the same way as we used `max` in +use `max` in the body of the `if let` block in the same way we used `max` in the corresponding `match` arm. The code in the `if let` block isn’t run if the value doesn’t match the pattern. @@ -48,13 +49,13 @@ We can include an `else` with an `if let`. The block of code that goes with the `Coin` enum definition in Listing 6-4, where the `Quarter` variant also held a `UsState` value. If we wanted to count all non-quarter coins we see while also announcing the state of the quarters, we could do that with a `match` -expression like this: +expression, like this: ```rust {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/src/main.rs:here}} ``` -Or we could use an `if let` and `else` expression like this: +Or we could use an `if let` and `else` expression, like this: ```rust {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/src/main.rs:here}} @@ -73,9 +74,10 @@ values, depending on how many cases you need to handle. Your Rust programs can now express concepts in your domain using structs and enums. Creating custom types to use in your API ensures type safety: the -compiler will make certain your functions get only values of the type each +compiler will make certain your functions only get values of the type each function expects. In order to provide a well-organized API to your users that is straightforward to use and only exposes exactly what your users will need, let’s now turn to Rust’s modules. + diff --git a/src/doc/book/src/title-page.md b/src/doc/book/src/title-page.md index ed55a6839..12d1a6598 100644 --- a/src/doc/book/src/title-page.md +++ b/src/doc/book/src/title-page.md @@ -2,7 +2,7 @@ *by Steve Klabnik and Carol Nichols, with contributions from the Rust Community* -This version of the text assumes you’re using Rust 1.62 (released 2022-06-30) +This version of the text assumes you’re using Rust 1.65 (released 2022-11-03) or later. See the [“Installation” section of Chapter 1][install]<!-- ignore --> to install or update Rust. diff --git a/src/doc/embedded-book/src/intro/install/linux.md b/src/doc/embedded-book/src/intro/install/linux.md index f8684d0a8..1c0b0edfa 100644 --- a/src/doc/embedded-book/src/intro/install/linux.md +++ b/src/doc/embedded-book/src/intro/install/linux.md @@ -39,16 +39,13 @@ sudo apt install gdb-arm-none-eabi openocd qemu-system-arm - Fedora 27 or newer -> **NOTE** `arm-none-eabi-gdb` is the GDB command you'll use to debug your ARM -> Cortex-M programs - <!-- Fedora 27 --> <!-- GDB 7.6 (!) --> <!-- OpenOCD 0.10.0 --> <!-- QEMU 2.10.2 --> ``` console -sudo dnf install arm-none-eabi-gdb openocd qemu-system-arm +sudo dnf install gdb openocd qemu-system-arm ``` - Arch Linux diff --git a/src/doc/embedded-book/src/intro/no-std.md b/src/doc/embedded-book/src/intro/no-std.md index 35bfc1adc..93aadf65d 100644 --- a/src/doc/embedded-book/src/intro/no-std.md +++ b/src/doc/embedded-book/src/intro/no-std.md @@ -47,7 +47,7 @@ bootstrapping (stage 0) code like bootloaders, firmware or kernels. | feature | no\_std | std | |-----------------------------------------------------------|--------|-----| | heap (dynamic memory) | * | ✓ | -| collections (Vec, HashMap, etc) | ** | ✓ | +| collections (Vec, BTreeMap, etc) | ** | ✓ | | stack overflow protection | ✘ | ✓ | | runs init code before main | ✘ | ✓ | | libstd available | ✘ | ✓ | @@ -58,6 +58,8 @@ bootstrapping (stage 0) code like bootloaders, firmware or kernels. \** Only if you use the `collections` crate and configure a global default allocator. +\** HashMap and HashSet are not available due to a lack of a secure random number generator. + [alloc-cortex-m]: https://github.com/rust-embedded/alloc-cortex-m ## See Also diff --git a/src/doc/embedded-book/src/peripherals/singletons.md b/src/doc/embedded-book/src/peripherals/singletons.md index 840a98665..3f04aa170 100644 --- a/src/doc/embedded-book/src/peripherals/singletons.md +++ b/src/doc/embedded-book/src/peripherals/singletons.md @@ -25,7 +25,7 @@ But this has a few problems. It is a mutable global variable, and in Rust, these ## How do we do this in Rust? -Instead of just making our peripheral a global variable, we might instead decide to make a global variable, in this case called `PERIPHERALS`, which contains an `Option<T>` for each of our peripherals. +Instead of just making our peripheral a global variable, we might instead decide to make a structure, in this case called `PERIPHERALS`, which contains an `Option<T>` for each of our peripherals. ```rust,ignore struct Peripherals { diff --git a/src/doc/embedded-book/src/start/hardware.md b/src/doc/embedded-book/src/start/hardware.md index f1eee3163..8166e62e5 100644 --- a/src/doc/embedded-book/src/start/hardware.md +++ b/src/doc/embedded-book/src/start/hardware.md @@ -272,7 +272,7 @@ Quit anyway? (y or n) ``` Debugging now requires a few more steps so we have packed all those steps into a -single GDB script named `openocd.gdb`. The file was created during the `cargo generate` step, and should work without any modifications. Let's have a peak: +single GDB script named `openocd.gdb`. The file was created during the `cargo generate` step, and should work without any modifications. Let's have a peek: ``` console cat openocd.gdb diff --git a/src/doc/nomicon/src/lifetime-mismatch.md b/src/doc/nomicon/src/lifetime-mismatch.md index 1da2d285c..bc53f06f8 100644 --- a/src/doc/nomicon/src/lifetime-mismatch.md +++ b/src/doc/nomicon/src/lifetime-mismatch.md @@ -74,7 +74,7 @@ care about, but the lifetime system is too coarse-grained to handle that. ## Improperly reduced borrows The following code fails to compile, because Rust sees that a variable, `map`, -is borrowed twice, and can not infer that the first borrow stops to be needed +is borrowed twice, and can not infer that the first borrow ceases to be needed before the second one occurs. This is caused by Rust conservatively falling back to using a whole scope for the first borrow. This will eventually get fixed. diff --git a/src/doc/nomicon/src/unchecked-uninit.md b/src/doc/nomicon/src/unchecked-uninit.md index c61415c97..b3dd31cf1 100644 --- a/src/doc/nomicon/src/unchecked-uninit.md +++ b/src/doc/nomicon/src/unchecked-uninit.md @@ -11,7 +11,7 @@ Unsafe Rust gives us a powerful tool to handle this problem: [`MaybeUninit`]. This type can be used to handle memory that has not been fully initialized yet. -With `MaybeUninit`, we can initialize an array element-for-element as follows: +With `MaybeUninit`, we can initialize an array element by element as follows: ```rust use std::mem::{self, MaybeUninit}; @@ -79,8 +79,7 @@ This code proceeds in three steps: acknowledge that by providing appropriate methods). It's worth spending a bit more time on the loop in the middle, and in particular -the assignment operator and its interaction with `drop`. If we would have -written something like: +the assignment operator and its interaction with `drop`. If we wrote something like: <!-- ignore: simplified code --> ```rust,ignore @@ -88,7 +87,7 @@ written something like: ``` we would actually overwrite a `Box<u32>`, leading to `drop` of uninitialized -data, which will cause much sadness and pain. +data, which would cause much sadness and pain. The correct alternative, if for some reason we cannot use `MaybeUninit::new`, is to use the [`ptr`] module. In particular, it provides three functions that allow @@ -97,7 +96,7 @@ us to assign bytes to a location in memory without dropping the old value: * `ptr::write(ptr, val)` takes a `val` and moves it into the address pointed to by `ptr`. -* `ptr::copy(src, dest, count)` copies the bits that `count` T's would occupy +* `ptr::copy(src, dest, count)` copies the bits that `count` T items would occupy from src to dest. (this is equivalent to C's memmove -- note that the argument order is reversed!) * `ptr::copy_nonoverlapping(src, dest, count)` does what `copy` does, but a @@ -105,8 +104,8 @@ us to assign bytes to a location in memory without dropping the old value: (this is equivalent to C's memcpy -- note that the argument order is reversed!) It should go without saying that these functions, if misused, will cause serious -havoc or just straight up Undefined Behavior. The only things that these -functions *themselves* require is that the locations you want to read and write +havoc or just straight up Undefined Behavior. The only requirement of these +functions *themselves* is that the locations you want to read and write are allocated and properly aligned. However, the ways writing arbitrary bits to arbitrary locations of memory can break things are basically uncountable! diff --git a/src/doc/nomicon/src/vec/vec-alloc.md b/src/doc/nomicon/src/vec/vec-alloc.md index 6c69c9379..249547339 100644 --- a/src/doc/nomicon/src/vec/vec-alloc.md +++ b/src/doc/nomicon/src/vec/vec-alloc.md @@ -28,7 +28,6 @@ impl<T> Vec<T> { ptr: NonNull::dangling(), len: 0, cap: 0, - _marker: PhantomData, } } } diff --git a/src/doc/nomicon/src/vec/vec-final.md b/src/doc/nomicon/src/vec/vec-final.md index 1f8af37ad..696391d10 100644 --- a/src/doc/nomicon/src/vec/vec-final.md +++ b/src/doc/nomicon/src/vec/vec-final.md @@ -10,7 +10,6 @@ use std::ptr::{self, NonNull}; struct RawVec<T> { ptr: NonNull<T>, cap: usize, - _marker: PhantomData<T>, } unsafe impl<T: Send> Send for RawVec<T> {} @@ -25,7 +24,6 @@ impl<T> RawVec<T> { RawVec { ptr: NonNull::dangling(), cap: cap, - _marker: PhantomData, } } diff --git a/src/doc/nomicon/src/vec/vec-insert-remove.md b/src/doc/nomicon/src/vec/vec-insert-remove.md index 57283f990..722e20c45 100644 --- a/src/doc/nomicon/src/vec/vec-insert-remove.md +++ b/src/doc/nomicon/src/vec/vec-insert-remove.md @@ -22,9 +22,11 @@ pub fn insert(&mut self, index: usize, elem: T) { unsafe { // ptr::copy(src, dest, len): "copy from src to dest len elems" - ptr::copy(self.ptr.as_ptr().add(index), - self.ptr.as_ptr().add(index + 1), - self.len - index); + ptr::copy( + self.ptr.as_ptr().add(index), + self.ptr.as_ptr().add(index + 1), + self.len - index, + ); ptr::write(self.ptr.as_ptr().add(index), elem); self.len += 1; } @@ -42,9 +44,11 @@ pub fn remove(&mut self, index: usize) -> T { unsafe { self.len -= 1; let result = ptr::read(self.ptr.as_ptr().add(index)); - ptr::copy(self.ptr.as_ptr().add(index + 1), - self.ptr.as_ptr().add(index), - self.len - index); + ptr::copy( + self.ptr.as_ptr().add(index + 1), + self.ptr.as_ptr().add(index), + self.len - index, + ); result } } diff --git a/src/doc/nomicon/src/vec/vec-into-iter.md b/src/doc/nomicon/src/vec/vec-into-iter.md index 61782e3b8..a3a3c8cb9 100644 --- a/src/doc/nomicon/src/vec/vec-into-iter.md +++ b/src/doc/nomicon/src/vec/vec-into-iter.md @@ -49,7 +49,6 @@ pub struct IntoIter<T> { cap: usize, start: *const T, end: *const T, - _marker: PhantomData<T>, } ``` @@ -61,13 +60,13 @@ impl<T> IntoIterator for Vec<T> { type Item = T; type IntoIter = IntoIter<T>; fn into_iter(self) -> IntoIter<T> { - // Can't destructure Vec since it's Drop - let ptr = self.ptr; - let cap = self.cap; - let len = self.len; - // Make sure not to drop Vec since that would free the buffer - mem::forget(self); + let vec = ManuallyDrop::new(self); + + // Can't destructure Vec since it's Drop + let ptr = vec.ptr; + let cap = vec.cap; + let len = vec.len; unsafe { IntoIter { @@ -80,7 +79,6 @@ impl<T> IntoIterator for Vec<T> { } else { ptr.as_ptr().add(len) }, - _marker: PhantomData, } } } diff --git a/src/doc/nomicon/src/vec/vec-layout.md b/src/doc/nomicon/src/vec/vec-layout.md index c1c1afcc7..9129952a5 100644 --- a/src/doc/nomicon/src/vec/vec-layout.md +++ b/src/doc/nomicon/src/vec/vec-layout.md @@ -15,13 +15,10 @@ pub struct Vec<T> { } ``` -And indeed this would compile. Unfortunately, it would be incorrect. First, the +And indeed this would compile. Unfortunately, it would be too strict. The compiler will give us too strict variance. So a `&Vec<&'static str>` -couldn't be used where an `&Vec<&'a str>` was expected. More importantly, it -will give incorrect ownership information to the drop checker, as it will -conservatively assume we don't own any values of type `T`. See [the chapter -on ownership and lifetimes][ownership] for all the details on variance and -drop check. +couldn't be used where a `&Vec<&'a str>` was expected. See [the chapter +on ownership and lifetimes][ownership] for all the details on variance. As we saw in the ownership chapter, the standard library uses `Unique<T>` in place of `*mut T` when it has a raw pointer to an allocation that it owns. Unique is unstable, @@ -30,16 +27,16 @@ so we'd like to not use it if possible, though. As a recap, Unique is a wrapper around a raw pointer that declares that: * We are covariant over `T` -* We may own a value of type `T` (for drop check) +* We may own a value of type `T` (this is not relevant for our example here, but see + [the chapter on PhantomData][phantom-data] on why the real `std::vec::Vec<T>` needs this) * We are Send/Sync if `T` is Send/Sync * Our pointer is never null (so `Option<Vec<T>>` is null-pointer-optimized) We can implement all of the above requirements in stable Rust. To do this, instead of using `Unique<T>` we will use [`NonNull<T>`][NonNull], another wrapper around a raw pointer, which gives us two of the above properties, namely it is covariant -over `T` and is declared to never be null. By adding a `PhantomData<T>` (for drop -check) and implementing Send/Sync if `T` is, we get the same results as using -`Unique<T>`: +over `T` and is declared to never be null. By implementing Send/Sync if `T` is, +we get the same results as using `Unique<T>`: ```rust use std::ptr::NonNull; @@ -49,7 +46,6 @@ pub struct Vec<T> { ptr: NonNull<T>, cap: usize, len: usize, - _marker: PhantomData<T>, } unsafe impl<T: Send> Send for Vec<T> {} @@ -58,4 +54,5 @@ unsafe impl<T: Sync> Sync for Vec<T> {} ``` [ownership]: ../ownership.html +[phantom-data]: ../phantom-data.md [NonNull]: ../../std/ptr/struct.NonNull.html diff --git a/src/doc/nomicon/src/vec/vec-raw.md b/src/doc/nomicon/src/vec/vec-raw.md index e86537b81..728feaa58 100644 --- a/src/doc/nomicon/src/vec/vec-raw.md +++ b/src/doc/nomicon/src/vec/vec-raw.md @@ -13,7 +13,6 @@ allocating, growing, and freeing: struct RawVec<T> { ptr: NonNull<T>, cap: usize, - _marker: PhantomData<T>, } unsafe impl<T: Send> Send for RawVec<T> {} @@ -25,7 +24,6 @@ impl<T> RawVec<T> { RawVec { ptr: NonNull::dangling(), cap: 0, - _marker: PhantomData, } } diff --git a/src/doc/nomicon/src/vec/vec-zsts.md b/src/doc/nomicon/src/vec/vec-zsts.md index 73a97ba49..8f2529727 100644 --- a/src/doc/nomicon/src/vec/vec-zsts.md +++ b/src/doc/nomicon/src/vec/vec-zsts.md @@ -33,14 +33,13 @@ method of `RawVec`. ```rust,ignore impl<T> RawVec<T> { fn new() -> Self { - // !0 is usize::MAX. This branch should be stripped at compile time. - let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 }; + // This branch should be stripped at compile time. + let cap = if mem::size_of::<T>() == 0 { usize::MAX } else { 0 }; // `NonNull::dangling()` doubles as "unallocated" and "zero-sized allocation" RawVec { ptr: NonNull::dangling(), cap: cap, - _marker: PhantomData, } } diff --git a/src/doc/reference/src/attributes.md b/src/doc/reference/src/attributes.md index b7c1ef609..5d619c990 100644 --- a/src/doc/reference/src/attributes.md +++ b/src/doc/reference/src/attributes.md @@ -248,6 +248,7 @@ The following is an index of all built-in attributes. - [`no_builtins`] — Disables use of certain built-in functions. - [`target_feature`] — Configure platform-specific code generation. - [`track_caller`] - Pass the parent call location to `std::panic::Location::caller()`. + - [`instruction_set`] - Specify the instruction set used to generate a functions code - Documentation - `doc` — Specifies documentation. See [The Rustdoc Book] for more information. [Doc comments] are transformed into `doc` attributes. @@ -298,6 +299,7 @@ The following is an index of all built-in attributes. [`global_allocator`]: runtime.md#the-global_allocator-attribute [`ignore`]: attributes/testing.md#the-ignore-attribute [`inline`]: attributes/codegen.md#the-inline-attribute +[`instruction_set`]: attributes/codegen.md#the-instruction_set-attribute [`link_name`]: items/external-blocks.md#the-link_name-attribute [`link_ordinal`]: items/external-blocks.md#the-link_ordinal-attribute [`link_section`]: abi.md#the-link_section-attribute diff --git a/src/doc/reference/src/attributes/codegen.md b/src/doc/reference/src/attributes/codegen.md index 3a36a10ca..69ad341d1 100644 --- a/src/doc/reference/src/attributes/codegen.md +++ b/src/doc/reference/src/attributes/codegen.md @@ -352,3 +352,26 @@ trait object whose methods are attributed. [`core::intrinsics::caller_location`]: ../../core/intrinsics/fn.caller_location.html [`core::panic::Location::caller`]: ../../core/panic/struct.Location.html#method.caller [`Location`]: ../../core/panic/struct.Location.html + +## The `instruction_set` attribute + +The *`instruction_set` attribute* may be applied to a function to enable code generation for a specific +instruction set supported by the target architecture. It uses the [_MetaListPath_] syntax and a path +comprised of the architecture and instruction set to specify how to generate the code for +architectures where a single program may utilize multiple instruction sets. + +The following values are available on targets for the `ARMv4` and `ARMv5te` architectures: + +* `arm::a32` - Uses ARM code. +* `arm::t32` - Uses Thumb code. + +<!-- ignore: arm-only --> +```rust,ignore +#[instruction_set(arm::a32)] +fn foo_arm_code() {} + +#[instruction_set(arm::t32)] +fn bar_thumb_code() {} +``` + +[_MetaListPath_]: ../attributes.md#meta-item-attribute-syntax diff --git a/src/doc/reference/src/behavior-considered-undefined.md b/src/doc/reference/src/behavior-considered-undefined.md index e810e8c0d..f8bffd13e 100644 --- a/src/doc/reference/src/behavior-considered-undefined.md +++ b/src/doc/reference/src/behavior-considered-undefined.md @@ -26,8 +26,22 @@ code. * Evaluating a [dereference expression] (`*expr`) on a raw pointer that is [dangling] or unaligned, even in [place expression context] (e.g. `addr_of!(&*expr)`). -* Breaking the [pointer aliasing rules]. `&mut T` and `&T` follow LLVM’s scoped - [noalias] model, except if the `&T` contains an [`UnsafeCell<U>`]. +* Breaking the [pointer aliasing rules]. `Box<T>`, `&mut T` and `&T` follow + LLVM’s scoped [noalias] model, except if the `&T` contains an + [`UnsafeCell<U>`]. References and boxes must not be [dangling] while they are + live. The exact liveness duration is not specified, but some bounds exist: + * For references, the liveness duration is upper-bounded by the syntactic + lifetime assigned by the borrow checker; it cannot be live any *longer* than + that lifetime. + * Each time a reference or box is passed to or returned from a function, it is + considered live. + * When a reference (but not a `Box`!) is passed to a function, it is live at + least as long as that function call, again except if the `&T` contains an + [`UnsafeCell<U>`]. + + All this also applies when values of these + types are passed in a (nested) field of a compound type, but not behind + pointer indirections. * Mutating immutable data. All data inside a [`const`] item is immutable. Moreover, all data reached through a shared reference or data owned by an immutable binding is immutable, unless that data is contained within an [`UnsafeCell<U>`]. diff --git a/src/doc/reference/src/comments.md b/src/doc/reference/src/comments.md index 46074b45c..ad29c58e5 100644 --- a/src/doc/reference/src/comments.md +++ b/src/doc/reference/src/comments.md @@ -2,7 +2,7 @@ > **<sup>Lexer</sup>**\ > LINE_COMMENT :\ -> `//` (~\[`/` `!`] | `//`) ~`\n`<sup>\*</sup>\ +> `//` (~\[`/` `!` `\n`] | `//`) ~`\n`<sup>\*</sup>\ > | `//` > > BLOCK_COMMENT :\ diff --git a/src/doc/reference/src/expressions/literal-expr.md b/src/doc/reference/src/expressions/literal-expr.md index 4eec37dcb..e5bc2dff4 100644 --- a/src/doc/reference/src/expressions/literal-expr.md +++ b/src/doc/reference/src/expressions/literal-expr.md @@ -8,11 +8,9 @@ > | [BYTE_LITERAL]\ > | [BYTE_STRING_LITERAL]\ > | [RAW_BYTE_STRING_LITERAL]\ -> | [INTEGER_LITERAL][^out-of-range]\ +> | [INTEGER_LITERAL]\ > | [FLOAT_LITERAL]\ > | `true` | `false` -> -> [^out-of-range]: A value ≥ 2<sup>128</sup> is not allowed. A _literal expression_ is an expression consisting of a single token, rather than a sequence of tokens, that immediately and directly denotes the value it evaluates to, rather than referring to it by name or some other evaluation rule. @@ -54,7 +52,7 @@ A string literal expression consists of a single [BYTE_STRING_LITERAL] or [RAW_B An integer literal expression consists of a single [INTEGER_LITERAL] token. -If the token has a [suffix], the suffix will be the name of one of the [primitive integer types][numeric types]: `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`, `usize`, or `isize`, and the expression has that type. +If the token has a [suffix], the suffix must be the name of one of the [primitive integer types][numeric types]: `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`, `usize`, or `isize`, and the expression has that type. If the token has no suffix, the expression's type is determined by type inference: @@ -96,10 +94,12 @@ The value of the expression is determined from the string representation of the * If the radix is not 10, the first two characters are removed from the string. +* Any suffix is removed from the string. + * Any underscores are removed from the string. * The string is converted to a `u128` value as if by [`u128::from_str_radix`] with the chosen radix. -If the value does not fit in `u128`, the expression is rejected by the parser. +If the value does not fit in `u128`, it is a compiler error. * The `u128` value is converted to the expression's type via a [numeric cast]. @@ -111,9 +111,11 @@ If the value does not fit in `u128`, the expression is rejected by the parser. ## Floating-point literal expressions -A floating-point literal expression consists of a single [FLOAT_LITERAL] token. +A floating-point literal expression has one of two forms: + * a single [FLOAT_LITERAL] token + * a single [INTEGER_LITERAL] token which has a suffix and no radix indicator -If the token has a [suffix], the suffix will be the name of one of the [primitive floating-point types][floating-point types]: `f32` or `f64`, and the expression has that type. +If the token has a [suffix], the suffix must be the name of one of the [primitive floating-point types][floating-point types]: `f32` or `f64`, and the expression has that type. If the token has no suffix, the expression's type is determined by type inference: @@ -136,6 +138,8 @@ let x: f64 = 2.; // type f64 The value of the expression is determined from the string representation of the token as follows: +* Any suffix is removed from the string. + * Any underscores are removed from the string. * The string is converted to the expression's type as if by [`f32::from_str`] or [`f64::from_str`]. diff --git a/src/doc/reference/src/items/extern-crates.md b/src/doc/reference/src/items/extern-crates.md index f4dc735b0..d6b3a9aae 100644 --- a/src/doc/reference/src/items/extern-crates.md +++ b/src/doc/reference/src/items/extern-crates.md @@ -20,9 +20,9 @@ clause can be used to bind the imported crate to a different name. The external crate is resolved to a specific `soname` at compile time, and a runtime linkage requirement to that `soname` is passed to the linker for loading at runtime. The `soname` is resolved at compile time by scanning the -compiler's library path and matching the optional `crateid` provided against -the `crateid` attributes that were declared on the external crate when it was -compiled. If no `crateid` is provided, a default `name` attribute is assumed, +compiler's library path and matching the optional `crate_name` provided against +the [`crate_name` attributes] that were declared on the external crate when it was +compiled. If no `crate_name` is provided, a default `name` attribute is assumed, equal to the [identifier] given in the `extern crate` declaration. The `self` crate may be imported which creates a binding to the current crate. @@ -78,6 +78,7 @@ crate to access only its macros. [`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute [extern prelude]: ../names/preludes.md#extern-prelude [`macro_use` prelude]: ../names/preludes.md#macro_use-prelude +[`crate_name` attributes]: ../crates-and-source-files.md#the-crate_name-attribute <script> (function() { diff --git a/src/doc/reference/src/items/external-blocks.md b/src/doc/reference/src/items/external-blocks.md index c91e1d10c..d89536968 100644 --- a/src/doc/reference/src/items/external-blocks.md +++ b/src/doc/reference/src/items/external-blocks.md @@ -201,6 +201,22 @@ The default for this modifier is `-whole-archive`. More implementation details about this modifier can be found in [`whole-archive` documentation for rustc]. +### Linking modifiers: `verbatim` + +This modifier is compatible with all linking kinds. + +`+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes +(like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the +linker. + +`-verbatim` means that rustc will either add a target-specific prefix and suffix to the library +name before passing it to linker, or won't prevent linker from implicitly adding it. + +The default for this modifier is `-verbatim`. + +More implementation details about this modifier can be found in +[`verbatim` documentation for rustc]. + #### `dylib` versus `raw-dylib` On Windows, linking against a dynamic library requires that an import library @@ -288,4 +304,5 @@ restrictions as [regular function parameters]. [regular function parameters]: functions.md#attributes-on-function-parameters [`bundle` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-bundle [`whole-archive` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive +[`verbatim` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-verbatim [`dylib` versus `raw-dylib`]: #dylib-versus-raw-dylib diff --git a/src/doc/reference/src/items/generics.md b/src/doc/reference/src/items/generics.md index 5ffcd1580..5b7170726 100644 --- a/src/doc/reference/src/items/generics.md +++ b/src/doc/reference/src/items/generics.md @@ -51,7 +51,7 @@ instances of the item must be instantiated with a value of the given type. <!-- TODO: update above to say "introduces a name in the [value namespace]" once namespaces are added. --> -The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`, `usize` +The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `char` and `bool`. Const parameters can be used anywhere a [const item] can be used, with the diff --git a/src/doc/reference/src/macros-by-example.md b/src/doc/reference/src/macros-by-example.md index 2c49300cd..cd9dc3402 100644 --- a/src/doc/reference/src/macros-by-example.md +++ b/src/doc/reference/src/macros-by-example.md @@ -76,6 +76,8 @@ delimiters for the matcher will match any pair of delimiters. Thus, for instance, the matcher `(())` will match `{()}` but not `{{}}`. The character `$` cannot be matched or transcribed literally. +### Forwarding a matched fragment + When forwarding a matched fragment to another macro-by-example, matchers in the second macro will see an opaque AST of the fragment type. The second macro can't use literal tokens to match the fragments in the matcher, only a diff --git a/src/doc/reference/src/special-types-and-traits.md b/src/doc/reference/src/special-types-and-traits.md index ca53b3c9a..6355f3fb2 100644 --- a/src/doc/reference/src/special-types-and-traits.md +++ b/src/doc/reference/src/special-types-and-traits.md @@ -135,7 +135,7 @@ UnwindSafe>` is a valid type. ## `Sized` The [`Sized`] trait indicates that the size of this type is known at compile-time; that is, it's not a [dynamically sized type]. -[Type parameters] are `Sized` by default, as are [associated types]. +[Type parameters] (except `Self` in traits) are `Sized` by default, as are [associated types]. `Sized` is always implemented automatically by the compiler, not by [implementation items]. These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound. diff --git a/src/doc/reference/src/tokens.md b/src/doc/reference/src/tokens.md index 8f9bcb1f7..0067b647d 100644 --- a/src/doc/reference/src/tokens.md +++ b/src/doc/reference/src/tokens.md @@ -72,13 +72,13 @@ Literals are tokens used in [literal expressions]. #### Numbers -| [Number literals](#number-literals)`*` | Example | Exponentiation | Suffixes | -|----------------------------------------|---------|----------------|----------| -| Decimal integer | `98_222` | `N/A` | Integer suffixes | -| Hex integer | `0xff` | `N/A` | Integer suffixes | -| Octal integer | `0o77` | `N/A` | Integer suffixes | -| Binary integer | `0b1111_0000` | `N/A` | Integer suffixes | -| Floating-point | `123.0E+77` | `Optional` | Floating-point suffixes | +| [Number literals](#number-literals)`*` | Example | Exponentiation | +|----------------------------------------|---------|----------------| +| Decimal integer | `98_222` | `N/A` | +| Hex integer | `0xff` | `N/A` | +| Octal integer | `0o77` | `N/A` | +| Binary integer | `0b1111_0000` | `N/A` | +| Floating-point | `123.0E+77` | `Optional` | `*` All number literals allow `_` as a visual separator: `1_234.0E+18f64` @@ -86,17 +86,26 @@ Literals are tokens used in [literal expressions]. A suffix is a sequence of characters following the primary part of a literal (without intervening whitespace), of the same form as a non-raw identifier or keyword. -Any kind of literal (string, integer, etc) with any suffix is valid as a token, -and can be passed to a macro without producing an error. + +> **<sup>Lexer</sup>**\ +> SUFFIX : IDENTIFIER_OR_KEYWORD\ +> SUFFIX_NO_E : SUFFIX <sub>_not beginning with `e` or `E`_</sub> + +Any kind of literal (string, integer, etc) with any suffix is valid as a token. + +A literal token with any suffix can be passed to a macro without producing an error. The macro itself will decide how to interpret such a token and whether to produce an error or not. +In particular, the `literal` fragment specifier for by-example macros matches literal tokens with arbitrary suffixes. ```rust macro_rules! blackhole { ($tt:tt) => () } +macro_rules! blackhole_lit { ($l:literal) => () } blackhole!("string"suffix); // OK +blackhole_lit!(1suffix); // OK ``` -However, suffixes on literal tokens parsed as Rust code are restricted. +However, suffixes on literal tokens which are interpreted as literal expressions or patterns are restricted. Any suffixes are rejected on non-numeric literal tokens, and numeric literal tokens are accepted only with suffixes from the list below. @@ -110,7 +119,7 @@ and numeric literal tokens are accepted only with suffixes from the list below. > **<sup>Lexer</sup>**\ > CHAR_LITERAL :\ -> `'` ( ~\[`'` `\` \\n \\r \\t] | QUOTE_ESCAPE | ASCII_ESCAPE | UNICODE_ESCAPE ) `'` +> `'` ( ~\[`'` `\` \\n \\r \\t] | QUOTE_ESCAPE | ASCII_ESCAPE | UNICODE_ESCAPE ) `'` SUFFIX<sup>?</sup> > > QUOTE_ESCAPE :\ > `\'` | `\"` @@ -136,7 +145,7 @@ which must be _escaped_ by a preceding `U+005C` character (`\`). > | ASCII_ESCAPE\ > | UNICODE_ESCAPE\ > | STRING_CONTINUE\ -> )<sup>\*</sup> `"` +> )<sup>\*</sup> `"` SUFFIX<sup>?</sup> > > STRING_CONTINUE :\ > `\` _followed by_ \\n @@ -196,7 +205,7 @@ following forms: > **<sup>Lexer</sup>**\ > RAW_STRING_LITERAL :\ -> `r` RAW_STRING_CONTENT +> `r` RAW_STRING_CONTENT SUFFIX<sup>?</sup> > > RAW_STRING_CONTENT :\ > `"` ( ~ _IsolatedCR_ )<sup>* (non-greedy)</sup> `"`\ @@ -233,7 +242,7 @@ r##"foo #"# bar"##; // foo #"# bar > **<sup>Lexer</sup>**\ > BYTE_LITERAL :\ -> `b'` ( ASCII_FOR_CHAR | BYTE_ESCAPE ) `'` +> `b'` ( ASCII_FOR_CHAR | BYTE_ESCAPE ) `'` SUFFIX<sup>?</sup> > > ASCII_FOR_CHAR :\ > _any ASCII (i.e. 0x00 to 0x7F), except_ `'`, `\`, \\n, \\r or \\t @@ -253,7 +262,7 @@ _number literal_. > **<sup>Lexer</sup>**\ > BYTE_STRING_LITERAL :\ -> `b"` ( ASCII_FOR_STRING | BYTE_ESCAPE | STRING_CONTINUE )<sup>\*</sup> `"` +> `b"` ( ASCII_FOR_STRING | BYTE_ESCAPE | STRING_CONTINUE )<sup>\*</sup> `"` SUFFIX<sup>?</sup> > > ASCII_FOR_STRING :\ > _any ASCII (i.e 0x00 to 0x7F), except_ `"`, `\` _and IsolatedCR_ @@ -284,7 +293,7 @@ following forms: > **<sup>Lexer</sup>**\ > RAW_BYTE_STRING_LITERAL :\ -> `br` RAW_BYTE_STRING_CONTENT +> `br` RAW_BYTE_STRING_CONTENT SUFFIX<sup>?</sup> > > RAW_BYTE_STRING_CONTENT :\ > `"` ASCII<sup>* (non-greedy)</sup> `"`\ @@ -329,7 +338,7 @@ literal_. The grammar for recognizing the two kinds of literals is mixed. > **<sup>Lexer</sup>**\ > INTEGER_LITERAL :\ > ( DEC_LITERAL | BIN_LITERAL | OCT_LITERAL | HEX_LITERAL ) -> INTEGER_SUFFIX<sup>?</sup> +> SUFFIX_NO_E<sup>?</sup> > > DEC_LITERAL :\ > DEC_DIGIT (DEC_DIGIT|`_`)<sup>\*</sup> @@ -350,10 +359,6 @@ literal_. The grammar for recognizing the two kinds of literals is mixed. > DEC_DIGIT : \[`0`-`9`] > > HEX_DIGIT : \[`0`-`9` `a`-`f` `A`-`F`] -> -> INTEGER_SUFFIX :\ -> `u8` | `u16` | `u32` | `u64` | `u128` | `usize`\ -> | `i8` | `i16` | `i32` | `i64` | `i128` | `isize` An _integer literal_ has one of four forms: @@ -369,11 +374,11 @@ An _integer literal_ has one of four forms: (`0b`) and continues as any mixture (with at least one digit) of binary digits and underscores. -Like any literal, an integer literal may be followed (immediately, without any spaces) by an _integer suffix_, which must be the name of one of the [primitive integer types][numeric types]: -`u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`, `usize`, or `isize`. +Like any literal, an integer literal may be followed (immediately, without any spaces) by a suffix as described above. +The suffix may not begin with `e` or `E`, as that would be interpreted as the exponent of a floating-point literal. See [literal expressions] for the effect of these suffixes. -Examples of integer literals of various forms: +Examples of integer literals which are accepted as literal expressions: ```rust # #![allow(overflowing_literals)] @@ -396,27 +401,27 @@ Examples of integer literals of various forms: 0usize; -// These are too big for their type, but are still valid tokens - +// These are too big for their type, but are accepted as literal expressions. 128_i8; 256_u8; +// This is an integer literal, accepted as a floating-point literal expression. +5f32; ``` Note that `-1i8`, for example, is analyzed as two tokens: `-` followed by `1i8`. -Examples of invalid integer literals: -```rust,compile_fail -// uses numbers of the wrong base +Examples of integer literals which are not accepted as literal expressions: -0b0102; -0o0581; - -// bin, hex, and octal literals must have at least one digit - -0b_; -0b____; +```rust +# #[cfg(FALSE)] { +0invalidSuffix; +123AFB43; +0b010a; +0xAB_CD_EF_GH; +0b1111_f32; +# } ``` #### Tuple index @@ -442,9 +447,8 @@ let cat = example.01; // ERROR no field named `01` let horse = example.0b10; // ERROR no field named `0b10` ``` -> **Note**: The tuple index may include an `INTEGER_SUFFIX`, but this is not -> intended to be valid, and may be removed in a future version. See -> <https://github.com/rust-lang/rust/issues/60210> for more information. +> **Note**: Tuple indices may include certain suffixes, but this is not intended to be valid, and may be removed in a future version. +> See <https://github.com/rust-lang/rust/issues/60210> for more information. #### Floating-point literals @@ -452,38 +456,32 @@ let horse = example.0b10; // ERROR no field named `0b10` > FLOAT_LITERAL :\ > DEC_LITERAL `.` > _(not immediately followed by `.`, `_` or an XID_Start character)_\ -> | DEC_LITERAL FLOAT_EXPONENT\ -> | DEC_LITERAL `.` DEC_LITERAL FLOAT_EXPONENT<sup>?</sup>\ -> | DEC_LITERAL (`.` DEC_LITERAL)<sup>?</sup> -> FLOAT_EXPONENT<sup>?</sup> FLOAT_SUFFIX +> | DEC_LITERAL `.` DEC_LITERAL SUFFIX_NO_E<sup>?</sup>\ +> | DEC_LITERAL (`.` DEC_LITERAL)<sup>?</sup> FLOAT_EXPONENT SUFFIX<sup>?</sup>\ > > FLOAT_EXPONENT :\ > (`e`|`E`) (`+`|`-`)<sup>?</sup> > (DEC_DIGIT|`_`)<sup>\*</sup> DEC_DIGIT (DEC_DIGIT|`_`)<sup>\*</sup> > -> FLOAT_SUFFIX :\ -> `f32` | `f64` -A _floating-point literal_ has one of three forms: +A _floating-point literal_ has one of two forms: * A _decimal literal_ followed by a period character `U+002E` (`.`). This is optionally followed by another decimal literal, with an optional _exponent_. * A single _decimal literal_ followed by an _exponent_. -* A single _decimal literal_ (in which case a suffix is required). Like integer literals, a floating-point literal may be followed by a suffix, so long as the pre-suffix part does not end with `U+002E` (`.`). -There are two valid _floating-point suffixes_: `f32` and `f64` (the names of the 32-bit and 64-bit [primitive floating-point types][floating-point types]). +The suffix may not begin with `e` or `E` if the literal does not include an exponent. See [literal expressions] for the effect of these suffixes. -Examples of floating-point literals of various forms: +Examples of floating-point literals which are accepted as literal expressions: ```rust 123.0f64; 0.1f64; 0.1f32; 12E+99_f64; -5f32; let x: f64 = 2.; ``` @@ -493,39 +491,16 @@ to call a method named `f64` on `2`. Note that `-1.0`, for example, is analyzed as two tokens: `-` followed by `1.0`. -#### Number pseudoliterals - -> **<sup>Lexer</sup>**\ -> NUMBER_PSEUDOLITERAL :\ -> DEC_LITERAL ( . DEC_LITERAL )<sup>?</sup> FLOAT_EXPONENT\ -> ( NUMBER_PSEUDOLITERAL_SUFFIX | INTEGER_SUFFIX )\ -> | DEC_LITERAL . DEC_LITERAL\ -> ( NUMBER_PSEUDOLITERAL_SUFFIX_NO_E | INTEGER SUFFIX )\ -> | DEC_LITERAL NUMBER_PSEUDOLITERAL_SUFFIX_NO_E\ -> | ( BIN_LITERAL | OCT_LITERAL | HEX_LITERAL )\ -> ( NUMBER_PSEUDOLITERAL_SUFFIX_NO_E | FLOAT_SUFFIX ) -> -> NUMBER_PSEUDOLITERAL_SUFFIX :\ -> IDENTIFIER_OR_KEYWORD <sub>_not matching INTEGER_SUFFIX or FLOAT_SUFFIX_</sub> -> -> NUMBER_PSEUDOLITERAL_SUFFIX_NO_E :\ -> NUMBER_PSEUDOLITERAL_SUFFIX <sub>_not beginning with `e` or `E`_</sub> - -Tokenization of numeric literals allows arbitrary suffixes as described in the grammar above. -These values generate valid tokens, but are not valid [literal expressions], so are usually an error except as macro arguments. +Examples of floating-point literals which are not accepted as literal expressions: -Examples of such tokens: -```rust,compile_fail -0invalidSuffix; -123AFB43; -0b010a; -0xAB_CD_EF_GH; +```rust +# #[cfg(FALSE)] { 2.0f80; 2e5f80; 2e5e6; 2.0e5e6; 1.3e10u64; -0b1111_f32; +# } ``` #### Reserved forms similar to number literals @@ -536,7 +511,7 @@ Examples of such tokens: > | OCT_LITERAL \[`8`-`9`​]\ > | ( BIN_LITERAL | OCT_LITERAL | HEX_LITERAL ) `.` \ > _(not immediately followed by `.`, `_` or an XID_Start character)_\ -> | ( BIN_LITERAL | OCT_LITERAL ) `e`\ +> | ( BIN_LITERAL | OCT_LITERAL ) (`e`|`E`)\ > | `0b` `_`<sup>\*</sup> _end of input or not BIN_DIGIT_\ > | `0o` `_`<sup>\*</sup> _end of input or not OCT_DIGIT_\ > | `0x` `_`<sup>\*</sup> _end of input or not HEX_DIGIT_\ @@ -549,7 +524,7 @@ Due to the possible ambiguity these raise, they are rejected by the tokenizer in * An unsuffixed binary, octal, or hexadecimal literal followed, without intervening whitespace, by a period character (with the same restrictions on what follows the period as for floating-point literals). -* An unsuffixed binary or octal literal followed, without intervening whitespace, by the character `e`. +* An unsuffixed binary or octal literal followed, without intervening whitespace, by the character `e` or `E`. * Input which begins with one of the radix prefixes but is not a valid binary, octal, or hexadecimal literal (because it contains no digits). @@ -561,13 +536,13 @@ Examples of reserved forms: 0b0102; // this is not `0b010` followed by `2` 0o1279; // this is not `0o127` followed by `9` 0x80.0; // this is not `0x80` followed by `.` and `0` -0b101e; // this is not a pseudoliteral, or `0b101` followed by `e` -0b; // this is not a pseudoliteral, or `0` followed by `b` -0b_; // this is not a pseudoliteral, or `0` followed by `b_` -2e; // this is not a pseudoliteral, or `2` followed by `e` -2.0e; // this is not a pseudoliteral, or `2.0` followed by `e` -2em; // this is not a pseudoliteral, or `2` followed by `em` -2.0em; // this is not a pseudoliteral, or `2.0` followed by `em` +0b101e; // this is not a suffixed literal, or `0b101` followed by `e` +0b; // this is not an integer literal, or `0` followed by `b` +0b_; // this is not an integer literal, or `0` followed by `b_` +2e; // this is not a floating-point literal, or `2` followed by `e` +2.0e; // this is not a floating-point literal, or `2.0` followed by `e` +2em; // this is not a suffixed literal, or `2` followed by `em` +2.0em; // this is not a suffixed literal, or `2.0` followed by `em` ``` ## Lifetimes and loop labels diff --git a/src/doc/reference/src/trait-bounds.md b/src/doc/reference/src/trait-bounds.md index f284ca4eb..c8dab3f1c 100644 --- a/src/doc/reference/src/trait-bounds.md +++ b/src/doc/reference/src/trait-bounds.md @@ -121,7 +121,7 @@ For example, if `'a` is an unconstrained lifetime parameter, then `i32: 'static` > _ForLifetimes_ :\ > `for` [_GenericParams_] -Type bounds may be *higher ranked* over lifetimes. These bounds specify a bound +Trait bounds may be *higher ranked* over lifetimes. These bounds specify a bound that is true *for all* lifetimes. For example, a bound such as `for<'a> &'a T: PartialEq<i32>` would require an implementation like diff --git a/src/doc/rust-by-example/.github/workflows/rbe.yml b/src/doc/rust-by-example/.github/workflows/rbe.yml index 94b7cdc95..76b127b96 100644 --- a/src/doc/rust-by-example/.github/workflows/rbe.yml +++ b/src/doc/rust-by-example/.github/workflows/rbe.yml @@ -42,7 +42,7 @@ jobs: sh linkcheck.sh --all rust-by-example - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v3 with: name: rust-by-example path: book diff --git a/src/doc/rust-by-example/src/crates/using_lib.md b/src/doc/rust-by-example/src/crates/using_lib.md index 102080700..8bd0feb94 100644 --- a/src/doc/rust-by-example/src/crates/using_lib.md +++ b/src/doc/rust-by-example/src/crates/using_lib.md @@ -20,7 +20,7 @@ fn main() { ```txt # Where library.rlib is the path to the compiled library, assumed that it's # in the same directory here: -$ rustc executable.rs --extern rary=library.rlib --edition=2018 && ./executable +$ rustc executable.rs --extern rary=library.rlib && ./executable called rary's `public_function()` called rary's `indirect_access()`, that > called rary's `private_function()` diff --git a/src/doc/rust-by-example/src/fn/closures.md b/src/doc/rust-by-example/src/fn/closures.md index 0c1b999ef..82286003b 100644 --- a/src/doc/rust-by-example/src/fn/closures.md +++ b/src/doc/rust-by-example/src/fn/closures.md @@ -19,21 +19,23 @@ Other characteristics of closures include: ```rust,editable fn main() { - // Increment via closures and functions. - fn function(i: i32) -> i32 { i + 1 } + let outer_var = 42; + + // A regular function can't refer to variables in the enclosing environment + //fn function(i: i32) -> i32 { i + outer_var } + // TODO: uncomment the line above and see the compiler error. The compiler + // suggests that we define a closure instead. // Closures are anonymous, here we are binding them to references // Annotation is identical to function annotation but is optional // as are the `{}` wrapping the body. These nameless functions // are assigned to appropriately named variables. - let closure_annotated = |i: i32| -> i32 { i + 1 }; - let closure_inferred = |i | i + 1 ; - - let i = 1; - // Call the function and closures. - println!("function: {}", function(i)); - println!("closure_annotated: {}", closure_annotated(i)); - println!("closure_inferred: {}", closure_inferred(i)); + let closure_annotated = |i: i32| -> i32 { i + outer_var }; + let closure_inferred = |i | i + outer_var ; + + // Call the closures. + println!("closure_annotated: {}", closure_annotated(1)); + println!("closure_inferred: {}", closure_inferred(1)); // Once closure's type has been inferred, it cannot be inferred again with another type. //println!("cannot reuse closure_inferred with another type: {}", closure_inferred(42i64)); // TODO: uncomment the line above and see the compiler error. diff --git a/src/doc/rust-by-example/src/fn/closures/input_parameters.md b/src/doc/rust-by-example/src/fn/closures/input_parameters.md index 8f4307ff5..41497179f 100644 --- a/src/doc/rust-by-example/src/fn/closures/input_parameters.md +++ b/src/doc/rust-by-example/src/fn/closures/input_parameters.md @@ -22,7 +22,7 @@ closure. This is because if a move is possible, then any type of borrow should also be possible. Note that the reverse is not true. If the parameter is annotated as `Fn`, then capturing variables by `&mut T` or `T` are not -allowed. +allowed. However, `&T` is allowed. In the following example, try swapping the usage of `Fn`, `FnMut`, and `FnOnce` to see what happens: diff --git a/src/doc/rust-by-example/src/hello/print.md b/src/doc/rust-by-example/src/hello/print.md index c28dd9125..cce838fc2 100644 --- a/src/doc/rust-by-example/src/hello/print.md +++ b/src/doc/rust-by-example/src/hello/print.md @@ -68,7 +68,7 @@ fn main() { // For Rust 1.58 and above, you can directly capture the argument from a // surrounding variable. Just like the above, this will output - // " 1". 5 white spaces and a "1". + // " 1". 4 white spaces and a "1". let number: f64 = 1.0; let width: usize = 5; println!("{number:>width$}"); diff --git a/src/doc/rust-by-example/src/scope/lifetime.md b/src/doc/rust-by-example/src/scope/lifetime.md index 33ffcae71..01c4bf405 100644 --- a/src/doc/rust-by-example/src/scope/lifetime.md +++ b/src/doc/rust-by-example/src/scope/lifetime.md @@ -26,7 +26,7 @@ fn main() { let borrow1 = &i; // `borrow1` lifetime starts. ──┐│ // ││ println!("borrow1: {}", borrow1); // ││ - } // `borrow1 ends. ──────────────────────────────────┘│ + } // `borrow1` ends. ─────────────────────────────────┘│ // │ // │ { // │ diff --git a/src/doc/rust-by-example/src/std_misc/file/read_lines.md b/src/doc/rust-by-example/src/std_misc/file/read_lines.md index 6792b1706..641eb972a 100644 --- a/src/doc/rust-by-example/src/std_misc/file/read_lines.md +++ b/src/doc/rust-by-example/src/std_misc/file/read_lines.md @@ -1,5 +1,39 @@ # `read_lines` +## Beginner friendly method +This method is NOT efficient. It's here for beginners +who can't understand the efficient method yet. + +```rust,no_run +use std::fs::File; +use std::io::{ self, BufRead, BufReader }; + +fn read_lines(filename: String) -> io::Lines<BufReader<File>> { + // Open the file in read-only mode. + let file = File::open(filename).unwrap(); + // Read the file line by line, and return an iterator of the lines of the file. + return io::BufReader::new(file).lines(); +} + +fn main() { + // Stores the iterator of lines of the file in lines variable. + let lines = read_lines("./hosts".to_string()); + // Iterate over the lines of the file, and in this case print them. + for line in lines { + println!("{}", line.unwrap()); + } +} +``` + +Running this program simply prints the lines individually. +```shell +$ echo -e "127.0.0.1\n192.168.0.1\n" > hosts +$ rustc read_lines.rs && ./read_lines +127.0.0.1 +192.168.0.1 +``` + +## Efficient method The method `lines()` returns an iterator over the lines of a file. diff --git a/src/doc/rust-by-example/src/types/cast.md b/src/doc/rust-by-example/src/types/cast.md index deed34cf7..3078d82c1 100644 --- a/src/doc/rust-by-example/src/types/cast.md +++ b/src/doc/rust-by-example/src/types/cast.md @@ -22,7 +22,7 @@ fn main() { let integer = decimal as u8; let character = integer as char; - // Error! There are limitations in conversion rules. + // Error! There are limitations in conversion rules. // A float cannot be directly converted to a char. let character = decimal as char; // FIXME ^ Comment out this line @@ -52,7 +52,7 @@ fn main() { // Unless it already fits, of course. println!(" 128 as a i16 is: {}", 128 as i16); - + // 128 as u8 -> 128, whose value in 8-bit two's complement representation is: println!(" 128 as a i8 is : {}", 128 as i8); @@ -61,21 +61,21 @@ fn main() { println!("1000 as a u8 is : {}", 1000 as u8); // and the value of 232 in 8-bit two's complement representation is -24 println!(" 232 as a i8 is : {}", 232 as i8); - - // Since Rust 1.45, the `as` keyword performs a *saturating cast* - // when casting from float to int. If the floating point value exceeds - // the upper bound or is less than the lower bound, the returned value + + // Since Rust 1.45, the `as` keyword performs a *saturating cast* + // when casting from float to int. If the floating point value exceeds + // the upper bound or is less than the lower bound, the returned value // will be equal to the bound crossed. - + // 300.0 as u8 is 255 println!(" 300.0 as u8 is : {}", 300.0_f32 as u8); // -100.0 as u8 is 0 println!("-100.0 as u8 is : {}", -100.0_f32 as u8); // nan as u8 is 0 println!(" nan as u8 is : {}", f32::NAN as u8); - - // This behavior incurs a small runtime cost and can be avoided - // with unsafe methods, however the results might overflow and + + // This behavior incurs a small runtime cost and can be avoided + // with unsafe methods, however the results might overflow and // return **unsound values**. Use these methods wisely: unsafe { // 300.0 as u8 is 44 diff --git a/src/doc/rust-by-example/triagebot.toml b/src/doc/rust-by-example/triagebot.toml index fa0824ac5..5b70fd0c4 100644 --- a/src/doc/rust-by-example/triagebot.toml +++ b/src/doc/rust-by-example/triagebot.toml @@ -1 +1,4 @@ [assign] + +[assign.owners] +"*" = ["@marioidival"] diff --git a/src/doc/rustc-dev-guide/src/asm.md b/src/doc/rustc-dev-guide/src/asm.md index cd5430ffd..9b5a82f34 100644 --- a/src/doc/rustc-dev-guide/src/asm.md +++ b/src/doc/rustc-dev-guide/src/asm.md @@ -10,12 +10,13 @@ through all of the compiler layers down to LLVM codegen. Throughout the various - The template string, which is stored as an array of `InlineAsmTemplatePiece`. Each piece represents either a literal or a placeholder for an operand (just like format strings). -```rust -pub enum InlineAsmTemplatePiece { - String(String), - Placeholder { operand_idx: usize, modifier: Option<char>, span: Span }, -} -``` + + ```rust + pub enum InlineAsmTemplatePiece { + String(String), + Placeholder { operand_idx: usize, modifier: Option<char>, span: Span }, + } + ``` - The list of operands to the `asm!` (`in`, `[late]out`, `in[late]out`, `sym`, `const`). These are represented differently at each stage of lowering, but follow a common pattern: @@ -34,21 +35,22 @@ or a `fn`. - The options set at the end of the `asm!` macro. The only ones that are of particular interest to rustc are `NORETURN` which makes `asm!` return `!` instead of `()`, and `RAW` which disables format string parsing. The remaining options are mostly passed through to LLVM with little processing. -```rust -bitflags::bitflags! { - pub struct InlineAsmOptions: u16 { - const PURE = 1 << 0; - const NOMEM = 1 << 1; - const READONLY = 1 << 2; - const PRESERVES_FLAGS = 1 << 3; - const NORETURN = 1 << 4; - const NOSTACK = 1 << 5; - const ATT_SYNTAX = 1 << 6; - const RAW = 1 << 7; - const MAY_UNWIND = 1 << 8; - } -} -``` + + ```rust + bitflags::bitflags! { + pub struct InlineAsmOptions: u16 { + const PURE = 1 << 0; + const NOMEM = 1 << 1; + const READONLY = 1 << 2; + const PRESERVES_FLAGS = 1 << 3; + const NORETURN = 1 << 4; + const NOSTACK = 1 << 5; + const ATT_SYNTAX = 1 << 6; + const RAW = 1 << 7; + const MAY_UNWIND = 1 << 8; + } + } + ``` ## AST diff --git a/src/doc/rustc-dev-guide/src/backend/monomorph.md b/src/doc/rustc-dev-guide/src/backend/monomorph.md index 416151ca9..21a788203 100644 --- a/src/doc/rustc-dev-guide/src/backend/monomorph.md +++ b/src/doc/rustc-dev-guide/src/backend/monomorph.md @@ -70,7 +70,7 @@ or more modules in Crate B. | Crate A function | Behavior | | - | - | | Non-generic function | Crate A function doesn't appear in any codegen units of Crate B | -| Non-generic `#[inline]` function | Crate A function appears with in a single CGU of Crate B, and exists even after post-inlining stage| +| Non-generic `#[inline]` function | Crate A function appears within a single CGU of Crate B, and exists even after post-inlining stage| | Generic function | Regardless of inlining, all monomorphized (specialized) functions <br> from Crate A appear within a single codegen unit for Crate B. <br> The codegen unit exists even after the post inlining stage.| | Generic `#[inline]` function | - same - | diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md index 81ebbbb40..38fbb2e44 100644 --- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md +++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md @@ -2,35 +2,25 @@ <!-- toc --> -The Rust compiler uses LLVM as its primary codegen backend today, and naturally -we want to at least occasionally update this dependency! Currently we do not -have a strict policy about when to update LLVM or what it can be updated to, but -a few guidelines are applied: +<!-- date-check: Aug 2022 --> +There is no formal policy about when to update LLVM or what it can be updated to, +but a few guidelines are applied: -* We try to always support the latest released version of LLVM -* We try to support the "last few" versions of LLVM (how many is changing over - time) -* We allow moving to arbitrary commits during development. -* Strongly prefer to upstream all patches to LLVM before including them in - rustc. - -This policy may change over time (or may actually start to exist as a formal -policy!), but for now these are rough guidelines! +* We try to always support the latest released version +* We try to support the last few versions + (and the number changes over time) +* We allow moving to arbitrary commits during development +* We strongly prefer to upstream all patches to LLVM before including them in rustc ## Why update LLVM? -There are a few reasons nowadays that we want to update LLVM in one way or -another: +There are two reasons we would want to update LLVM: * A bug could have been fixed! Often we find bugs in the compiler and fix them upstream in LLVM. We'll want to pull fixes back to the compiler itself as they're merged upstream. -* A new feature may be available in LLVM that we want to use in rustc, - but we don't want to wait for a full LLVM release to test it out. - -* LLVM itself may have a new release and we'd like to update to this LLVM - release. +* LLVM itself may have a new release. Each of these reasons has a different strategy for updating LLVM, and we'll go over them in detail here. @@ -57,59 +47,67 @@ the branch we're already using. The steps for this are: src/llvm-project` typically. 10. Wait for PR to be merged -The tl;dr; is that we can cherry-pick bugfixes at any time and pull them back -into the rust-lang/llvm-project branch that we're using, and getting it into the -compiler is just updating the submodule via a PR! - -Example PRs look like: +An example PR: [#59089](https://github.com/rust-lang/rust/pull/59089) -## Feature updates - -> Note that this information is as of the time of this writing, <!-- -date-check --> October 2021. The process for updating LLVM changes with -practically all LLVM updates, so this may be out of date! - -Unlike bugfixes, updating to pick up a new feature of LLVM typically requires a -lot more work. This is where we can't reasonably cherry-pick commits backwards -so we need to do a full update. There's a lot of stuff to do here, so let's go -through each in detail. - -1. Create a new branch in the [rust-lang/llvm-project repository]. This branch - should be named `rustc/a.b-yyyy-mm-dd` where `a.b` is the current version - number of LLVM in-tree at the time of the branch and the remaining part is - today's date. Move this branch to the commit in LLVM that you'd like, which - for this is probably the current LLVM HEAD. - -2. Apply Rust-specific patches to the llvm-project repository. All features and - bugfixes are upstream, but there's often some weird build-related patches - that don't make sense to upstream which we have on our repositories. These - patches are around the latest patches in the rust-lang/llvm-project branch - that rustc is currently using. +## New LLVM Release Updates -3. Build the new LLVM in the `rust` repository. To do this you'll want to update - the `src/llvm-project` repository to your branch and the revision you've - created. It's also typically a good idea to update `.gitmodules` with the new - branch name of the LLVM submodule. Make sure you've committed changes to - `src/llvm-project` to ensure submodule updates aren't reverted. Some commands - you should execute are: +<!-- date-check: Aug 2022 --> + +Unlike bugfixes, +updating to a new release of LLVM typically requires a lot more work. +This is where we can't reasonably cherry-pick commits backwards, +so we need to do a full update. +There's a lot of stuff to do here, +so let's go through each in detail. + +1. LLVM announces that its latest release version has branched. + This will show up as a branch in the [llvm/llvm-project repository], + typically named `release/$N.x`, + where `$N` is the version of LLVM that's being released. + +1. Create a new branch in the [rust-lang/llvm-project repository] + from this `release/$N.x` branch, + and name it `rustc/a.b-yyyy-mm-dd`, + where `a.b` is the current version number of LLVM in-tree + at the time of the branch, + and the remaining part is the current date. + +2. Apply Rust-specific patches to the llvm-project repository. + All features and bugfixes are upstream, + but there's often some weird build-related patches + that don't make sense to upstream. + These patches are typically the latest patches in the + rust-lang/llvm-project branch that rustc is currently using. + +3. Build the new LLVM in the `rust` repository. + To do this, + you'll want to update the `src/llvm-project` repository to your branch, + and the revision you've created. + It's also typically a good idea to update `.gitmodules` with the new + branch name of the LLVM submodule. + Make sure you've committed changes to + `src/llvm-project` to ensure submodule updates aren't reverted. + Some commands you should execute are: * `./x.py build src/llvm` - test that LLVM still builds * `./x.py build src/tools/lld` - same for LLD * `./x.py build` - build the rest of rustc - You'll likely need to update [`llvm-wrapper/*.cpp`][`llvm-wrapper`] to compile - with updated LLVM bindings. Note that you should use `#ifdef` and such to ensure + You'll likely need to update [`llvm-wrapper/*.cpp`][`llvm-wrapper`] + to compile with updated LLVM bindings. + Note that you should use `#ifdef` and such to ensure that the bindings still compile on older LLVM versions. Note that `profile = "compiler"` and other defaults set by `./x.py setup` - download LLVM from CI instead of building it from source. You should - disable this temporarily to make sure your changes are being used, by setting + download LLVM from CI instead of building it from source. + You should disable this temporarily to make sure your changes are being used. + This is done by having the following setting in `config.toml`: + ```toml [llvm] download-ci-llvm = false ``` - in config.toml. 4. Test for regressions across other platforms. LLVM often has at least one bug for non-tier-1 architectures, so it's good to do some more testing before @@ -122,7 +120,7 @@ through each in detail. * macOS * Windows - and afterwards run some docker containers that CI also does: + Afterwards, run some docker containers that CI also does: * `./src/ci/docker/run.sh wasm32` * `./src/ci/docker/run.sh arm-android` @@ -135,16 +133,39 @@ through each in detail. and then you can send a PR to `rust-lang/rust`. You'll change at least `src/llvm-project` and will likely also change [`llvm-wrapper`] as well. -For prior art, previous LLVM updates look like -[#62474](https://github.com/rust-lang/rust/pull/62474) -[#62592](https://github.com/rust-lang/rust/pull/62592) -[#67759](https://github.com/rust-lang/rust/pull/67759) -[#73526](https://github.com/rust-lang/rust/pull/73526) -[#81451](https://github.com/rust-lang/rust/pull/81451). Note that sometimes it's -easiest to land [`llvm-wrapper`] compatibility as a PR before actually updating -`src/llvm-project`. This way while you're working through LLVM issues others -interested in trying out the new LLVM can benefit from work you've done to -update the C++ bindings. + > For prior art, here are some previous LLVM updates: + > - [LLVM 11](https://github.com/rust-lang/rust/pull/73526) + > - [LLVM 12](https://github.com/rust-lang/rust/pull/81451) + > - [LLVM 13](https://github.com/rust-lang/rust/pull/87570) + > - [LLVM 14](https://github.com/rust-lang/rust/pull/93577) + > - [LLVM 15](https://github.com/rust-lang/rust/pull/99464) + + Note that sometimes it's easiest to land [`llvm-wrapper`] compatibility as a PR + before actually updating `src/llvm-project`. + This way, + while you're working through LLVM issues, + others interested in trying out the new LLVM can benefit from work you've done + to update the C++ bindings. + +3. Over the next few months, + LLVM will continually push commits to its `release/a.b` branch. + We will often want to have those bug fixes as well. + The merge process for that is to use `git merge` itself to merge LLVM's + `release/a.b` branch with the branch created in step 2. + This is typically + done multiple times when necessary while LLVM's release branch is baking. + +4. LLVM then announces the release of version `a.b`. + +5. After LLVM's official release, + we follow the process of creating a new branch on the + rust-lang/llvm-project repository again, + this time with a new date. + It is only then that the PR to update Rust to use that version is merged. + + The commit history of `rust-lang/llvm-project` + should look much cleaner as a `git rebase` is done, + where just a few Rust-specific commits are stacked on top of stock LLVM's release branch. ### Caveats and gotchas @@ -158,35 +179,6 @@ keep in mind while going through them: * Creating branches is a privileged operation on GitHub, so you'll need someone with write access to create the branches for you most likely. -## New LLVM Release Updates - -Updating to a new release of LLVM is very similar to the "feature updates" -section above. The release process for LLVM is often months-long though and we -like to ensure compatibility ASAP. The main tweaks to the "feature updates" -section above is generally around branch naming. The sequence of events -typically looks like: - -1. LLVM announces that its latest release version has branched. This will show - up as a branch in the [llvm/llvm-project repository] typically named - `release/$N.x` where `$N` is the version of LLVM that's being released. - -2. We then follow the "feature updates" section above to create a new branch of - LLVM in our rust-lang/llvm-project repository. This follows the same naming - convention of branches as usual, except that `a.b` is the new version. This - update is eventually landed in the rust-lang/rust repository. - -3. Over the next few months, LLVM will continually push commits to its - `release/a.b` branch. Often those are bug fixes we'd like to have as well. - The merge process for that is to use `git merge` itself to merge LLVM's - `release/a.b` branch with the branch created in step 2. This is typically - done multiple times when necessary while LLVM's release branch is baking. - -4. LLVM then announces the release of version `a.b`. - -5. After LLVM's official release, we follow the "feature update" section again - to create a new branch in the rust-lang/llvm-project repository, this time - with a new date. The commit history should look much cleaner as just a few - Rust-specific commits stacked on top of stock LLVM's release branch. [rust-lang/llvm-project repository]: https://github.com/rust-lang/llvm-project [llvm/llvm-project repository]: https://github.com/llvm/llvm-project diff --git a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md index 8702f8aa9..2f5e24716 100644 --- a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md +++ b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md @@ -53,9 +53,9 @@ Please see [the RFC][rfc 1122] for full details! The procedure for making a breaking change is as follows (each of these steps is described in more detail below): -0. Do a **crater run** to assess the impact of the change. -1. Make a **special tracking issue** dedicated to the change. -1. Do not report an error right away. Instead, **issue forwards-compatibility +1. Do a **crater run** to assess the impact of the change. +2. Make a **special tracking issue** dedicated to the change. +3. Do not report an error right away. Instead, **issue forwards-compatibility lint warnings**. - Sometimes this is not straightforward. See the text below for suggestions on different techniques we have employed in the past. @@ -65,7 +65,7 @@ described in more detail below): - Submit PRs to all known affected crates that fix the issue - or, at minimum, alert the owners of those crates to the problem and direct them to the tracking issue -1. Once the change has been in the wild for at least one cycle, we can +4. Once the change has been in the wild for at least one cycle, we can **stabilize the change**, converting those warnings into errors. Finally, for changes to `rustc_ast` that will affect plugins, the general policy diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index c5cf3166d..46d4b9c04 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -152,7 +152,9 @@ is what you need to build other Rust programs (unless you use `#![no_std]` or You will probably find that building the stage1 `std` is a bottleneck for you, but fear not, there is a (hacky) workaround... -see [the section on "recommended workflows"](./suggested.md) below. +see [the section on avoiding rebuilds for std][keep-stage]. + +[keep-stage]: ./suggested.md#faster-builds-with---keep-stage Note that this whole command just gives you a subset of the full `rustc` build. The **full** `rustc` build (what you get with `./x.py build diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index 5c5e571e4..a85229c6a 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -8,8 +8,9 @@ to make your life easier. CI will automatically fail your build if it doesn't pass `tidy`, our internal tool for ensuring code quality. If you'd like, you can install a [Git hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) -that will automatically run `./x.py test tidy --bless` on each push, to ensure -your code is up to par. If you decide later that this behavior is +that will automatically run `./x.py test tidy` on each push, to ensure +your code is up to par. If the hook fails then run `./x.py test tidy --bless` +and commit the changes. If you decide later that the pre-push behavior is undesirable, you can delete the `pre-push` file in `.git/hooks`. A prebuilt git hook lives at [`src/etc/pre-push.sh`](https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh) which can be copied into your `.git/hooks` folder as `pre-push` (without the `.sh` extension!). @@ -22,7 +23,7 @@ You can also install the hook as a step of running `./x.py setup`! a file. By default, `rust-analyzer` runs the `cargo check` and `rustfmt` commands, but you can override these commands to use more adapted versions of these tools when hacking on `rustc`. For example, for Visual Studio Code, -you can write: <!-- date-check: apr 2022 --><!-- the date comment is for the edition below --> +you can write: <!-- date-check: nov 2022 --><!-- the date comment is for the edition below --> ```JSON { @@ -135,13 +136,13 @@ lets you use `cargo fmt`. [the section on vscode]: suggested.md#configuring-rust-analyzer-for-rustc [the section on rustup]: how-to-build-and-run.md?highlight=rustup#creating-a-rustup-toolchain -## Incremental builds with `--keep-stage`. +## Faster builds with `--keep-stage`. Sometimes just checking whether the compiler builds is not enough. A common example is that you need to add a `debug!` statement to inspect the value of some state or better understand the problem. In that case, you really need -a full build. By leveraging incremental, though, you can often get +a full build. By bypassing bootstrap's cache invalidation, you can often get these builds to complete very fast (e.g., around 30 seconds). The only catch is this requires a bit of fudging and may produce compilers that don't work (but that is easily detected and fixed). diff --git a/src/doc/rustc-dev-guide/src/closure.md b/src/doc/rustc-dev-guide/src/closure.md index c3906a80b..5746fd4de 100644 --- a/src/doc/rustc-dev-guide/src/closure.md +++ b/src/doc/rustc-dev-guide/src/closure.md @@ -142,11 +142,11 @@ declared in the file [`compiler/rustc_middle/src/ty/mod.rs`][ty]. [ty]:https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/index.html Before we go any further, let's discuss how we can examine the flow of control through the rustc -codebase. For closures specifically, set the `RUST_LOG` env variable as below and collect the +codebase. For closures specifically, set the `RUSTC_LOG` env variable as below and collect the output in a file: ```console -> RUST_LOG=rustc_hir_typeck::upvar rustc +stage1 -Z dump-mir=all \ +> RUSTC_LOG=rustc_hir_typeck::upvar rustc +stage1 -Z dump-mir=all \ <.rs file to compile> 2> <file where the output will be dumped> ``` diff --git a/src/doc/rustc-dev-guide/src/compiler-team.md b/src/doc/rustc-dev-guide/src/compiler-team.md index abdeac3d2..4570fd3fa 100644 --- a/src/doc/rustc-dev-guide/src/compiler-team.md +++ b/src/doc/rustc-dev-guide/src/compiler-team.md @@ -111,20 +111,22 @@ The guidelines for reviewers are as follows: [Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct -### high-five +### Reviewer rotation -Once you have r+ rights, you can also be added to the [high-five][hi5] -rotation. high-five is the bot that assigns incoming PRs to -reviewers. If you are added, you will be randomly selected to review +Once you have r+ rights, you can also be added to the [reviewer rotation]. +[triagebot] is the bot that [automatically assigns] incoming PRs to reviewers. +If you are added, you will be randomly selected to review PRs. If you find you are assigned a PR that you don't feel comfortable reviewing, you can also leave a comment like `r? @so-and-so` to assign to someone else — if you don't know who to request, just write `r? @nikomatsakis for reassignment` and @nikomatsakis will pick someone for you. -[hi5]: https://github.com/rust-highfive +[reviewer rotation]: https://github.com/rust-lang/rust/blob/36285c5de8915ecc00d91ae0baa79a87ed5858d5/triagebot.toml#L528-L577 +[triagebot]: https://github.com/rust-lang/triagebot/ +[automatically assigns]: https://github.com/rust-lang/triagebot/wiki/Assignment -Getting on the high-five list is much appreciated as it lowers the +Getting on the reviewer rotation is much appreciated as it lowers the review burden for all of us! However, if you don't have time to give people timely feedback on their PRs, it may be better that you don't get on the list. diff --git a/src/doc/rustc-dev-guide/src/constants.md b/src/doc/rustc-dev-guide/src/constants.md index 4f1027b98..a33a283f3 100644 --- a/src/doc/rustc-dev-guide/src/constants.md +++ b/src/doc/rustc-dev-guide/src/constants.md @@ -79,4 +79,4 @@ the constant doesn't use them in any way. This can cause [`ty::Const`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Const.html [`ty::ConstKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.ConstKind.html [`ty::TyKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html -[pcg-unused-substs]: https://github.com/rust-lang/project-const-generics/blob/master/design-docs/anon-const-substs.md#unused-substs
\ No newline at end of file +[pcg-unused-substs]: https://github.com/rust-lang/project-const-generics/issues/33 diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 279bc2f28..41ad1c915 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -73,7 +73,7 @@ when contributing to Rust under [the git section](./git.md). ### r? All pull requests are reviewed by another person. We have a bot, -[@rust-highfive][rust-highfive], that will automatically assign a random person +[@rustbot], that will automatically assign a random person to review your request based on which files you changed. If you want to request that a specific person reviews your pull request, you @@ -82,7 +82,7 @@ if you want to ask a review to @awesome-reviewer, add r? @awesome-reviewer -to the end of the pull request description, and [@rust-highfive][rust-highfive] will assign +to the end of the pull request description, and [@rustbot] will assign them instead of a random person. This is entirely optional. You can also assign a random reviewer from a specific team by writing `r? rust-lang/groupname`. @@ -91,8 +91,10 @@ team by adding: r? rust-lang/diagnostics -For a full list of possible `groupname` check the `groups` section at the -[rust highfive config file](https://github.com/rust-lang/highfive/blob/master/highfive/configs/rust-lang/rust.json). +For a full list of possible `groupname` check the `adhoc_groups` section at the +[triagebot.toml config file](https://github.com/rust-lang/rust/blob/master/triagebot.toml) +or the list of teams in the [rust-lang teams +database](https://github.com/rust-lang/team/tree/master/teams). ### CI @@ -133,7 +135,7 @@ Changes that are rolled up are tested and merged alongside other PRs, to speed the process up. Typically only small changes that are expected not to conflict with one another are marked as "always roll up". -[rust-highfive]: https://github.com/rust-highfive +[@rustbot]: https://github.com/rustbot [@bors]: https://github.com/bors [merge-queue]: https://bors.rust-lang.org/queue/rust @@ -189,8 +191,10 @@ differently from other crates that are directly in this repo: In contrast to `submodule` dependencies (see below for those), the `subtree` dependencies are just regular files and directories which can -be updated in tree. However, enhancements, bug fixes, etc. specific to these tools should be filed -against the tools directly in their respective upstream repositories. +be updated in tree. However, if possible, enhancements, bug fixes, etc. specific +to these tools should be filed against the tools directly in their respective +upstream repositories. The exception is that when rustc changes are required to +implement a new tool feature or test, that should happen in one collective rustc PR. #### Synchronizing a subtree diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index 0d5f17b99..4dd0a2da9 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -21,7 +21,7 @@ Formatting is checked by the `tidy` script. It runs automatically when you do If you want to use format-on-save in your editor, the pinned version of `rustfmt` is built under `build/<target>/stage0/bin/rustfmt`. You'll have to -pass the <!-- date-check: April 2022 --> `--edition=2021` argument yourself when calling +pass the <!-- date-check: nov 2022 --> `--edition=2021` argument yourself when calling `rustfmt` directly. [fmt]: https://github.com/rust-dev-tools/fmt-rfcs diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md index d51e79348..e26ba5f34 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md @@ -28,8 +28,10 @@ pub struct FieldAlreadyDeclared { } ``` -`Diagnostic` can only be applied to structs. Every `Diagnostic` -has to have one attribute, `#[diag(...)]`, applied to the struct itself. +`Diagnostic` can only be applied to structs and enums. +Attributes that are placed on the type for structs are placed on each +variants for enums (or vice versa). Each `Diagnostic` has to have one +attribute, `#[diag(...)]`, applied to the struct or each enum variant. If an error has an error code (e.g. "E0624"), then that can be specified using the `code` sub-attribute. Specifying a `code` isn't mandatory, but if you are @@ -198,9 +200,9 @@ following attributes: - See [translation documentation](./translation.md). - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or - `.suggestion` in Fluent). - - `code = "..."` (_Mandatory_) - - Value is a format string indicating the code to be suggested as a - replacement. + - `code = "..."`/`code("...", ...)` (_Mandatory_) + - One or multiple format strings indicating the code to be suggested as a + replacement. Multiple values signify multiple possible replacements. - `applicability = "..."` (_Optional_) - String which must be one of `machine-applicable`, `maybe-incorrect`, `has-placeholders` or `unspecified`. @@ -243,7 +245,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> { } ``` -Unlike `Diagnostic`, `Subdiagnostic` can be applied to structs or +Like `Diagnostic`, `Subdiagnostic` can be applied to structs or enums. Attributes that are placed on the type for structs are placed on each variants for enums (or vice versa). Each `Subdiagnostic` should have one attribute applied to the struct or each variant, one of: @@ -357,9 +359,9 @@ diagnostic struct. - See [translation documentation](./translation.md). - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or - `.suggestion` in Fluent). - - `code = "..."` (_Mandatory_) - - Value is a format string indicating the code to be suggested as a - replacement. + - `code = "..."`/`code("...", ...)` (_Mandatory_) + - One or multiple format strings indicating the code to be suggested as a + replacement. Multiple values signify multiple possible replacements. - `applicability = "..."` (_Optional_) - _Mutually exclusive with `#[applicability]` on a field._ - Value is the applicability of the suggestion. diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md index 33d9646f6..603c9ed65 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md @@ -14,11 +14,6 @@ There are two parts to the linting mechanism within the compiler: lints and lint passes. Unfortunately, a lot of the documentation we have refers to both of these as just "lints." -First, we have the lint declarations themselves: this is where the name and -default lint level and other metadata come from. These are normally defined by -way of the [`declare_lint!`] macro, which boils down to a static with type -[`&rustc_lint_defs::Lint`]. - First, we have the lint declarations themselves, and this is where the name and default lint level and other metadata come from. These are normally defined by way of the [`declare_lint!`] macro, diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index b4dc11a68..4e1f520ff 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -156,7 +156,7 @@ highlights, but there are a lot more details, which we will link to below. ### Code Review -When you open a PR on the `rust-lang/rust` repo, a bot called `@rust-highfive` will +When you open a PR on the `rust-lang/rust` repo, a bot called `@rustbot` will automatically assign a reviewer to the PR based on which files you changed. The reviewer is the person that will approve the PR to be tested and merged. If you want a specific reviewer (e.g. a team member you've been working with), diff --git a/src/doc/rustc-dev-guide/src/macro-expansion.md b/src/doc/rustc-dev-guide/src/macro-expansion.md index 156df8d5f..7f50f7f89 100644 --- a/src/doc/rustc-dev-guide/src/macro-expansion.md +++ b/src/doc/rustc-dev-guide/src/macro-expansion.md @@ -48,45 +48,45 @@ iteration, this represents a compile error. Here is the [algorithm][original]: [fef]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/expand/struct.MacroExpander.html#method.fully_expand_fragment [original]: https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049 -0. Initialize an `queue` of unresolved macros. -1. Repeat until `queue` is empty (or we make no progress, which is an error): - 0. [Resolve](./name-resolution.md) imports in our partially built crate as - much as possible. - 1. Collect as many macro [`Invocation`s][inv] as possible from our - partially built crate (fn-like, attributes, derives) and add them to the - queue. - 2. Dequeue the first element, and attempt to resolve it. - 3. If it's resolved: - 0. Run the macro's expander function that consumes a [`TokenStream`] or - AST and produces a [`TokenStream`] or [`AstFragment`] (depending on - the macro kind). (A `TokenStream` is a collection of [`TokenTree`s][tt], - each of which are a token (punctuation, identifier, or literal) or a - delimited group (anything inside `()`/`[]`/`{}`)). - - At this point, we know everything about the macro itself and can - call `set_expn_data` to fill in its properties in the global data; - that is the hygiene data associated with `ExpnId`. (See [the - "Hygiene" section below][hybelow]). - 1. Integrate that piece of AST into the big existing partially built - AST. This is essentially where the "token-like mass" becomes a - proper set-in-stone AST with side-tables. It happens as follows: - - If the macro produces tokens (e.g. a proc macro), we parse into - an AST, which may produce parse errors. - - During expansion, we create `SyntaxContext`s (hierarchy 2). (See - [the "Hygiene" section below][hybelow]) - - These three passes happen one after another on every AST fragment - freshly expanded from a macro: - - [`NodeId`]s are assigned by [`InvocationCollector`]. This - also collects new macro calls from this new AST piece and - adds them to the queue. - - ["Def paths"][defpath] are created and [`DefId`]s are - assigned to them by [`DefCollector`]. - - Names are put into modules (from the resolver's point of - view) by [`BuildReducedGraphVisitor`]. - 2. After expanding a single macro and integrating its output, continue - to the next iteration of [`fully_expand_fragment`][fef]. - 4. If it's not resolved: - 0. Put the macro back in the queue - 1. Continue to next iteration... +1. Initialize an `queue` of unresolved macros. +2. Repeat until `queue` is empty (or we make no progress, which is an error): + 1. [Resolve](./name-resolution.md) imports in our partially built crate as + much as possible. + 2. Collect as many macro [`Invocation`s][inv] as possible from our + partially built crate (fn-like, attributes, derives) and add them to the + queue. + 3. Dequeue the first element, and attempt to resolve it. + 4. If it's resolved: + 1. Run the macro's expander function that consumes a [`TokenStream`] or + AST and produces a [`TokenStream`] or [`AstFragment`] (depending on + the macro kind). (A `TokenStream` is a collection of [`TokenTree`s][tt], + each of which are a token (punctuation, identifier, or literal) or a + delimited group (anything inside `()`/`[]`/`{}`)). + - At this point, we know everything about the macro itself and can + call `set_expn_data` to fill in its properties in the global data; + that is the hygiene data associated with `ExpnId`. (See [the + "Hygiene" section below][hybelow]). + 2. Integrate that piece of AST into the big existing partially built + AST. This is essentially where the "token-like mass" becomes a + proper set-in-stone AST with side-tables. It happens as follows: + - If the macro produces tokens (e.g. a proc macro), we parse into + an AST, which may produce parse errors. + - During expansion, we create `SyntaxContext`s (hierarchy 2). (See + [the "Hygiene" section below][hybelow]) + - These three passes happen one after another on every AST fragment + freshly expanded from a macro: + - [`NodeId`]s are assigned by [`InvocationCollector`]. This + also collects new macro calls from this new AST piece and + adds them to the queue. + - ["Def paths"][defpath] are created and [`DefId`]s are + assigned to them by [`DefCollector`]. + - Names are put into modules (from the resolver's point of + view) by [`BuildReducedGraphVisitor`]. + 3. After expanding a single macro and integrating its output, continue + to the next iteration of [`fully_expand_fragment`][fef]. + 5. If it's not resolved: + 1. Put the macro back in the queue + 2. Continue to next iteration... [defpath]: hir.md#identifiers-in-the-hir [`NodeId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/node_id/struct.NodeId.html @@ -149,9 +149,9 @@ macros are implemented in [`rustc_builtin_macros`], along with some other early code generation facilities like injection of standard library imports or generation of test harness. There are some additional helpers for building their AST fragments in [`rustc_expand::build`][reb]. Eager expansion generally -performs a subset of the things that lazy (normal) expansion. It is done by +performs a subset of the things that lazy (normal) expansion does. It is done by invoking [`fully_expand_fragment`][fef] on only part of a crate (as opposed to -whole crate, like we normally do). +the whole crate, like we normally do). ### Other Data Structures @@ -532,7 +532,7 @@ three cases has occurred: - Failure: the token stream does not match `matcher`. This results in an error message such as "No rule expected token _blah_". - Error: some fatal error has occurred _in the parser_. For example, this - happens if there are more than one pattern match, since that indicates + happens if there is more than one pattern match, since that indicates the macro is ambiguous. The full interface is defined [here][code_parse_int]. diff --git a/src/doc/rustc-dev-guide/src/mir/dataflow.md b/src/doc/rustc-dev-guide/src/mir/dataflow.md index ce4a86a23..15bfd6aed 100644 --- a/src/doc/rustc-dev-guide/src/mir/dataflow.md +++ b/src/doc/rustc-dev-guide/src/mir/dataflow.md @@ -61,7 +61,7 @@ slower as a result. All implementers of `GenKillAnalysis` also implement ### Transfer Functions and Effects The dataflow framework in `rustc` allows each statement (and terminator) inside -a basic block define its own transfer function. For brevity, these +a basic block to define its own transfer function. For brevity, these individual transfer functions are known as "effects". Each effect is applied successively in dataflow order, and together they define the transfer function for the entire basic block. It's also possible to define an effect for diff --git a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md index 20b92cc45..0869e0e3d 100644 --- a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md +++ b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md @@ -111,7 +111,7 @@ a few optimizations: - Only paths that are the target of a `Drop` (or have the target as a prefix) need drop flags. -- Some variables are known to initialized (or uninitialized) when they are +- Some variables are known to be initialized (or uninitialized) when they are dropped. These do not need drop flags. - If a set of paths are only dropped or moved from via a shared prefix, those paths can share a single drop flag. diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md index 7fbdfd359..ceb0efdb2 100644 --- a/src/doc/rustc-dev-guide/src/overview.md +++ b/src/doc/rustc-dev-guide/src/overview.md @@ -292,7 +292,7 @@ Moreover, the compiler wasn't originally built to use a query system; the query system has been retrofitted into the compiler, so parts of it are not query-fied yet. Also, LLVM isn't our code, so that isn't querified either. The plan is to eventually query-fy all of the steps listed in the previous section, -but as of <!-- date-check --> November 2021, only the steps between HIR and +but as of <!-- date-check --> November 2022, only the steps between HIR and LLVM IR are query-fied. That is, lexing, parsing, name resolution, and macro expansion are done all at once for the whole program. diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md index e93f51dbb..e7cbbd7ee 100644 --- a/src/doc/rustc-dev-guide/src/parallel-rustc.md +++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md @@ -26,7 +26,7 @@ occurs in the `rustc_codegen_ssa::base` module. The underlying thread-safe data-structures used in the parallel compiler can be found in the `rustc_data_structures::sync` module. These data structures -are implemented diferently depending on whether `parallel-compiler` is true. +are implemented differently depending on whether `parallel-compiler` is true. | data structure | parallel | non-parallel | | -------------------------------- | --------------------------------------------------- | ------------ | @@ -141,7 +141,7 @@ the previous `Data Structures` and `Parallel Iterators`. See [this tracking issu ## Rustdoc -As of <!-- date-check--> May 2022, there are still a number of steps +As of <!-- date-check--> November 2022, there are still a number of steps to complete before rustdoc rendering can be made parallel. More details on this issue can be found [here][parallel-rustdoc]. diff --git a/src/doc/rustc-dev-guide/src/part-5-intro.md b/src/doc/rustc-dev-guide/src/part-5-intro.md index faa12f484..f32508d27 100644 --- a/src/doc/rustc-dev-guide/src/part-5-intro.md +++ b/src/doc/rustc-dev-guide/src/part-5-intro.md @@ -21,16 +21,16 @@ Now, we will finally take the MIR and produce some executable machine code. So what do we need to do? -0. First, we need to collect the set of things to generate code for. +1. First, we need to collect the set of things to generate code for. In particular, we need to find out which concrete types to substitute for generic ones, since we need to generate code for the concrete types. Generating code for the concrete types (i.e. emitting a copy of the code for each concrete type) is called _monomorphization_, so the process of collecting all the concrete types is called _monomorphization collection_. -1. Next, we need to actually lower the MIR to a codegen IR +2. Next, we need to actually lower the MIR to a codegen IR (usually LLVM IR) for each concrete type we collected. -2. Finally, we need to invoke the codegen backend, +3. Finally, we need to invoke the codegen backend, which runs a bunch of optimization passes, generates executable code, and links together an executable binary. diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md index dc196e490..abd2b0155 100644 --- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md +++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md @@ -175,11 +175,12 @@ fn try_mark_green(tcx, current_node) -> bool { true } - -// Note: The actual implementation can be found in -// compiler/rustc_middle/src/dep_graph/graph.rs ``` +> NOTE: +> The actual implementation can be found in +> [`compiler/rustc_query_system/src/dep_graph/graph.rs`][try_mark_green] + By using red-green marking we can avoid the devastating cumulative effect of having false positives during change detection. Whenever a query is executed in incremental mode, we first check if its already green. If not, we run @@ -187,7 +188,6 @@ in incremental mode, we first check if its already green. If not, we run invoke the query provider to re-compute the result. - ## The Real World: How Persistence Makes Everything Complicated The sections above described the underlying algorithm for incremental @@ -533,5 +533,5 @@ be reusable. See <https://github.com/rust-lang/rust/issues/47389> for more information. - [query-model]: ./query-evaluation-model-in-detail.html +[try_mark_green]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_query_system/dep_graph/graph.rs.html diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 3d60059bd..268a56558 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -169,31 +169,30 @@ they define both a `provide` and a `provide_extern` function, through How do you add a new query? Defining a query takes place in two steps: -1. Specify the query name and its arguments. +1. Declare the query name, its arguments and description. 2. Supply query providers where needed. -To specify the query name and arguments, you simply add an entry to -the big macro invocation in -[`compiler/rustc_middle/src/query/mod.rs`][query-mod], which looks something like: +To declare the query name and arguments, you simply add an entry to +the big macro invocation in [`compiler/rustc_middle/src/query/mod.rs`][query-mod]. +Then you need to add a documentation comment to it with some _internal_ description. +Then, provide the `desc` attribute which contains a _user-facing_ description of the query. +The `desc` attribute is shown to the user in query cycles. + +This looks something like: [query-mod]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/index.html ```rust,ignore rustc_queries! { - Other { - /// Records the type of every item. - query type_of(key: DefId) -> Ty<'tcx> { - cache { key.is_local() } - } + /// Records the type of every item. + query type_of(key: DefId) -> Ty<'tcx> { + cache_on_disk_if { key.is_local() } + desc { |tcx| "computing the type of `{}`", tcx.def_path_str(key) } } - ... } ``` -Queries are grouped into categories (`Other`, `Codegen`, `TypeChecking`, etc.). -Each group contains one or more queries. - A query definition has the following form: ```rust,ignore @@ -238,62 +237,6 @@ which is used to cheaply modify MIR in place. See the definition of `Steal` for more details. New uses of `Steal` should **not** be added without alerting `@rust-lang/compiler`. -### Query structs and descriptions - -For each query, the `rustc_queries` macro will generate a "query struct" -named after the query. This struct is a kind of placeholder -describing the query. Each query struct implements the -[`self::config::QueryConfig`][QueryConfig] trait, which has associated types for the -key/value of that particular query. Basically the code generated looks something -like this: - -```rust,ignore -// Dummy struct representing a particular kind of query: -pub struct type_of<'tcx> { data: PhantomData<&'tcx ()> } - -impl<'tcx> QueryConfig for type_of<'tcx> { - type Key = DefId; - type Value = Ty<'tcx>; - - const NAME: QueryName = QueryName::type_of; - const CATEGORY: ProfileCategory = ProfileCategory::Other; -} -``` - -There is an additional trait that you may wish to implement called -[`self::config::QueryDescription`][QueryDescription]. This trait is -used during cycle errors to give a "human readable" name for the query, -so that we can summarize what was happening when the cycle occurred. -Implementing this trait is optional if the query key is `DefId`, but -if you *don't* implement it, you get a pretty generic error ("processing `foo`..."). -You can put new impls into the `config` module. They look something like this: - -[QueryConfig]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_query_system/query/config/trait.QueryConfig.html -[QueryDescription]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_query_system/query/config/trait.QueryDescription.html - -```rust,ignore -impl<'tcx> QueryDescription for queries::type_of<'tcx> { - fn describe(tcx: TyCtxt, key: DefId) -> String { - format!("computing the type of `{}`", tcx.def_path_str(key)) - } -} -``` - -Another option is to add `desc` modifier: - -```rust,ignore -rustc_queries! { - Other { - /// Records the type of every item. - query type_of(key: DefId) -> Ty<'tcx> { - desc { |tcx| "computing the type of `{}`", tcx.def_path_str(key) } - } - } -} -``` - -`rustc_queries` macro will generate an appropriate `impl` automatically. - ## External links Related design ideas, and tracking issues: diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md index f21c8725c..c85e82e96 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md @@ -66,7 +66,7 @@ these passes, please let us know!) [44136]: https://github.com/rust-lang/rust/issues/44136 -Here is the list of passes as of <!-- date-check --> May 2022: +Here is the list of passes as of <!-- date-check --> November 2022: - `calculate-doc-coverage` calculates information used for the `--show-coverage` flag. diff --git a/src/doc/rustc-dev-guide/src/salsa.md b/src/doc/rustc-dev-guide/src/salsa.md index 872308e78..66f9d7479 100644 --- a/src/doc/rustc-dev-guide/src/salsa.md +++ b/src/doc/rustc-dev-guide/src/salsa.md @@ -9,7 +9,7 @@ want to watch [Salsa In More Depth](https://www.youtube.com/watch?v=i_IhACacPRY), also by Niko Matsakis. -> As of <!-- date-check --> April 2022, although Salsa is inspired by +> As of <!-- date-check --> November 2022, although Salsa is inspired by > (among other things) rustc's query system, it is not used directly in rustc. > It _is_ used in chalk and extensively in `rust-analyzer`, but there are no > medium or long-term concrete plans to integrate it into the compiler. diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md index b7308ee73..85c75fadb 100644 --- a/src/doc/rustc-dev-guide/src/stability.md +++ b/src/doc/rustc-dev-guide/src/stability.md @@ -72,14 +72,14 @@ Furthermore this attribute is needed to mark an intrinsic as callable from To stabilize a feature, follow these steps: -0. Ask a **@T-libs-api** member to start an FCP on the tracking issue and wait for +1. Ask a **@T-libs-api** member to start an FCP on the tracking issue and wait for the FCP to complete (with `disposition-merge`). -1. Change `#[unstable(...)]` to `#[stable(since = "CURRENT_RUSTC_VERSION")]`. -2. Remove `#![feature(...)]` from any test or doc-test for this API. If the feature is used in the +2. Change `#[unstable(...)]` to `#[stable(since = "CURRENT_RUSTC_VERSION")]`. +3. Remove `#![feature(...)]` from any test or doc-test for this API. If the feature is used in the compiler or tools, remove it from there as well. -3. If applicable, change `#[rustc_const_unstable(...)]` to +4. If applicable, change `#[rustc_const_unstable(...)]` to `#[rustc_const_stable(since = "CURRENT_RUSTC_VERSION")]`. -4. Open a PR against `rust-lang/rust`. +5. Open a PR against `rust-lang/rust`. - Add the appropriate labels: `@rustbot modify labels: +T-libs-api`. - Link to the tracking issue and say "Closes #XXXXX". diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md index 1baa447a0..3556f4e23 100644 --- a/src/doc/rustc-dev-guide/src/tests/ui.md +++ b/src/doc/rustc-dev-guide/src/tests/ui.md @@ -207,6 +207,10 @@ There are several ways to match the message with the line (see the examples belo This is more convenient than using multiple carets when there are multiple messages associated with the same line. +The space character between `//~` (or other variants) and the subsequent text +is negligible (i.e. there is no semantic difference between `//~ ERROR` and +`//~ERROR` although the former is more common in the codebase). + ### Error annotation examples Here are examples of error annotations on different lines of UI test diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md index 88767ad94..9cf753b19 100644 --- a/src/doc/rustc-dev-guide/src/traits/resolution.md +++ b/src/doc/rustc-dev-guide/src/traits/resolution.md @@ -52,7 +52,7 @@ by proving that an appropriate impl does exist. During type checking, we do not store the results of trait selection. We simply wish to verify that trait selection will succeed. Then -later, at trans time, when we have all concrete types available, we +later, at codegen time, when we have all concrete types available, we can repeat the trait selection to choose an actual implementation, which will then be generated in the output binary. diff --git a/src/doc/rustc-dev-guide/src/traits/specialization.md b/src/doc/rustc-dev-guide/src/traits/specialization.md index 7a30314b4..7cae5e9c1 100644 --- a/src/doc/rustc-dev-guide/src/traits/specialization.md +++ b/src/doc/rustc-dev-guide/src/traits/specialization.md @@ -36,7 +36,7 @@ as long as they are part of the same specialization family. In that case, it returns a *single* impl on success – this is the most specialized impl *known* to apply. However, if there are any inference variables in play, the returned impl may not be the actual impl we -will use at trans time. Thus, we take special care to avoid projecting +will use at codegen time. Thus, we take special care to avoid projecting associated types unless either (1) the associated type does not use `default` and thus cannot be overridden or (2) all input types are known concretely. diff --git a/src/doc/rustc-dev-guide/src/ty-fold.md b/src/doc/rustc-dev-guide/src/ty-fold.md index c390597f9..dd76b80d4 100644 --- a/src/doc/rustc-dev-guide/src/ty-fold.md +++ b/src/doc/rustc-dev-guide/src/ty-fold.md @@ -17,7 +17,7 @@ and For example, the `TypeFolder` trait has a method [`fold_ty`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFolder.html#method.fold_ty) -that takes a type as input a type and returns a new type as a result. `TypeFoldable` invokes the +that takes a type as input and returns a new type as a result. `TypeFoldable` invokes the `TypeFolder` `fold_foo` methods on itself, giving the `TypeFolder` access to its contents (the types, regions, etc that are contained within). diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md index 10f1dd5ef..ca88c1686 100644 --- a/src/doc/rustc-dev-guide/src/type-inference.md +++ b/src/doc/rustc-dev-guide/src/type-inference.md @@ -218,29 +218,33 @@ algorithms. [`region_constraints`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/region_constraints/index.html [`opportunistic_resolve_var`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/region_constraints/struct.RegionConstraintCollector.html#method.opportunistic_resolve_var -## Extracting region constraints +## Solving region constraints -Ultimately, region constraints are only solved at the very end of -type-checking, once all other constraints are known. There are two +Region constraints are only solved at the very end of +typechecking, once all other constraints are known and +all other obligations have been proven. There are two ways to solve region constraints right now: lexical and non-lexical. Eventually there will only be one. +An exception here is the leak-check which is used during trait solving +and relies on region constraints containing higher-ranked regions. Region +constraints in the root universe (i.e. not arising from a `for<'a>`) must +not influence the trait system, as these regions are all erased during +codegen. + To solve **lexical** region constraints, you invoke [`resolve_regions_and_report_errors`]. This "closes" the region constraint process and invokes the [`lexical_region_resolve`] code. Once this is done, any further attempt to equate or create a subtyping relationship will yield an ICE. -Non-lexical region constraints are not handled within the inference -context. Instead, the NLL solver (actually, the MIR type-checker) -invokes [`take_and_reset_region_constraints`] periodically. This -extracts all of the outlives constraints from the region solver, but -leaves the set of variables intact. This is used to get *just* the -region constraints that resulted from some particular point in the -program, since the NLL solver needs to know not just *what* regions -were subregions, but also *where*. Finally, the NLL solver invokes -[`take_region_var_origins`], which "closes" the region constraint -process in the same way as normal solving. +The NLL solver (actually, the MIR type-checker) does things slightly +differently. It uses canonical queries for trait solving which use +[`take_and_reset_region_constraints`] at the end. This extracts all of the +outlives constraints added during the canonical query. This is required +as the NLL solver must not only know *what* regions outlive each other, +but also *where*. Finally, the NLL solver invokes [`take_region_var_origins`], +providing all region variables to the solver. [`resolve_regions_and_report_errors`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.resolve_regions_and_report_errors [`lexical_region_resolve`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/lexical_region_resolve/index.html diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 06883ddd5..2d3b83094 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -29,9 +29,11 @@ - [\*-kmc-solid_\*](platform-support/kmc-solid.md) - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) - [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md) + - [mipsel-sony-psx](platform-support/mipsel-sony-psx.md) - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md) - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md) + - [\*-nto-qnx-\*](platform-support/nto-qnx.md) - [*-unknown-openbsd](platform-support/openbsd.md) - [\*-unknown-uefi](platform-support/unknown-uefi.md) - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index b1c3b618c..7e355b7fc 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -210,8 +210,8 @@ metrics. ## link-self-contained -On targets that support it this flag controls whether the linker will use libraries and objects -shipped with Rust instead or those in the system. +On `windows-gnu`, `linux-musl`, and `wasi` targets, this flag controls whether the +linker will use libraries and objects shipped with Rust instead or those in the system. It takes one of the following values: * no value: rustc will use heuristic to disable self-contained mode if system has necessary tools. @@ -531,8 +531,10 @@ platforms. Possible values are: debug information. On other Unix platforms this means that `*.dwo` files will contain debug information. -Note that `packed` and `unpacked` are gated behind `-Z unstable-options` on -non-macOS platforms at this time. +Note that all three options are supported on Linux and Apple platforms, +`packed` is supported on Windows-MSVC, and all other platforms support `off`. +Attempting to use an unsupported option requires using the nightly channel +with the `-Z unstable-options` flag. ## strip diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 2dc182b3d..ef6eee75f 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -104,6 +104,33 @@ This modifier has no effect when building other targets like executables or dyna The default for this modifier is `+bundle`. +### Linking modifiers: `verbatim` + +This modifier is compatible with all linking kinds. + +`+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes +(like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the +linker. + +For `ld`-like linkers supporting GNU extensions rustc will use the `-l:filename` syntax (note the +colon) when passing the library, so the linker won't add any prefixes or suffixes to it. +See [`-l namespec`](https://sourceware.org/binutils/docs/ld/Options.html) in ld documentation for +more details. \ +For linkers not supporting any verbatim modifiers (e.g. `link.exe` or `ld64`) the library name will +be passed as is. So the most reliable cross-platform use scenarios for this option are when no +linker is involved, for example bundling native libraries into rlibs. + +`-verbatim` means that rustc will either add a target-specific prefix and suffix to the library +name before passing it to linker, or won't prevent linker from implicitly adding it. \ +In case of `raw-dylib` kind in particular `.dll` will be added to the library name on Windows. + +The default for this modifier is `-verbatim`. + +NOTE: Even with `+verbatim` and `-l:filename` syntax `ld`-like linkers do not typically support +passing absolute paths to libraries. Usually such paths need to be passed as input files without +using any options like `-l`, e.g. `ld /my/absolute/path`. \ +`-Clink-arg=/my/absolute/path` can be used for doing this from stable `rustc`. + <a id="option-crate-type"></a> ## `--crate-type`: a list of types of crates for the compiler to emit diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md index b1854b22a..9272b9ac9 100644 --- a/src/doc/rustc/src/linker-plugin-lto.md +++ b/src/doc/rustc/src/linker-plugin-lto.md @@ -131,24 +131,47 @@ able to get around this problem by setting `-Clinker=lld-link` in RUSTFLAGS ## Toolchain Compatibility -<!-- NOTE: to update the below table, you can use this shell script: - -```sh -rustup toolchain install --profile minimal nightly -MINOR_VERSION=$(rustc +nightly --version | cut -d . -f 2) -LOWER_BOUND=61 - -llvm_version() { - toolchain="$1" - printf "Rust $toolchain | Clang " - rustc +"$toolchain" -Vv | grep LLVM | cut -d ':' -f 2 | tr -d ' ' -} - -for version in `seq $LOWER_BOUND $((MINOR_VERSION - 2))`; do - toolchain=1.$version.0 - rustup toolchain install --no-self-update --profile minimal $toolchain >/dev/null 2>&1 - llvm_version $toolchain -done +<!-- NOTE: to update the below table, you can use this Python script: + +```python +from collections import defaultdict +import subprocess + +def minor_version(version): + return int(version.split('.')[1]) + +INSTALL_TOOLCHAIN = ["rustup", "toolchain", "install", "--profile", "minimal"] +subprocess.run(INSTALL_TOOLCHAIN + ["nightly"]) + +LOWER_BOUND = 65 +NIGHTLY_VERSION = minor_version(subprocess.run( + ["rustc", "+nightly", "--version"], + capture_output=True, + text=True).stdout) + +def llvm_version(toolchain): + version_text = subprocess.run( + ["rustc", "+{}".format(toolchain), "-Vv"], + capture_output=True, + text=True).stdout + return int(version_text.split("LLVM")[1].split(':')[1].split('.')[0]) + +version_map = defaultdict(lambda: []) +for version in range(LOWER_BOUND, NIGHTLY_VERSION - 1): + toolchain = "1.{}.0".format(version) + subprocess.run( + INSTALL_TOOLCHAIN + ["--no-self-update", toolchain], + capture_output=True) + version_map[llvm_version(toolchain)].append(version) + +print("| Rust Version | Clang Version |") +print("|--------------|---------------|") +for clang, rust in sorted(version_map.items()): + if len(rust) > 1: + rust_range = "1.{} - 1.{}".format(rust[0], rust[-1]) + else: + rust_range = "1.{} ".format(rust[0]) + print("| {} | {} |".format(rust_range, clang)) ``` --> @@ -166,32 +189,13 @@ The following table shows known good combinations of toolchain versions. | Rust Version | Clang Version | |--------------|---------------| -| Rust 1.34 | Clang 8 | -| Rust 1.35 | Clang 8 | -| Rust 1.36 | Clang 8 | -| Rust 1.37 | Clang 8 | -| Rust 1.38 | Clang 9 | -| Rust 1.39 | Clang 9 | -| Rust 1.40 | Clang 9 | -| Rust 1.41 | Clang 9 | -| Rust 1.42 | Clang 9 | -| Rust 1.43 | Clang 9 | -| Rust 1.44 | Clang 9 | -| Rust 1.45 | Clang 10 | -| Rust 1.46 | Clang 10 | -| Rust 1.47 | Clang 11 | -| Rust 1.48 | Clang 11 | -| Rust 1.49 | Clang 11 | -| Rust 1.50 | Clang 11 | -| Rust 1.51 | Clang 11 | -| Rust 1.52 | Clang 12 | -| Rust 1.53 | Clang 12 | -| Rust 1.54 | Clang 12 | -| Rust 1.55 | Clang 12 | -| Rust 1.56 | Clang 13 | -| Rust 1.57 | Clang 13 | -| Rust 1.58 | Clang 13 | -| Rust 1.59 | Clang 13 | -| Rust 1.60 | Clang 14 | +| 1.34 - 1.37 | 8 | +| 1.38 - 1.44 | 9 | +| 1.45 - 1.46 | 10 | +| 1.47 - 1.51 | 11 | +| 1.52 - 1.55 | 12 | +| 1.56 - 1.59 | 13 | +| 1.60 - 1.64 | 14 | +| 1.65 | 15 | Note that the compatibility policy for this feature might change in the future. diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index a36518cc8..d0c3ddf26 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -128,6 +128,7 @@ target | std | notes [`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android `aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat `aarch64-unknown-none` | * | Bare ARM64, hardfloat +[`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | * | ARM64 UEFI [`arm-linux-androideabi`](platform-support/android.md) | ✓ | ARMv7 Android `arm-unknown-linux-musleabi` | ✓ | ARMv6 Linux with MUSL `arm-unknown-linux-musleabihf` | ✓ | ARMv6 Linux with MUSL, hardfloat @@ -149,6 +150,7 @@ target | std | notes [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD `i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL +[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI `mips-unknown-linux-musl` | ✓ | MIPS Linux with MUSL `mips64-unknown-linux-muslabi64` | ✓ | MIPS64 Linux, n64 ABI, MUSL `mips64el-unknown-linux-muslabi64` | ✓ | MIPS64 (LE) Linux, n64 ABI, MUSL @@ -181,6 +183,7 @@ target | std | notes `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat `x86_64-unknown-redox` | ✓ | Redox OS +[`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | 64-bit UEFI [Fortanix ABI]: https://edp.fortanix.com/ @@ -211,9 +214,9 @@ target | std | host | notes [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | +[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.1 RTOS | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore -[`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | * | | ARM64 UEFI `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) `aarch64-unknown-netbsd` | ✓ | ✓ | [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD @@ -252,7 +255,6 @@ target | std | host | notes `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku `i686-unknown-netbsd` | ✓ | ✓ | NetBSD/i386 with SSE2 [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD -[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | | 32-bit UEFI `i686-uwp-windows-gnu` | ? | | `i686-uwp-windows-msvc` | ? | | `i686-wrs-vxworks` | ? | | @@ -260,6 +262,7 @@ target | std | host | notes `mips-unknown-linux-uclibc` | ✓ | | MIPS Linux with uClibc [`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? | | MIPS64 for OpenWrt Linux MUSL `mipsel-sony-psp` | * | | MIPS (LE) Sony PlayStation Portable (PSP) +[`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX) `mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc `mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat `mipsisa32r6-unknown-linux-gnu` | ? | | @@ -280,6 +283,7 @@ target | std | host | notes `powerpc64-wrs-vxworks` | ? | | `powerpc64le-unknown-linux-musl` | ? | | [`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64 +`powerpc64-ibm-aix` | ? | | 64-bit AIX (7.2 and newer) `riscv32gc-unknown-linux-gnu` | | | RISC-V Linux (kernel 5.4, glibc 2.33) `riscv32gc-unknown-linux-musl` | | | RISC-V Linux (kernel 5.4, musl + RISCV32 support patches) `riscv32im-unknown-none-elf` | * | | Bare RISC-V (RV32IM ISA) @@ -301,6 +305,7 @@ target | std | host | notes `x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64 `x86_64-apple-tvos` | * | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator +[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ? | | x86 64-bit QNX Neutrino 7.1 RTOS | [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | `x86_64-pc-windows-msvc` | * | | 64-bit Windows XP support `x86_64-sun-solaris` | ? | | Deprecated target for 64-bit Solaris 10/11, illumos @@ -308,9 +313,7 @@ target | std | host | notes `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku `x86_64-unknown-hermit` | ✓ | | HermitCore `x86_64-unknown-l4re-uclibc` | ? | | -`x86_64-unknown-none-linuxkernel` | * | | Linux kernel modules [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD -[`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | | 64-bit UEFI `x86_64-uwp-windows-gnu` | ✓ | | `x86_64-uwp-windows-msvc` | ✓ | | `x86_64-wrs-vxworks` | ? | | diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index 1ff6003c1..fbf999f97 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -189,17 +189,45 @@ Fuchsia as well. A recent version (14+) of clang should be sufficient to compile Rust for Fuchsia. x86-64 and AArch64 Fuchsia targets can be enabled using the following -configuration. - -In `config.toml`, add: +configuration in `config.toml`: ```toml [build] target = ["<host_platform>", "aarch64-fuchsia", "x86_64-fuchsia"] + +[rust] +lld = true + +[target.x86_64-fuchsia] +cc = "clang" +cxx = "clang++" + +[target.aarch64-fuchsia] +cc = "clang" +cxx = "clang++" +``` + +Though not strictly required, you may also want to use `clang` for your host +target as well: + +```toml +[target.<host_platform>] +cc = "clang" +cxx = "clang++" +``` + +By default, the Rust compiler installs itself to `/usr/local` on most UNIX +systems. You may want to install it to another location (e.g. a local `install` +directory) by setting a custom prefix in `config.toml`: + +```toml +[install] +# Make sure to use the absolute path to your install directory +prefix = "<RUST_SRC_PATH>/install" ``` -Additionally, the following environment variables must be configured (for -example, using a script like `config-env.sh`): +Next, the following environment variables must be configured. For example, using +a script we name `config-env.sh`: ```sh # Configure this environment variable to be the path to the downloaded SDK @@ -215,8 +243,11 @@ export LDFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arc export CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/x64/sysroot -Lnative=${SDK_PATH}/arch/x64/sysroot/lib -Lnative=${SDK_PATH}/arch/x64/lib" ``` -These can be run together in a shell environment by executing -`(source config-env.sh && ./x.py install)`. +Finally, the Rust compiler can be built and installed: + +```sh +(source config-env.sh && ./x.py install) +``` Once `rustc` is installed, we can create a new working directory to work from, `hello_fuchsia` along with `hello_fuchsia/src`: @@ -641,8 +672,72 @@ available on the [Fuchsia devsite]. ### Running the compiler test suite -Running the Rust test suite on Fuchsia is [not currently supported], but work is -underway to enable it. +The commands in this section assume that they are being run from inside your +local Rust source checkout: + +```sh +cd ${RUST_SRC_PATH} +``` + +To run the Rust test suite on an emulated Fuchsia device, you must install the +Rust compiler locally. See "[Targeting Fuchsia with a compiler built from source](#targeting-fuchsia-with-a-compiler-built-from-source)" +for the steps to build locally. + +You'll also need to download a copy of the Fuchsia SDK. The current minimum +supported SDK version is [9.20220726.1.1](https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:9.20220726.1.1). + +Fuchsia's test runner interacts with the Fuchsia emulator and is located at +`src/ci/docker/scripts/fuchsia-test-runner.py`. We can use it to start our +test environment with: + +```sh +src/ci/docker/scripts/fuchsia-test-runner.py start + --rust ${RUST_SRC_PATH}/install + --sdk ${SDK_PATH} + --target-arch {x64,arm64} +``` + +Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and +`${SDK_PATH}` is the path to the downloaded and unzipped SDK. + +Once our environment is started, we can run our tests using `x.py` as usual. The +test runner script will run the compiled tests on an emulated Fuchsia device. To +run the full `src/test/ui` test suite: + +```sh +( \ + source config-env.sh && \ + ./x.py \ + --config config.toml \ + --stage=2 \ + test src/test/ui \ + --target x86_64-fuchsia \ + --run=always --jobs 1 \ + --test-args --target-rustcflags \ + --test-args -L \ + --test-args --target-rustcflags \ + --test-args ${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \ + --test-args --target-rustcflags \ + --test-args -L \ + --test-args --target-rustcflags \ + --test-args ${SDK_PATH}/arch/{x64|arm64}/lib \ + --test-args --target-rustcflags \ + --test-args -Cpanic=abort \ + --test-args --target-rustcflags \ + --test-args -Zpanic_abort_tests \ + --test-args --remote-test-client \ + --test-args src/ci/docker/scripts/fuchsia-test-runner.py \ +) +``` + +*Note: The test suite cannot be run in parallel at the moment, so `x.py` +must be run with `--jobs 1` to ensure only one test runs at a time.* + +When finished, the test runner can be used to stop the test environment: + +```sh +src/ci/docker/scripts/fuchsia-test-runner.py stop +``` ## Debugging diff --git a/src/doc/rustc/src/platform-support/mipsel-sony-psx.md b/src/doc/rustc/src/platform-support/mipsel-sony-psx.md new file mode 100644 index 000000000..589100e88 --- /dev/null +++ b/src/doc/rustc/src/platform-support/mipsel-sony-psx.md @@ -0,0 +1,49 @@ +# mipsel-sony-psx + +**Tier: 3** + +Sony PlayStation 1 (psx) + +## Designated Developer + +* [@ayrtonm](https://github.com/ayrtonm) + +## Requirements + +This target is cross-compiled. +It has no special requirements for the host. + +## Building + +The target can be built by enabling it for a `rustc` build: + +```toml +[build] +build-stage = 1 +target = ["mipsel-sony-psx"] +``` + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Testing + +Currently there is no support to run the rustc test suite for this target. + +## Building Rust programs + +Since it is Tier 3, rust doesn't ship pre-compiled artifacts for this target. + +Just use the `build-std` nightly cargo feature to build the `core` and `alloc` libraries: +```shell +cargo build -Zbuild-std=core,alloc --target mipsel-sony-psx +``` + +The command above generates an ELF. To generate binaries in the PSEXE format that emulators run, you can use [cargo-psx](https://github.com/ayrtonm/psx-sdk-rs#readme): + +```shell +cargo psx build +``` + +or use `-Clink-arg=--oformat=binary` to produce a flat binary. diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md new file mode 100644 index 000000000..37d0c3197 --- /dev/null +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -0,0 +1,118 @@ +# nto-qnx + +**Tier: 3** + +[BlackBerry® QNX®][BlackBerry] Neutrino (nto) Real-time operating system. +The support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit] +and [BlackBerry][BlackBerry]. + +[BlackBerry]: https://blackberry.qnx.com +[Elektrobit]: https://www.elektrobit.com + +## Target maintainers + +- Florian Bartels, `Florian.Bartels@elektrobit.com`, https://github.com/flba-eb +- Tristan Roach, `TRoach@blackberry.com`, https://github.com/gh-tr + +## Requirements + +Currently, only cross-compilation for QNX Neutrino on AArch64 and x86_64 are supported (little endian). +Adding other architectures that are supported by QNX Neutrino is possible. + +The standard library does not yet support QNX Neutrino. Therefore, only `no_std` code can +be compiled. + +`core` and `alloc` (with default allocator) are supported. + +Applications must link against `libc.so` (see example). This is required because applications +always link against the `crt` library and `crt` depends on `libc.so`. + +The correct version of `qcc` must be available by setting the `$PATH` variable (e.g. by sourcing `qnxsdp-env.sh` of the +QNX Neutrino toolchain). + +### Small example application + +```rust,ignore (platform-specific) +#![no_std] +#![no_main] +#![feature(lang_items)] + +// We must always link against libc, even if no external functions are used +// "extern C" - Block can be empty but must be present +#[link(name = "c")] +extern "C" { + pub fn printf(format: *const core::ffi::c_char, ...) -> core::ffi::c_int; +} + +#[no_mangle] +pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize { + const HELLO: &'static str = "Hello World, the answer is %d\n\0"; + unsafe { + printf(HELLO.as_ptr() as *const _, 42); + } + 0 +} + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(_panic: &PanicInfo<'_>) -> ! { + loop {} +} + +#[lang = "eh_personality"] +#[no_mangle] +pub extern "C" fn rust_eh_personality() {} +``` + +The QNX Neutrino support of Rust has been tested with QNX Neutrino 7.1. + +There are no further known requirements. + +## Conditional compilation + +For conditional compilation, following QNX Neutrino specific attributes are defined: + +- `target_os` = `"nto"` +- `target_env` = `"nto71"` (for QNX Neutrino 7.1) + +## Building the target + +1. Create a `config.toml` + +Example content: + +```toml +profile = "compiler" +changelog-seen = 2 +``` + +2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host (for both `aarch64` and `x86_64` targets) + +Run the following: + +```bash +env \ + CC_aarch64-unknown-nto-qnx710="qcc" \ + CFLAGS_aarch64-unknown-nto-qnx710="-Vgcc_ntoaarch64le_cxx" \ + CXX_aarch64-unknown-nto-qnx710="qcc" \ + AR_aarch64_unknown_nto_qnx710="ntoaarch64-ar" \ + CC_x86_64-pc-nto-qnx710="qcc" \ + CFLAGS_x86_64-pc-nto-qnx710="-Vgcc_ntox86_64_cxx" \ + CXX_x86_64-pc-nto-qnx710="qcc" \ + AR_x86_64_pc_nto_qnx710="ntox86_64-ar" \ + ./x.py build --target aarch64-unknown-nto-qnx710 --target x86_64-pc-nto-qnx710 --target x86_64-unknown-linux-gnu rustc library/core library/alloc/ +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for this target, you must either build Rust with the target enabled (see "Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +## Testing + +Compiled executables can directly be run on QNX Neutrino. + +## Cross-compilation toolchains and C code + +Compiling C code requires the same environment variables to be set as compiling the Rust toolchain (see above), to ensure `qcc` is used with proper arguments. To ensure compatibility, do not specify any further arguments that for example change calling conventions or memory layout. diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md index 295dec0f0..e2bdf73a9 100644 --- a/src/doc/rustc/src/platform-support/unknown-uefi.md +++ b/src/doc/rustc/src/platform-support/unknown-uefi.md @@ -1,6 +1,6 @@ # `*-unknown-uefi` -**Tier: 3** +**Tier: 2** Unified Extensible Firmware Interface (UEFI) targets for application, driver, and core UEFI binaries. @@ -72,28 +72,14 @@ target = ["x86_64-unknown-uefi"] ## Building Rust programs -Rust does not yet ship pre-compiled artifacts for this target. To compile for -this target, you will either need to build Rust with the target enabled (see -"Building rust for UEFI targets" above), or build your own copy of `core` by -using `build-std`, `cargo-buildx`, or similar. - -A native build with the unstable `build-std`-feature can be achieved via: - -```sh -cargo +nightly build \ - -Zbuild-std=core,compiler_builtins \ - -Zbuild-std-features=compiler-builtins-mem \ - --target x86_64-unknown-uefi -``` - -Alternatively, you can install `cargo-xbuild` via -`cargo install --force cargo-xbuild` and build for the UEFI targets via: +Starting with Rust 1.67, precompiled artifacts are provided via +`rustup`. For example, to use `x86_64-unknown-uefi`: ```sh -cargo \ - +nightly \ - xbuild \ - --target x86_64-unknown-uefi +# install cross-compile toolchain +rustup target add x86_64-unknown-uefi +# target flag may be used with any cargo or rustc command +cargo build --target x86_64-unknown-uefi ``` ## Testing @@ -167,18 +153,10 @@ The following code is a valid UEFI application returning immediately upon execution with an exit code of 0. A panic handler is provided. This is executed by rust on panic. For simplicity, we simply end up in an infinite loop. -Note that as of rust-1.31.0, all features used here are stabilized. No unstable -features are required, nor do we rely on nightly compilers. However, if you do -not compile rustc for the UEFI targets, you need a nightly compiler to support -the `-Z build-std` flag. - This example can be compiled as binary crate via `cargo`: ```sh -cargo +nightly build \ - -Zbuild-std=core,compiler_builtins \ - -Zbuild-std-features=compiler-builtins-mem \ - --target x86_64-unknown-uefi +cargo build --target x86_64-unknown-uefi ``` ```rust,ignore (platform-specific,eh-personality-is-unstable) diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md index 53d0470fa..95932db14 100644 --- a/src/doc/rustc/src/target-tier-policy.md +++ b/src/doc/rustc/src/target-tier-policy.md @@ -3,6 +3,7 @@ ## Table of Contents * [General](#general) +* [Adding a new target](#adding-a-new-target) * [Tier 3 target policy](#tier-3-target-policy) * [Tier 2 target policy](#tier-2-target-policy) * [Tier 2 with host tools](#tier-2-with-host-tools) @@ -104,6 +105,30 @@ indicates something entirely optional, and does not indicate guidance or recommendations. This language is based on [IETF RFC 2119](https://tools.ietf.org/html/rfc2119). +## Adding a new target + +New targets typically start as Tier 3 and then can be promoted later. +To propose addition of a new target, open a pull request on [`rust-lang/rust`]: + +- Copy the [Tier 3 target policy](#tier-3-target-policy) to the description + and fill it out, see [example][tier3example]. +- Add a new description for the target in `src/doc/rustc/src/platform-support` + using the [template][platform_template]. +- Add the target to the [SUMMARY.md][summary] (allows wildcards) and + [platform-support.md][platformsupport] (must name all targets verbatim). + Link to the created description page. +- Ensure the pull request is assigned to a member of the [Rust compiler team][rust_compiler_team] by commenting: + ```text + r? compiler-team + ``` + +[tier3example]: https://github.com/rust-lang/rust/pull/94872 +[platform_template]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support/TEMPLATE.md +[summary]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/SUMMARY.md +[platformsupport]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support.md +[rust_compiler_team]: https://www.rust-lang.org/governance/teams/compiler +[`rust-lang/rust`]: https://github.com/rust-lang/rust + ## Tier 3 target policy At this tier, the Rust project provides no official support for a target, so we @@ -133,6 +158,8 @@ approved by the appropriate team for that shared code before acceptance. the name of the target makes people extremely likely to form incorrect beliefs about what it targets, the name should be changed or augmented to disambiguate it. + - If possible, use only letters, numbers, dashes and underscores for the name. + Periods (`.`) are known to cause issues in Cargo. - Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users. diff --git a/src/doc/rustdoc/book.toml b/src/doc/rustdoc/book.toml index 45405a117..dfa685785 100644 --- a/src/doc/rustdoc/book.toml +++ b/src/doc/rustdoc/book.toml @@ -6,5 +6,9 @@ title = "The rustdoc book" git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/rustdoc" [output.html.redirect] +"/what-to-include.html" = "write-documentation/what-to-include.html" "/the-doc-attribute.html" = "write-documentation/the-doc-attribute.html" +"/linking-to-items-by-name.html" = "write-documentation/linking-to-items-by-name.html" "/documentation-tests.html" = "write-documentation/documentation-tests.html" +"/website-features.html" = "advanced-features.html#custom-search-engines" +"/passes.html" = "deprecated-features.html#passes" diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index bff01d7cb..45db3bb9b 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -261,7 +261,7 @@ typo mistakes for some common attributes. ## `invalid_html_tags` -This lint is **allowed by default** and is **nightly-only**. It detects unclosed +This lint **warns by default**. It detects unclosed or invalid HTML tags. For example: ```rust diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md index b02b3c047..216689731 100644 --- a/src/doc/style-guide/src/principles.md +++ b/src/doc/style-guide/src/principles.md @@ -8,7 +8,9 @@ following principles (in rough priority order): - avoiding misleading formatting - accessibility - readable and editable by users using the the widest variety of hardware, including non-visual accessibility interfaces - - readability of code when quoted in rustc error messages + - readability of code in contexts without syntax highlighting or IDE + assistance, such as rustc error messages, diffs, grep, and other + plain-text contexts * aesthetics - sense of 'beauty' diff --git a/src/doc/unstable-book/src/language-features/abi-efiapi.md b/src/doc/unstable-book/src/language-features/abi-efiapi.md new file mode 100644 index 000000000..b492da884 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/abi-efiapi.md @@ -0,0 +1,23 @@ +# `abi_efiapi` + +The tracking issue for this feature is: [#65815] + +[#65815]: https://github.com/rust-lang/rust/issues/65815 + +------------------------ + +The `efiapi` calling convention can be used for defining a function with +an ABI compatible with the UEFI Interfaces as defined in the [UEFI +Specification]. + +Example: + +```rust,ignore (not-all-targets-support-uefi) +#![feature(abi_efiapi)] + +extern "efiapi" { fn f1(); } + +extern "efiapi" fn f2() { todo!() } +``` + +[UEFI Specification]: https://uefi.org/specs/UEFI/2.10/ diff --git a/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md new file mode 100644 index 000000000..b20c30ec8 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md @@ -0,0 +1,10 @@ +# `extended_varargs_abi_support` + +The tracking issue for this feature is: [#100189] + +[#100189]: https://github.com/rust-lang/rust/issues/100189 + +------------------------ + +This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling +conventions on functions with varargs. diff --git a/src/doc/unstable-book/src/language-features/native-link-modifiers-verbatim.md b/src/doc/unstable-book/src/language-features/native-link-modifiers-verbatim.md deleted file mode 100644 index 02bd87e50..000000000 --- a/src/doc/unstable-book/src/language-features/native-link-modifiers-verbatim.md +++ /dev/null @@ -1,20 +0,0 @@ -# `native_link_modifiers_verbatim` - -The tracking issue for this feature is: [#81490] - -[#81490]: https://github.com/rust-lang/rust/issues/81490 - ------------------------- - -The `native_link_modifiers_verbatim` feature allows you to use the `verbatim` modifier. - -`+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes (like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the linker. - -For `ld`-like linkers rustc will use the `-l:filename` syntax (note the colon) when passing the library, so the linker won't add any prefixes or suffixes as well. -See [`-l namespec`](https://sourceware.org/binutils/docs/ld/Options.html) in ld documentation for more details. -For linkers not supporting any verbatim modifiers (e.g. `link.exe` or `ld64`) the library name will be passed as is. - -The default for this modifier is `-verbatim`. - -This RFC changes the behavior of `raw-dylib` linking kind specified by [RFC 2627](https://github.com/rust-lang/rfcs/pull/2627). The `.dll` suffix (or other target-specified suffixes for other targets) is now added automatically. -If your DLL doesn't have the `.dll` suffix, it can be specified with `+verbatim`. |