diff options
Diffstat (limited to 'src/doc')
109 files changed, 1085 insertions, 679 deletions
diff --git a/src/doc/book/src/appendix-06-translation.md b/src/doc/book/src/appendix-06-translation.md index 2c5734354..7e8c68d25 100644 --- a/src/doc/book/src/appendix-06-translation.md +++ b/src/doc/book/src/appendix-06-translation.md @@ -11,7 +11,7 @@ For resources in languages other than English. Most are still in progress; see - [正體中文](https://github.com/rust-tw/book-tw) - [Українська](https://github.com/pavloslav/rust-book-uk-ua) - [Español](https://github.com/thecodix/book), [alternate](https://github.com/ManRR/rust-book-es) -- [Italiano](https://github.com/Ciro-Fusco/book_it) +- [Italiano](https://github.com/EmanueleGurini/book_it) - [Русский](https://github.com/rust-lang-ru/book) - [한국어](https://github.com/rinthel/rust-lang-book-ko) - [日本語](https://github.com/rust-lang-ja/book-ja) diff --git a/src/doc/book/src/ch01-01-installation.md b/src/doc/book/src/ch01-01-installation.md index fa9617ad9..87f37fab2 100644 --- a/src/doc/book/src/ch01-01-installation.md +++ b/src/doc/book/src/ch01-01-installation.md @@ -28,7 +28,7 @@ these steps should work as expected with the content of this book. If you’re using Linux or macOS, open a terminal and enter the following command: ```console -$ curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh +$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh ``` The command downloads a script and starts the installation of the `rustup` diff --git a/src/doc/book/src/ch02-00-guessing-game-tutorial.md b/src/doc/book/src/ch02-00-guessing-game-tutorial.md index 4dac23764..4f2857333 100644 --- a/src/doc/book/src/ch02-00-guessing-game-tutorial.md +++ b/src/doc/book/src/ch02-00-guessing-game-tutorial.md @@ -291,7 +291,7 @@ let y = 10; println!("x = {x} and y + 2 = {}", y + 2); ``` -This code would print `x = 5 and y = 12`. +This code would print `x = 5 and y + 2 = 12`. ### Testing the First Part diff --git a/src/doc/book/src/ch13-03-improving-our-io-project.md b/src/doc/book/src/ch13-03-improving-our-io-project.md index b9ef0b430..42a5be89d 100644 --- a/src/doc/book/src/ch13-03-improving-our-io-project.md +++ b/src/doc/book/src/ch13-03-improving-our-io-project.md @@ -28,7 +28,7 @@ we would remove them in the future. Well, that time is now! We needed `clone` here because we have a slice with `String` elements in the parameter `args`, but the `build` function doesn’t own `args`. To return ownership of a `Config` instance, we had to clone the values from the `query` -and `filename` fields of `Config` so the `Config` instance can own its values. +and `file_path` fields of `Config` so the `Config` instance can own its values. With our new knowledge about iterators, we can change the `build` function to take ownership of an iterator as its argument instead of borrowing a slice. @@ -118,7 +118,7 @@ the program. We want to ignore that and get to the next value, so first we call value we want to put in the `query` field of `Config`. If `next` returns a `Some`, we use a `match` to extract the value. If it returns `None`, it means not enough arguments were given and we return early with an `Err` value. We do -the same thing for the `filename` value. +the same thing for the `file_path` value. ### Making Code Clearer with Iterator Adaptors diff --git a/src/doc/nomicon/src/borrow-splitting.md b/src/doc/nomicon/src/borrow-splitting.md index 3d13ff954..08b6d0d48 100644 --- a/src/doc/nomicon/src/borrow-splitting.md +++ b/src/doc/nomicon/src/borrow-splitting.md @@ -159,7 +159,7 @@ impl<'a, T> Iterator for IterMut<'a, T> { type Item = &'a mut T; fn next(&mut self) -> Option<Self::Item> { - let slice = mem::replace(&mut self.0, &mut []); + let slice = mem::take(&mut self.0); if slice.is_empty() { return None; } let (l, r) = slice.split_at_mut(1); @@ -170,7 +170,7 @@ impl<'a, T> Iterator for IterMut<'a, T> { impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { fn next_back(&mut self) -> Option<Self::Item> { - let slice = mem::replace(&mut self.0, &mut []); + let slice = mem::take(&mut self.0); if slice.is_empty() { return None; } let new_len = slice.len() - 1; diff --git a/src/doc/nomicon/src/ffi.md b/src/doc/nomicon/src/ffi.md index 9b0ff98e6..8d1a882b3 100644 --- a/src/doc/nomicon/src/ffi.md +++ b/src/doc/nomicon/src/ffi.md @@ -659,7 +659,8 @@ Certain Rust types are defined to never be `null`. This includes references (`&T `&mut T`), boxes (`Box<T>`), and function pointers (`extern "abi" fn()`). When interfacing with C, pointers that might be `null` are often used, which would seem to require some messy `transmute`s and/or unsafe code to handle conversions to/from Rust types. -However, the language provides a workaround. +However, trying to construct/work with these invalid values **is undefined behavior**, +so you should use the following workaround instead. As a special case, an `enum` is eligible for the "nullable pointer optimization" if it contains exactly two variants, one of which contains no data and the other contains a field of one of the diff --git a/src/doc/nomicon/src/lifetime-mismatch.md b/src/doc/nomicon/src/lifetime-mismatch.md index bc53f06f8..ecb6cf205 100644 --- a/src/doc/nomicon/src/lifetime-mismatch.md +++ b/src/doc/nomicon/src/lifetime-mismatch.md @@ -65,7 +65,7 @@ fn main() { The lifetime system is forced to extend the `&mut foo` to have lifetime `'c`, due to the lifetime of `loan` and `mutate_and_share`'s signature. Then when we -try to call `share`, and it sees we're trying to alias that `&'c mut foo` and +try to call `share`, it sees we're trying to alias that `&'c mut foo` and blows up in our face! This program is clearly correct according to the reference semantics we actually diff --git a/src/doc/nomicon/src/vec/vec-raw.md b/src/doc/nomicon/src/vec/vec-raw.md index 728feaa58..0bca2daf8 100644 --- a/src/doc/nomicon/src/vec/vec-raw.md +++ b/src/doc/nomicon/src/vec/vec-raw.md @@ -28,18 +28,13 @@ impl<T> RawVec<T> { } fn grow(&mut self) { - let (new_cap, new_layout) = if self.cap == 0 { - (1, Layout::array::<T>(1).unwrap()) - } else { - // This can't overflow because we ensure self.cap <= isize::MAX. - let new_cap = 2 * self.cap; - - // Layout::array checks that the number of bytes is <= usize::MAX, - // but this is redundant since old_layout.size() <= isize::MAX, - // so the `unwrap` should never fail. - let new_layout = Layout::array::<T>(new_cap).unwrap(); - (new_cap, new_layout) - }; + // This can't overflow because we ensure self.cap <= isize::MAX. + let new_cap = if self.cap == 0 { 1 } else { 2 * self.cap }; + + // Layout::array checks that the number of bytes is <= usize::MAX, + // but this is redundant since old_layout.size() <= isize::MAX, + // so the `unwrap` should never fail. + let new_layout = Layout::array::<T>(new_cap).unwrap(); // Ensure that the new allocation doesn't exceed `isize::MAX` bytes. assert!(new_layout.size() <= isize::MAX as usize, "Allocation too large"); diff --git a/src/doc/reference/src/const_eval.md b/src/doc/reference/src/const_eval.md index c0560376c..34e34d703 100644 --- a/src/doc/reference/src/const_eval.md +++ b/src/doc/reference/src/const_eval.md @@ -113,7 +113,7 @@ Conversely, the following are possible in a const function, but not in a const c [Const parameters]: items/generics.md [dereference operator]: expressions/operator-expr.md#the-dereference-operator [destructors]: destructors.md -[enum discriminants]: items/enumerations.md#custom-discriminant-values-for-fieldless-enumerations +[enum discriminants]: items/enumerations.md#discriminants [expression statements]: statements.md#expression-statements [expressions]: expressions.md [field]: expressions/field-expr.md diff --git a/src/doc/reference/src/destructors.md b/src/doc/reference/src/destructors.md index 242d9b2db..f89fde157 100644 --- a/src/doc/reference/src/destructors.md +++ b/src/doc/reference/src/destructors.md @@ -271,8 +271,9 @@ let x = &mut 0; println!("{}", x); ``` -If a borrow, dereference, field, or tuple indexing expression has an extended -temporary scope then so does its operand. If an indexing expression has an +If a [borrow][borrow expression], [dereference][dereference expression], +[field][field expression], or [tuple indexing expression] has an extended +temporary scope then so does its operand. If an [indexing expression] has an extended temporary scope then the indexed expression also has an extended temporary scope. @@ -384,8 +385,12 @@ variable or field from being dropped automatically. [block expression]: expressions/block-expr.md [borrow expression]: expressions/operator-expr.md#borrow-operators [cast expression]: expressions/operator-expr.md#type-cast-expressions +[dereference expression]: expressions/operator-expr.md#the-dereference-operator +[field expression]: expressions/field-expr.md +[indexing expression]: expressions/array-expr.md#array-and-slice-indexing-expressions [struct expression]: expressions/struct-expr.md [tuple expression]: expressions/tuple-expr.md#tuple-expressions +[tuple indexing expression]: expressions/tuple-expr.md#tuple-indexing-expressions [`for`]: expressions/loop-expr.md#iterator-loops [`if let`]: expressions/if-expr.md#if-let-expressions diff --git a/src/doc/reference/src/expressions/field-expr.md b/src/doc/reference/src/expressions/field-expr.md index 93777b3a7..11c2d3d3d 100644 --- a/src/doc/reference/src/expressions/field-expr.md +++ b/src/doc/reference/src/expressions/field-expr.md @@ -37,7 +37,7 @@ foo().x; ## Automatic dereferencing If the type of the container operand implements [`Deref`] or [`DerefMut`][`Deref`] depending on whether the operand is [mutable], it is *automatically dereferenced* as many times as necessary to make the field access possible. -This processes is also called *autoderef* for short. +This process is also called *autoderef* for short. ## Borrowing diff --git a/src/doc/reference/src/expressions/operator-expr.md b/src/doc/reference/src/expressions/operator-expr.md index d8658d647..9f7e8edac 100644 --- a/src/doc/reference/src/expressions/operator-expr.md +++ b/src/doc/reference/src/expressions/operator-expr.md @@ -368,7 +368,7 @@ reference types and `mut` or `const` in pointer types. | Type of `e` | `U` | Cast performed by `e as U` | |-----------------------|-----------------------|----------------------------------| | Integer or Float type | Integer or Float type | Numeric cast | -| C-like enum | Integer type | Enum cast | +| Enumeration | Integer type | Enum cast | | `bool` or `char` | Integer type | Primitive to integer cast | | `u8` | `char` | `u8` to `char` cast | | `*T` | `*V` where `V: Sized` \* | Pointer to pointer cast | @@ -430,6 +430,10 @@ halfway between two floating point numbers. #### Enum cast Casts an enum to its discriminant, then uses a numeric cast if needed. +Casting is limited to the following kinds of enumerations: + +* [Unit-only enums] +* [Field-less enums] without [explicit discriminants], or where only unit-variants have explicit discriminants #### Primitive to integer cast @@ -632,6 +636,8 @@ See [this test] for an example of using this dependency. [copies or moves]: ../expressions.md#moved-and-copied-types [dropping]: ../destructors.md +[explicit discriminants]: ../items/enumerations.md#explicit-discriminants +[field-less enums]: ../items/enumerations.md#field-less-enum [grouped expression]: grouped-expr.md [literal expression]: literal-expr.md#integer-literal-expressions [logical and]: ../types/boolean.md#logical-and @@ -643,6 +649,7 @@ See [this test] for an example of using this dependency. [assignee expression]: ../expressions.md#place-expressions-and-value-expressions [undefined behavior]: ../behavior-considered-undefined.md [unit]: ../types/tuple.md +[Unit-only enums]: ../items/enumerations.md#unit-only-enum [value expression]: ../expressions.md#place-expressions-and-value-expressions [temporary value]: ../expressions.md#temporaries [this test]: https://github.com/rust-lang/rust/blob/1.58.0/src/test/ui/expr/compound-assignment/eval-order.rs diff --git a/src/doc/reference/src/items/enumerations.md b/src/doc/reference/src/items/enumerations.md index 28d3ba873..0d42bfd05 100644 --- a/src/doc/reference/src/items/enumerations.md +++ b/src/doc/reference/src/items/enumerations.md @@ -13,8 +13,8 @@ > > _EnumItem_ :\ > _OuterAttribute_<sup>\*</sup> [_Visibility_]<sup>?</sup>\ -> [IDENTIFIER] ( _EnumItemTuple_ | _EnumItemStruct_ -> | _EnumItemDiscriminant_ )<sup>?</sup> +> [IDENTIFIER] ( _EnumItemTuple_ | _EnumItemStruct_ )<sup>?</sup> +> _EnumItemDiscriminant_<sup>?</sup> > > _EnumItemTuple_ :\ > `(` [_TupleFields_]<sup>?</sup> `)` @@ -56,22 +56,71 @@ a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 }; ``` In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is simply -called an enum variant. Each enum instance has a _discriminant_ which is an -integer associated to it that is used to determine which variant it holds. An -opaque reference to this discriminant can be obtained with the -[`mem::discriminant`] function. +called an enum variant. -## Custom Discriminant Values for Fieldless Enumerations +An enum where no constructors contain fields are called a +*<span id="field-less-enum">field-less enum</span>*. For example, this is a fieldless enum: -If there is no data attached to *any* of the variants of an enumeration, -then the discriminant can be directly chosen and accessed. +```rust +enum Fieldless { + Tuple(), + Struct{}, + Unit, +} +``` + +If a field-less enum only contains unit variants, the enum is called an +*<span id="unit-only-enum">unit-only enum</span>*. For example: + +```rust +enum Enum { + Foo = 3, + Bar = 2, + Baz = 1, +} +``` + +<span id="custom-discriminant-values-for-fieldless-enumerations"></span> +## Discriminants + +Each enum instance has a _discriminant_: an integer logically associated to it +that is used to determine which variant it holds. + +Under the [default representation], the discriminant is interpreted as +an `isize` value. However, the compiler is allowed to use a smaller type (or +another means of distinguishing variants) in its actual memory layout. + +### Assigning discriminant values + +#### Explicit discriminants -These enumerations can be cast to integer types with the `as` operator by a -[numeric cast]. The enumeration can optionally specify which integer each -discriminant gets by following the variant name with `=` followed by a [constant -expression]. If the first variant in the declaration is unspecified, then it is -set to zero. For every other unspecified discriminant, it is set to one higher -than the previous variant in the declaration. +In two circumstances, the discriminant of a variant may be explicitly set by +following the variant name with `=` and a [constant expression]: + + +1. if the enumeration is "[unit-only]". + + +2. if a [primitive representation] is used. For example: + + ```rust + #[repr(u8)] + enum Enum { + Unit = 3, + Tuple(u16), + Struct { + a: u8, + b: u16, + } = 1, + } + ``` + +#### Implicit discriminants + +If a discriminant for a variant is not specified, then it is set to one higher +than the discriminant of the previous variant in the declaration. If the +discriminant of the first variant in the declaration is unspecified, then +it is set to zero. ```rust enum Foo { @@ -84,10 +133,7 @@ let baz_discriminant = Foo::Baz as u32; assert_eq!(baz_discriminant, 123); ``` -Under the [default representation], the specified discriminant is interpreted as -an `isize` value although the compiler is allowed to use a smaller type in the -actual memory layout. The size and thus acceptable values can be changed by -using a [primitive representation] or the [`C` representation]. +#### Restrictions It is an error when two variants share the same discriminant. @@ -122,7 +168,89 @@ enum OverflowingDiscriminantError2 { } ``` -## Zero-variant Enums +### Accessing discriminant + +#### Via `mem::discriminant` + +[`mem::discriminant`] returns an opaque reference to the discriminant of +an enum value which can be compared. This cannot be used to get the value +of the discriminant. + +#### Casting + +If an enumeration is [unit-only] (with no tuple and struct variants), then its +discriminant can be directly accessed with a [numeric cast]; e.g.: + +```rust +enum Enum { + Foo, + Bar, + Baz, +} + +assert_eq!(0, Enum::Foo as isize); +assert_eq!(1, Enum::Bar as isize); +assert_eq!(2, Enum::Baz as isize); +``` + +[Field-less enums] can be casted if they do not have explicit discriminants, or where only unit variants are explicit. + +```rust +enum Fieldless { + Tuple(), + Struct{}, + Unit, +} + +assert_eq!(0, Fieldless::Tuple() as isize); +assert_eq!(1, Fieldless::Struct{} as isize); +assert_eq!(2, Fieldless::Unit as isize); + +#[repr(u8)] +enum FieldlessWithDiscrimants { + First = 10, + Tuple(), + Second = 20, + Struct{}, + Unit, +} + +assert_eq!(10, FieldlessWithDiscrimants::First as u8); +assert_eq!(11, FieldlessWithDiscrimants::Tuple() as u8); +assert_eq!(20, FieldlessWithDiscrimants::Second as u8); +assert_eq!(21, FieldlessWithDiscrimants::Struct{} as u8); +assert_eq!(22, FieldlessWithDiscrimants::Unit as u8); +``` + +#### Pointer casting + +If the enumeration specifies a [primitive representation], then the +discriminant may be reliably accessed via unsafe pointer casting: + +```rust +#[repr(u8)] +enum Enum { + Unit, + Tuple(bool), + Struct{a: bool}, +} + +impl Enum { + fn discriminant(&self) -> u8 { + unsafe { *(self as *const Self as *const u8) } + } +} + +let unit_like = Enum::Unit; +let tuple_like = Enum::Tuple(true); +let struct_like = Enum::Struct{a: false}; + +assert_eq!(0, unit_like.discriminant()); +assert_eq!(1, tuple_like.discriminant()); +assert_eq!(2, struct_like.discriminant()); +``` + +## Zero-variant enums Enums with zero variants are known as *zero-variant enums*. As they have no valid values, they cannot be instantiated. @@ -181,8 +309,10 @@ enum E { [enumerated type]: ../types/enum.md [`mem::discriminant`]: ../../std/mem/fn.discriminant.html [never type]: ../types/never.md +[unit-only]: #unit-only-enum [numeric cast]: ../expressions/operator-expr.md#semantics [constant expression]: ../const_eval.md#constant-expressions [default representation]: ../type-layout.md#the-default-representation [primitive representation]: ../type-layout.md#primitive-representations [`C` representation]: ../type-layout.md#the-c-representation +[Field-less enums]: #field-less-enum diff --git a/src/doc/reference/src/type-layout.md b/src/doc/reference/src/type-layout.md index 80a36abb8..191567a42 100644 --- a/src/doc/reference/src/type-layout.md +++ b/src/doc/reference/src/type-layout.md @@ -583,7 +583,7 @@ used with any other representation. [`Sized`]: ../std/marker/trait.Sized.html [`Copy`]: ../std/marker/trait.Copy.html [dynamically sized types]: dynamically-sized-types.md -[field-less enums]: items/enumerations.md#custom-discriminant-values-for-fieldless-enumerations +[field-less enums]: items/enumerations.md#field-less-enum [enumerations]: items/enumerations.md [zero-variant enums]: items/enumerations.md#zero-variant-enums [undefined behavior]: behavior-considered-undefined.md diff --git a/src/doc/reference/triagebot.toml b/src/doc/reference/triagebot.toml index 4059f9190..4a29166cb 100644 --- a/src/doc/reference/triagebot.toml +++ b/src/doc/reference/triagebot.toml @@ -4,3 +4,5 @@ allow-unauthenticated = [ ] [assign] + +[shortcut] diff --git a/src/doc/rust-by-example/src/SUMMARY.md b/src/doc/rust-by-example/src/SUMMARY.md index 9d7001690..b1bcf223d 100644 --- a/src/doc/rust-by-example/src/SUMMARY.md +++ b/src/doc/rust-by-example/src/SUMMARY.md @@ -59,6 +59,7 @@ - [Guards](flow_control/match/guard.md) - [Binding](flow_control/match/binding.md) - [if let](flow_control/if_let.md) + - [let-else](flow_control/let_else.md) - [while let](flow_control/while_let.md) - [Functions](fn.md) diff --git a/src/doc/rust-by-example/src/custom_types/enum.md b/src/doc/rust-by-example/src/custom_types/enum.md index e861df9bf..b7fb7e419 100644 --- a/src/doc/rust-by-example/src/custom_types/enum.md +++ b/src/doc/rust-by-example/src/custom_types/enum.md @@ -1,7 +1,7 @@ # Enums The `enum` keyword allows the creation of a type which may be one of a few -different variants. Any variant which is valid as a `struct` is also valid as +different variants. Any variant which is valid as a `struct` is also valid in an `enum`. ```rust,editable @@ -10,7 +10,7 @@ an `enum`. // `PageLoad != PageUnload` and `KeyPress(char) != Paste(String)`. // Each is different and independent. enum WebEvent { - // An `enum` may either be `unit-like`, + // An `enum` variant may either be `unit-like`, PageLoad, PageUnload, // like tuple structs, @@ -26,7 +26,7 @@ fn inspect(event: WebEvent) { match event { WebEvent::PageLoad => println!("page loaded"), WebEvent::PageUnload => println!("page unloaded"), - // Destructure `c` from inside the `enum`. + // Destructure `c` from inside the `enum` variant. WebEvent::KeyPress(c) => println!("pressed '{}'.", c), WebEvent::Paste(s) => println!("pasted \"{}\".", s), // Destructure `Click` into `x` and `y`. diff --git a/src/doc/rust-by-example/src/error/option_unwrap/defaults.md b/src/doc/rust-by-example/src/error/option_unwrap/defaults.md index 117333f12..4c1844a20 100644 --- a/src/doc/rust-by-example/src/error/option_unwrap/defaults.md +++ b/src/doc/rust-by-example/src/error/option_unwrap/defaults.md @@ -63,17 +63,17 @@ fn main() { To make sure that an `Option` contains a value, we can use `get_or_insert` to modify it in place with a fallback value, as is shown in the following example. Note that `get_or_insert` eagerly evaluates its parameter, so variable `apple` is moved: ```rust,editable -#[derive(Debug)] +#[derive(Debug)] enum Fruit { Apple, Orange, Banana, Kiwi, Lemon } fn main() { let mut my_fruit: Option<Fruit> = None; let apple = Fruit::Apple; let first_available_fruit = my_fruit.get_or_insert(apple); - println!("my_fruit is: {:?}", first_available_fruit); println!("first_available_fruit is: {:?}", first_available_fruit); - // my_fruit is: Apple + println!("my_fruit is: {:?}", my_fruit); // first_available_fruit is: Apple + // my_fruit is: Some(Apple) //println!("Variable named `apple` is moved: {:?}", apple); // TODO: uncomment the line above to see the compiler error } @@ -94,11 +94,11 @@ fn main() { }; let first_available_fruit = my_fruit .get_or_insert_with(get_lemon_as_fallback); - println!("my_fruit is: {:?}", first_available_fruit); println!("first_available_fruit is: {:?}", first_available_fruit); + println!("my_fruit is: {:?}", my_fruit); // Providing lemon as fallback - // my_fruit is: Lemon // first_available_fruit is: Lemon + // my_fruit is: Some(Lemon) // If the Option has a value, it is left unchanged, and the closure is not invoked let mut my_apple = Some(Fruit::Apple); diff --git a/src/doc/rust-by-example/src/flow_control/let_else.md b/src/doc/rust-by-example/src/flow_control/let_else.md new file mode 100644 index 000000000..bc21723c7 --- /dev/null +++ b/src/doc/rust-by-example/src/flow_control/let_else.md @@ -0,0 +1,60 @@ +# let-else + + +> 🛈 stable since: rust 1.65 + + +With `let`-`else`, a refutable pattern can match and bind variables +in the surrounding scope like a normal `let`, or else diverge (e.g. `break`, +`return`, `panic!`) when the pattern doesn't match. + +```rust +use std::str::FromStr; + +fn get_count_item(s: &str) -> (u64, &str) { + let mut it = s.split(' '); + let (Some(count_str), Some(item)) = (it.next(), it.next()) else { + panic!("Can't segment count item pair: '{s}'"); + }; + let Ok(count) = u64::from_str(count_str) else { + panic!("Can't parse integer: '{count_str}'"); + }; + (count, item) +} + +assert_eq!(get_count_item("3 chairs"), (3, "chairs")); +``` + +The scope of name bindings is the main thing that makes this different from +`match` or `if let`-`else` expressions. You could previously approximate these +patterns with an unfortunate bit of repetition and an outer `let`: + +```rust +# use std::str::FromStr; +# +# fn get_count_item(s: &str) -> (u64, &str) { +# let mut it = s.split(' '); + let (count_str, item) = match (it.next(), it.next()) { + (Some(count_str), Some(item)) => (count_str, item), + _ => panic!("Can't segment count item pair: '{s}'"), + }; + let count = if let Ok(count) = u64::from_str(count_str) { + count + } else { + panic!("Can't parse integer: '{count_str}'"); + }; +# (count, item) +# } +# +# assert_eq!(get_count_item("3 chairs"), (3, "chairs")); +``` + +### See also: + +[option][option], [match][match], [if let][if_let] and the [let-else RFC][let_else_rfc]. + + +[match]: ./match.md +[if_let]: ./if_let.md +[let_else_rfc]: https://rust-lang.github.io/rfcs/3137-let-else.html +[option]: ../std/option.md
\ No newline at end of file diff --git a/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_any.md b/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_any.md index fe7fc39f8..4c19caccc 100644 --- a/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_any.md +++ b/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_any.md @@ -27,7 +27,7 @@ fn main() { // `iter()` for vecs yields `&i32`. Destructure to `i32`. println!("2 in vec1: {}", vec1.iter() .any(|&x| x == 2)); // `into_iter()` for vecs yields `i32`. No destructuring required. - println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2)); + println!("2 in vec2: {}", vec2.into_iter().any(|x| x == 2)); // `iter()` only borrows `vec1` and its elements, so they can be used again println!("vec1 len: {}", vec1.len()); diff --git a/src/doc/rust-by-example/src/fn/diverging.md b/src/doc/rust-by-example/src/fn/diverging.md index 52e1f819a..4bc7c9fea 100644 --- a/src/doc/rust-by-example/src/fn/diverging.md +++ b/src/doc/rust-by-example/src/fn/diverging.md @@ -21,8 +21,8 @@ fn some_fn() { } fn main() { - let a: () = some_fn(); - println!("This function returns and you can see this line.") + let _a: () = some_fn(); + println!("This function returns and you can see this line."); } ``` diff --git a/src/doc/rust-by-example/src/hello.md b/src/doc/rust-by-example/src/hello.md index 2a8d3153f..4aaddeb1f 100644 --- a/src/doc/rust-by-example/src/hello.md +++ b/src/doc/rust-by-example/src/hello.md @@ -3,18 +3,19 @@ This is the source code of the traditional Hello World program. ```rust,editable -// This is a comment, and is ignored by the compiler +// This is a comment, and is ignored by the compiler. // You can test this code by clicking the "Run" button over there -> -// or if you prefer to use your keyboard, you can use the "Ctrl + Enter" shortcut +// or if you prefer to use your keyboard, you can use the "Ctrl + Enter" +// shortcut. // This code is editable, feel free to hack it! // You can always return to the original code by clicking the "Reset" button -> -// This is the main function +// This is the main function. fn main() { - // Statements here are executed when the compiled binary is called + // Statements here are executed when the compiled binary is called. - // Print text to the console + // Print text to the console. println!("Hello World!"); } ``` @@ -38,8 +39,7 @@ Hello World! ### Activity Click 'Run' above to see the expected output. Next, add a new -line with a second `println!` macro so that the output -shows: +line with a second `println!` macro so that the output shows: ```text Hello World! diff --git a/src/doc/rust-by-example/src/hello/comment.md b/src/doc/rust-by-example/src/hello/comment.md index 8cd1ccf55..5027f0a22 100644 --- a/src/doc/rust-by-example/src/hello/comment.md +++ b/src/doc/rust-by-example/src/hello/comment.md @@ -4,30 +4,29 @@ Any program requires comments, and Rust supports a few different varieties: * *Regular comments* which are ignored by the compiler: - * `// Line comments which go to the end of the line.` - * `/* Block comments which go to the closing delimiter. */` -* *Doc comments* which are parsed into HTML library - [documentation][docs]: - * `/// Generate library docs for the following item.` - * `//! Generate library docs for the enclosing item.` + * `// Line comments which go to the end of the line.` + * `/* Block comments which go to the closing delimiter. */` +* *Doc comments* which are parsed into HTML library [documentation][docs]: + * `/// Generate library docs for the following item.` + * `//! Generate library docs for the enclosing item.` ```rust,editable fn main() { - // This is an example of a line comment - // There are two slashes at the beginning of the line - // And nothing written inside these will be read by the compiler + // This is an example of a line comment. + // There are two slashes at the beginning of the line. + // And nothing written inside these will be read by the compiler. // println!("Hello, world!"); // Run it. See? Now try deleting the two slashes, and run it again. - /* + /* * This is another type of comment, a block comment. In general, - * line comments are the recommended comment style. But - * block comments are extremely useful for temporarily disabling - * chunks of code. /* Block comments can be /* nested, */ */ - * so it takes only a few keystrokes to comment out everything - * in this main() function. /*/*/* Try it yourself! */*/*/ + * line comments are the recommended comment style. But block comments + * are extremely useful for temporarily disabling chunks of code. + * /* Block comments can be /* nested, */ */ so it takes only a few + * keystrokes to comment out everything in this main() function. + * /*/*/* Try it yourself! */*/*/ */ /* @@ -41,7 +40,6 @@ fn main() { let x = 5 + /* 90 + */ 5; println!("Is `x` 10 or 100? x = {}", x); } - ``` ### See also: diff --git a/src/doc/rust-by-example/src/hello/print.md b/src/doc/rust-by-example/src/hello/print.md index cce838fc2..55f6ed520 100644 --- a/src/doc/rust-by-example/src/hello/print.md +++ b/src/doc/rust-by-example/src/hello/print.md @@ -1,12 +1,14 @@ # Formatted print -Printing is handled by a series of [`macros`][macros] defined in [`std::fmt`][fmt] -some of which include: +Printing is handled by a series of [`macros`][macros] defined in +[`std::fmt`][fmt] some of which include: * `format!`: write formatted text to [`String`][string] -* `print!`: same as `format!` but the text is printed to the console (io::stdout). +* `print!`: same as `format!` but the text is printed to the console + (io::stdout). * `println!`: same as `print!` but a newline is appended. -* `eprint!`: same as `print!` but the text is printed to the standard error (io::stderr). +* `eprint!`: same as `print!` but the text is printed to the standard error + (io::stderr). * `eprintln!`: same as `eprint!` but a newline is appended. All parse text in the same fashion. As a plus, Rust checks formatting @@ -20,7 +22,7 @@ fn main() { // Positional arguments can be used. Specifying an integer inside `{}` // determines which additional argument will be replaced. Arguments start - // at 0 immediately after the format string + // at 0 immediately after the format string. println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); // As can named arguments. @@ -29,13 +31,13 @@ fn main() { subject="the quick brown fox", verb="jumps over"); - // Different formatting can be invoked by specifying the format character after a - // `:`. - println!("Base 10: {}", 69420); //69420 - println!("Base 2 (binary): {:b}", 69420); //10000111100101100 - println!("Base 8 (octal): {:o}", 69420); //207454 - println!("Base 16 (hexadecimal): {:x}", 69420); //10f2c - println!("Base 16 (hexadecimal): {:X}", 69420); //10F2C + // Different formatting can be invoked by specifying the format character + // after a `:`. + println!("Base 10: {}", 69420); // 69420 + println!("Base 2 (binary): {:b}", 69420); // 10000111100101100 + println!("Base 8 (octal): {:o}", 69420); // 207454 + println!("Base 16 (hexadecimal): {:x}", 69420); // 10f2c + println!("Base 16 (hexadecimal): {:X}", 69420); // 10F2C // You can right-justify text with a specified width. This will @@ -43,32 +45,31 @@ fn main() { println!("{number:>5}", number=1); // You can pad numbers with extra zeroes, - //and left-adjust by flipping the sign. This will output "10000". + // and left-adjust by flipping the sign. This will output "10000". println!("{number:0<5}", number=1); - // You can use named arguments in the format specifier by appending a `$` + // You can use named arguments in the format specifier by appending a `$`. println!("{number:0>width$}", number=1, width=5); - // Rust even checks to make sure the correct number of arguments are - // used. + // Rust even checks to make sure the correct number of arguments are used. println!("My name is {0}, {1} {0}", "Bond"); // FIXME ^ Add the missing argument: "James" // Only types that implement fmt::Display can be formatted with `{}`. User- - // defined types do not implement fmt::Display by default + // defined types do not implement fmt::Display by default. - #[allow(dead_code)] + #[allow(dead_code)] // disable `dead_code` which warn against unused module struct Structure(i32); // This will not compile because `Structure` does not implement - // fmt::Display + // fmt::Display. //println!("This struct `{}` won't print...", Structure(3)); // TODO ^ Try uncommenting this line // For Rust 1.58 and above, you can directly capture the argument from a // surrounding variable. Just like the above, this will output - // " 1". 4 white spaces and a "1". + // " 1", 4 white spaces and a "1". let number: f64 = 1.0; let width: usize = 5; println!("{number:>width$}"); @@ -80,7 +81,7 @@ of text. The base form of two important ones are listed below: * `fmt::Debug`: Uses the `{:?}` marker. Format text for debugging purposes. * `fmt::Display`: Uses the `{}` marker. Format text in a more elegant, user -friendly fashion. + friendly fashion. Here, we used `fmt::Display` because the std library provides implementations for these types. To print text for custom types, more steps are required. @@ -88,21 +89,22 @@ for these types. To print text for custom types, more steps are required. Implementing the `fmt::Display` trait automatically implements the [`ToString`] trait which allows us to [convert] the type to [`String`][string]. +In *line 46*, `#[allow(dead_code)]` is an [attribute] which only apply to the module after it. + ### Activities - * Fix the issue in the above code (see FIXME) so that it runs without - error. - * Try uncommenting the line that attempts to format the `Structure` struct (see TODO) - * Add a `println!` macro call that prints: `Pi is roughly 3.142` by controlling - the number of decimal places shown. For the purposes of this exercise, - use `let pi = 3.141592` as an estimate for pi. (Hint: you may need to - check the [`std::fmt`][fmt] documentation for setting the number of - decimals to display) +* Fix the issue in the above code (see FIXME) so that it runs without + error. +* Try uncommenting the line that attempts to format the `Structure` struct + (see TODO) +* Add a `println!` macro call that prints: `Pi is roughly 3.142` by controlling + the number of decimal places shown. For the purposes of this exercise, use + `let pi = 3.141592` as an estimate for pi. (Hint: you may need to check the + [`std::fmt`][fmt] documentation for setting the number of decimals to display) ### See also: -[`std::fmt`][fmt], [`macros`][macros], [`struct`][structs], -and [`traits`][traits] +[`std::fmt`][fmt], [`macros`][macros], [`struct`][structs], [`traits`][traits], and [`dead_code`][dead_code] [fmt]: https://doc.rust-lang.org/std/fmt/ [macros]: ../macros.md @@ -111,3 +113,5 @@ and [`traits`][traits] [traits]: https://doc.rust-lang.org/std/fmt/#formatting-traits [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html [convert]: ../conversion/string.md +[attribute]: ../attribute.md +[dead_code]: ../attribute/unused.md diff --git a/src/doc/rust-by-example/src/hello/print/fmt.md b/src/doc/rust-by-example/src/hello/print/fmt.md index 82c3e0145..5332b4903 100644 --- a/src/doc/rust-by-example/src/hello/print/fmt.md +++ b/src/doc/rust-by-example/src/hello/print/fmt.md @@ -3,8 +3,7 @@ We've seen that formatting is specified via a *format string*: * `format!("{}", foo)` -> `"3735928559"` -* `format!("0x{:X}", foo)` -> - [`"0xDEADBEEF"`][deadbeef] +* `format!("0x{:X}", foo)` -> [`"0xDEADBEEF"`][deadbeef] * `format!("0o{:o}", foo)` -> `"0o33653337357"` The same variable (`foo`) can be formatted differently depending on which @@ -26,13 +25,13 @@ struct City { } impl Display for City { - // `f` is a buffer, and this method must write the formatted string into it + // `f` is a buffer, and this method must write the formatted string into it. fn fmt(&self, f: &mut Formatter) -> fmt::Result { let lat_c = if self.lat >= 0.0 { 'N' } else { 'S' }; let lon_c = if self.lon >= 0.0 { 'E' } else { 'W' }; // `write!` is like `format!`, but it will write the formatted string - // into a buffer (the first argument) + // into a buffer (the first argument). write!(f, "{}: {:.3}°{} {:.3}°{}", self.name, self.lat.abs(), lat_c, self.lon.abs(), lon_c) } @@ -69,6 +68,7 @@ You can view a [full list of formatting traits][fmt_traits] and their argument types in the [`std::fmt`][fmt] documentation. ### Activity + Add an implementation of the `fmt::Display` trait for the `Color` struct above so that the output displays as: @@ -79,8 +79,9 @@ RGB (0, 0, 0) 0x000000 ``` Two hints if you get stuck: - * You [may need to list each color more than once][named_parameters], - * You can [pad with zeros to a width of 2][fmt_width] with `:0>2`. + +* You [may need to list each color more than once][named_parameters]. +* You can [pad with zeros to a width of 2][fmt_width] with `:0>2`. ### See also: diff --git a/src/doc/rust-by-example/src/hello/print/print_debug.md b/src/doc/rust-by-example/src/hello/print/print_debug.md index 161b0b772..03b1975ee 100644 --- a/src/doc/rust-by-example/src/hello/print/print_debug.md +++ b/src/doc/rust-by-example/src/hello/print/print_debug.md @@ -43,15 +43,15 @@ fn main() { // `Structure` is printable! println!("Now {:?} will print!", Structure(3)); - + // The problem with `derive` is there is no control over how // the results look. What if I want this to just show a `7`? println!("Now {:?} will print!", Deep(Structure(7))); } ``` -So `fmt::Debug` definitely makes this printable but sacrifices some -elegance. Rust also provides "pretty printing" with `{:#?}`. +So `fmt::Debug` definitely makes this printable but sacrifices some elegance. +Rust also provides "pretty printing" with `{:#?}`. ```rust,editable #[derive(Debug)] diff --git a/src/doc/rust-by-example/src/hello/print/print_display.md b/src/doc/rust-by-example/src/hello/print/print_display.md index fdae9648a..5d8a45b12 100644 --- a/src/doc/rust-by-example/src/hello/print/print_display.md +++ b/src/doc/rust-by-example/src/hello/print/print_display.md @@ -41,7 +41,7 @@ or for any other generic containers. `fmt::Debug` must then be used for these generic cases. This is not a problem though because for any new *container* type which is -*not* generic,`fmt::Display` can be implemented. +*not* generic, `fmt::Display` can be implemented. ```rust,editable use std::fmt; // Import `fmt` @@ -66,7 +66,7 @@ struct Point2D { y: f64, } -// Similarly, implement `Display` for `Point2D` +// Similarly, implement `Display` for `Point2D`. impl fmt::Display for Point2D { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Customize so only `x` and `y` are denoted. @@ -100,10 +100,9 @@ fn main() { } ``` -So, `fmt::Display` has been implemented but `fmt::Binary` has not, and -therefore cannot be used. `std::fmt` has many such [`traits`][traits] and -each requires its own implementation. This is detailed further in -[`std::fmt`][fmt]. +So, `fmt::Display` has been implemented but `fmt::Binary` has not, and therefore +cannot be used. `std::fmt` has many such [`traits`][traits] and each requires +its own implementation. This is detailed further in [`std::fmt`][fmt]. ### Activity diff --git a/src/doc/rust-by-example/src/hello/print/print_display/testcase_list.md b/src/doc/rust-by-example/src/hello/print/print_display/testcase_list.md index 63e400b6a..d07316b72 100644 --- a/src/doc/rust-by-example/src/hello/print/print_display/testcase_list.md +++ b/src/doc/rust-by-example/src/hello/print/print_display/testcase_list.md @@ -52,7 +52,8 @@ fn main() { ### Activity -Try changing the program so that the index of each element in the vector is also printed. The new output should look like this: +Try changing the program so that the index of each element in the vector is also +printed. The new output should look like this: ```rust,ignore [0: 1, 1: 2, 2: 3] diff --git a/src/doc/rust-by-example/src/primitives.md b/src/doc/rust-by-example/src/primitives.md index 6b579e5ea..6560e99e9 100644 --- a/src/doc/rust-by-example/src/primitives.md +++ b/src/doc/rust-by-example/src/primitives.md @@ -2,28 +2,27 @@ Rust provides access to a wide variety of `primitives`. A sample includes: - ### Scalar Types -* signed integers: `i8`, `i16`, `i32`, `i64`, `i128` and `isize` (pointer size) -* unsigned integers: `u8`, `u16`, `u32`, `u64`, `u128` and `usize` (pointer +* Signed integers: `i8`, `i16`, `i32`, `i64`, `i128` and `isize` (pointer size) +* Unsigned integers: `u8`, `u16`, `u32`, `u64`, `u128` and `usize` (pointer size) -* floating point: `f32`, `f64` +* Floating point: `f32`, `f64` * `char` Unicode scalar values like `'a'`, `'α'` and `'∞'` (4 bytes each) * `bool` either `true` or `false` -* and the unit type `()`, whose only possible value is an empty tuple: `()` +* The unit type `()`, whose only possible value is an empty tuple: `()` -Despite the value of a unit type being a tuple, it is not considered a -compound type because it does not contain multiple values. +Despite the value of a unit type being a tuple, it is not considered a compound +type because it does not contain multiple values. ### Compound Types -* arrays like `[1, 2, 3]` -* tuples like `(1, true)` +* Arrays like `[1, 2, 3]` +* Tuples like `(1, true)` -Variables can always be *type annotated*. Numbers may additionally be -annotated via a *suffix* or *by default*. Integers default to `i32` and -floats to `f64`. Note that Rust can also infer types from context. +Variables can always be *type annotated*. Numbers may additionally be annotated +via a *suffix* or *by default*. Integers default to `i32` and floats to `f64`. +Note that Rust can also infer types from context. ```rust,editable,ignore,mdbook-runnable fn main() { @@ -36,18 +35,18 @@ fn main() { // Or a default will be used. let default_float = 3.0; // `f64` let default_integer = 7; // `i32` - - // A type can also be inferred from context - let mut inferred_type = 12; // Type i64 is inferred from another line + + // A type can also be inferred from context. + let mut inferred_type = 12; // Type i64 is inferred from another line. inferred_type = 4294967296i64; - + // A mutable variable's value can be changed. let mut mutable = 12; // Mutable `i32` mutable = 21; - + // Error! The type of a variable can't be changed. mutable = true; - + // Variables can be overwritten with shadowing. let mutable = true; } @@ -55,7 +54,8 @@ fn main() { ### See also: -[the `std` library][std], [`mut`][mut], [`inference`][inference], and [`shadowing`][shadowing] +[the `std` library][std], [`mut`][mut], [`inference`][inference], and +[`shadowing`][shadowing] [std]: https://doc.rust-lang.org/std/ [mut]: variable_bindings/mut.md diff --git a/src/doc/rust-by-example/src/primitives/array.md b/src/doc/rust-by-example/src/primitives/array.md index 0f56182cd..3811bb6d7 100644 --- a/src/doc/rust-by-example/src/primitives/array.md +++ b/src/doc/rust-by-example/src/primitives/array.md @@ -5,66 +5,65 @@ memory. Arrays are created using brackets `[]`, and their length, which is known at compile time, is part of their type signature `[T; length]`. Slices are similar to arrays, but their length is not known at compile time. -Instead, a slice is a two-word object, the first word is a pointer to the data, -and the second word is the length of the slice. The word size is the same as -usize, determined by the processor architecture e.g. 64 bits on an x86-64. -Slices can be used to borrow a section of an array, and have the type signature -`&[T]`. +Instead, a slice is a two-word object; the first word is a pointer to the data, +the second word the length of the slice. The word size is the same as usize, +determined by the processor architecture, e.g. 64 bits on an x86-64. Slices can +be used to borrow a section of an array and have the type signature `&[T]`. ```rust,editable,ignore,mdbook-runnable use std::mem; -// This function borrows a slice +// This function borrows a slice. fn analyze_slice(slice: &[i32]) { - println!("first element of the slice: {}", slice[0]); - println!("the slice has {} elements", slice.len()); + println!("First element of the slice: {}", slice[0]); + println!("The slice has {} elements", slice.len()); } fn main() { - // Fixed-size array (type signature is superfluous) + // Fixed-size array (type signature is superfluous). let xs: [i32; 5] = [1, 2, 3, 4, 5]; - // All elements can be initialized to the same value + // All elements can be initialized to the same value. let ys: [i32; 500] = [0; 500]; - // Indexing starts at 0 - println!("first element of the array: {}", xs[0]); - println!("second element of the array: {}", xs[1]); + // Indexing starts at 0. + println!("First element of the array: {}", xs[0]); + println!("Second element of the array: {}", xs[1]); - // `len` returns the count of elements in the array - println!("number of elements in array: {}", xs.len()); + // `len` returns the count of elements in the array. + println!("Number of elements in array: {}", xs.len()); - // Arrays are stack allocated - println!("array occupies {} bytes", mem::size_of_val(&xs)); + // Arrays are stack allocated. + println!("Array occupies {} bytes", mem::size_of_val(&xs)); - // Arrays can be automatically borrowed as slices - println!("borrow the whole array as a slice"); + // Arrays can be automatically borrowed as slices. + println!("Borrow the whole array as a slice."); analyze_slice(&xs); - // Slices can point to a section of an array - // They are of the form [starting_index..ending_index] - // starting_index is the first position in the slice - // ending_index is one more than the last position in the slice - println!("borrow a section of the array as a slice"); + // Slices can point to a section of an array. + // They are of the form [starting_index..ending_index]. + // `starting_index` is the first position in the slice. + // `ending_index` is one more than the last position in the slice. + println!("Borrow a section of the array as a slice."); analyze_slice(&ys[1 .. 4]); - // Example of empty slice `&[]` + // Example of empty slice `&[]`: let empty_array: [u32; 0] = []; assert_eq!(&empty_array, &[]); - assert_eq!(&empty_array, &[][..]); // same but more verbose + assert_eq!(&empty_array, &[][..]); // Same but more verbose // Arrays can be safely accessed using `.get`, which returns an // `Option`. This can be matched as shown below, or used with // `.expect()` if you would like the program to exit with a nice // message instead of happily continue. - for i in 0..xs.len() + 1 { // OOPS, one element too far + for i in 0..xs.len() + 1 { // Oops, one element too far! match xs.get(i) { Some(xval) => println!("{}: {}", i, xval), None => println!("Slow down! {} is too far!", i), } } - // Out of bound indexing causes runtime error + // Out of bound indexing causes runtime error. //println!("{}", xs[5]); } ``` diff --git a/src/doc/rust-by-example/src/primitives/literals.md b/src/doc/rust-by-example/src/primitives/literals.md index 4927e6af8..dfe4e3a88 100644 --- a/src/doc/rust-by-example/src/primitives/literals.md +++ b/src/doc/rust-by-example/src/primitives/literals.md @@ -9,12 +9,15 @@ notation using these prefixes respectively: `0x`, `0o` or `0b`. Underscores can be inserted in numeric literals to improve readability, e.g. `1_000` is the same as `1000`, and `0.000_001` is the same as `0.000001`. +Rust also supports scientific [E-notation][enote], e.g. `1e6`, `7.6e-4`. The +associated type is `f64`. + We need to tell the compiler the type of the literals we use. For now, we'll use the `u32` suffix to indicate that the literal is an unsigned 32-bit integer, and the `i32` suffix to indicate that it's a signed 32-bit integer. -The operators available and their precedence [in Rust][rust op-prec] are similar to other -[C-like languages][op-prec]. +The operators available and their precedence [in Rust][rust op-prec] are similar +to other [C-like languages][op-prec]. ```rust,editable fn main() { @@ -25,6 +28,9 @@ fn main() { println!("1 - 2 = {}", 1i32 - 2); // TODO ^ Try changing `1i32` to `1u32` to see why the type is important + // Scientific notation + println!("1e4 is {}, -2.5e-3 is {}", 1e4, -2.5e-3); + // Short-circuiting boolean logic println!("true AND false is {}", true && false); println!("true OR false is {}", true || false); @@ -42,5 +48,6 @@ fn main() { } ``` +[enote]: https://en.wikipedia.org/wiki/Scientific_notation#E_notation [rust op-prec]: https://doc.rust-lang.org/reference/expressions.html#expression-precedence [op-prec]: https://en.wikipedia.org/wiki/Operator_precedence#Programming_languages diff --git a/src/doc/rust-by-example/src/primitives/tuples.md b/src/doc/rust-by-example/src/primitives/tuples.md index f4b59c04b..e745d89be 100644 --- a/src/doc/rust-by-example/src/primitives/tuples.md +++ b/src/doc/rust-by-example/src/primitives/tuples.md @@ -6,9 +6,9 @@ using parentheses `()`, and each tuple itself is a value with type signature use tuples to return multiple values, as tuples can hold any number of values. ```rust,editable -// Tuples can be used as function arguments and as return values +// Tuples can be used as function arguments and as return values. fn reverse(pair: (i32, bool)) -> (bool, i32) { - // `let` can be used to bind the members of a tuple to variables + // `let` can be used to bind the members of a tuple to variables. let (int_param, bool_param) = pair; (bool_param, int_param) @@ -19,38 +19,38 @@ fn reverse(pair: (i32, bool)) -> (bool, i32) { struct Matrix(f32, f32, f32, f32); fn main() { - // A tuple with a bunch of different types + // A tuple with a bunch of different types. let long_tuple = (1u8, 2u16, 3u32, 4u64, -1i8, -2i16, -3i32, -4i64, 0.1f32, 0.2f64, 'a', true); - // Values can be extracted from the tuple using tuple indexing - println!("long tuple first value: {}", long_tuple.0); - println!("long tuple second value: {}", long_tuple.1); + // Values can be extracted from the tuple using tuple indexing. + println!("Long tuple first value: {}", long_tuple.0); + println!("Long tuple second value: {}", long_tuple.1); - // Tuples can be tuple members + // Tuples can be tuple members. let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16); - // Tuples are printable + // Tuples are printable. println!("tuple of tuples: {:?}", tuple_of_tuples); - - // But long Tuples (more than 12 elements) cannot be printed - // let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13); - // println!("too long tuple: {:?}", too_long_tuple); + + // But long Tuples (more than 12 elements) cannot be printed. + //let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13); + //println!("Too long tuple: {:?}", too_long_tuple); // TODO ^ Uncomment the above 2 lines to see the compiler error let pair = (1, true); - println!("pair is {:?}", pair); + println!("Pair is {:?}", pair); - println!("the reversed pair is {:?}", reverse(pair)); + println!("Uhe reversed pair is {:?}", reverse(pair)); // To create one element tuples, the comma is required to tell them apart - // from a literal surrounded by parentheses - println!("one element tuple: {:?}", (5u32,)); - println!("just an integer: {:?}", (5u32)); + // from a literal surrounded by parentheses. + println!("One element tuple: {:?}", (5u32,)); + println!("Just an integer: {:?}", (5u32)); - //tuples can be destructured to create bindings + // Tuples can be destructured to create bindings. let tuple = (1, "hello", 4.5, true); let (a, b, c, d) = tuple; @@ -58,40 +58,39 @@ fn main() { let matrix = Matrix(1.1, 1.2, 2.1, 2.2); println!("{:?}", matrix); - } ``` ### Activity - 1. *Recap*: Add the `fmt::Display` trait to the `Matrix` struct in the above example, - so that if you switch from printing the debug format `{:?}` to the display - format `{}`, you see the following output: - - ```text - ( 1.1 1.2 ) - ( 2.1 2.2 ) - ``` - - You may want to refer back to the example for [print display][print_display]. - 2. Add a `transpose` function using the `reverse` function as a template, which - accepts a matrix as an argument, and returns a matrix in which two elements - have been swapped. For example: - - ```rust,ignore - println!("Matrix:\n{}", matrix); - println!("Transpose:\n{}", transpose(matrix)); - ``` - - results in the output: - - ```text - Matrix: - ( 1.1 1.2 ) - ( 2.1 2.2 ) - Transpose: - ( 1.1 2.1 ) - ( 1.2 2.2 ) - ``` +1. *Recap*: Add the `fmt::Display` trait to the `Matrix` struct in the above + example, so that if you switch from printing the debug format `{:?}` to the + display format `{}`, you see the following output: + + ```text + ( 1.1 1.2 ) + ( 2.1 2.2 ) + ``` + + You may want to refer back to the example for [print display][print_display]. +2. Add a `transpose` function using the `reverse` function as a template, which + accepts a matrix as an argument, and returns a matrix in which two elements + have been swapped. For example: + + ```rust,ignore + println!("Matrix:\n{}", matrix); + println!("Transpose:\n{}", transpose(matrix)); + ``` + + Results in the output: + + ```text + Matrix: + ( 1.1 1.2 ) + ( 2.1 2.2 ) + Transpose: + ( 1.1 2.1 ) + ( 1.2 2.2 ) + ``` [print_display]: ../hello/print/print_display.md diff --git a/src/doc/rust-by-example/src/types/alias.md b/src/doc/rust-by-example/src/types/alias.md index 1d004587c..a2e02ac1a 100644 --- a/src/doc/rust-by-example/src/types/alias.md +++ b/src/doc/rust-by-example/src/types/alias.md @@ -24,8 +24,8 @@ fn main() { } ``` -The main use of aliases is to reduce boilerplate; for example the `IoResult<T>` type -is an alias for the `Result<T, IoError>` type. +The main use of aliases is to reduce boilerplate; for example the `io::Result<T>` type +is an alias for the `Result<T, io::Error>` type. ### See also: diff --git a/src/doc/rustc-dev-guide/.github/workflows/date-check.yml b/src/doc/rustc-dev-guide/.github/workflows/date-check.yml index c34c11c1e..bf2a7a819 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/date-check.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/date-check.yml @@ -27,9 +27,8 @@ jobs: cargo run -- ../../src/ > ../../date-check-output.txt - name: Open issue - uses: actions/github-script@v3 + uses: actions/github-script@v6 with: - github-token: ${{secrets.GITHUB_TOKEN}} script: | const fs = require('fs'); @@ -37,7 +36,7 @@ jobs: const title = rawText.split('\n')[0]; if (title != 'empty') { const body = rawText.split('\n').slice(1).join('\n'); - github.issues.create({ + github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, title, diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs index 4203fe96a..8d8b40cd7 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs @@ -3,7 +3,7 @@ // NOTE: For the example to compile, you will need to first run the following: // rustup component add rustc-dev llvm-tools-preview -// version: 1.62.0-nightly (7c4b47696 2022-04-30) +// version: rustc 1.68.0-nightly (935dc0721 2022-12-19) extern crate rustc_error_codes; extern crate rustc_errors; @@ -50,7 +50,6 @@ fn main() { output_dir: None, // Option<PathBuf> output_file: None, // Option<PathBuf> file_loader: None, // Option<Box<dyn FileLoader + Send + Sync>> - diagnostic_output: rustc_session::DiagnosticOutput::Default, lint_caps: FxHashMap::default(), // FxHashMap<lint::LintId, lint::Level> // This is a callback from the driver that is called when [`ParseSess`] is created. parse_sess_created: None, //Option<Box<dyn FnOnce(&mut ParseSess) + Send>> diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs index 1d3a4034e..49ee9ff44 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs @@ -3,7 +3,7 @@ // NOTE: For the example to compile, you will need to first run the following: // rustup component add rustc-dev llvm-tools-preview -// version: 1.62.0-nightly (7c4b47696 2022-04-30) +// version: rustc 1.68.0-nightly (935dc0721 2022-12-19) extern crate rustc_error_codes; extern crate rustc_errors; @@ -65,10 +65,6 @@ fn main() { " .into(), }, - // Redirect the diagnostic output of the compiler to a buffer. - diagnostic_output: rustc_session::DiagnosticOutput::Raw(Box::from(DiagnosticSink( - buffer.clone(), - ))), crate_cfg: rustc_hash::FxHashSet::default(), crate_check_cfg: CheckCfg::default(), input_path: None, diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs index 231994a97..07b09e9df 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs @@ -3,7 +3,7 @@ // NOTE: For the example to compile, you will need to first run the following: // rustup component add rustc-dev llvm-tools-preview -// version: 1.62.0-nightly (7c4b47696 2022-04-30) +// version: rustc 1.68.0-nightly (935dc0721 2022-12-19) extern crate rustc_ast_pretty; extern crate rustc_error_codes; @@ -43,7 +43,6 @@ fn main() { "# .to_string(), }, - diagnostic_output: rustc_session::DiagnosticOutput::Default, crate_cfg: rustc_hash::FxHashSet::default(), crate_check_cfg: CheckCfg::default(), input_path: None, diff --git a/src/doc/rustc-dev-guide/src/appendix/background.md b/src/doc/rustc-dev-guide/src/appendix/background.md index ae6136dd5..0b83b010f 100644 --- a/src/doc/rustc-dev-guide/src/appendix/background.md +++ b/src/doc/rustc-dev-guide/src/appendix/background.md @@ -328,5 +328,5 @@ does not. - [nLab](https://ncatlab.org/nlab/show/HomePage) ## Misc Papers and Blog Posts -- [Programming in Martin-Löf's Type Theory](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.118.6683&rep=rep1&type=pdf) +- [Programming in Martin-Löf's Type Theory](https://www.researchgate.net/publication/213877272_Programming_in_Martin-Lof's_Type_Theory) - [Polymorphism, Subtyping, and Type Inference in MLsub](https://dl.acm.org/doi/10.1145/3093333.3009882) diff --git a/src/doc/rustc-dev-guide/src/appendix/bibliography.md b/src/doc/rustc-dev-guide/src/appendix/bibliography.md index 27529314c..c2bb00e3b 100644 --- a/src/doc/rustc-dev-guide/src/appendix/bibliography.md +++ b/src/doc/rustc-dev-guide/src/appendix/bibliography.md @@ -23,7 +23,7 @@ Rust, as well as publications about Rust. * [Scheduling multithreaded computations by work stealing](http://supertech.csail.mit.edu/papers/steal.pdf) * [Thread scheduling for multiprogramming multiprocessors](https://www.eecis.udel.edu/%7Ecavazos/cisc879-spring2008/papers/arora98thread.pdf) * [The data locality of work stealing](http://www.aladdin.cs.cmu.edu/papers/pdfs/y2000/locality_spaa00.pdf) -* [Dynamic circular work stealing deque](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.170.1097&rep=rep1&type=pdf) - The Chase/Lev deque +* [Dynamic circular work stealing deque](https://patents.google.com/patent/US7346753B2/en) - The Chase/Lev deque * [Work-first and help-first scheduling policies for async-finish task parallelism](https://dl.acm.org/doi/10.1109/IPDPS.2009.5161079) - More general than fully-strict work stealing * [A Java fork/join calamity](https://web.archive.org/web/20190904045322/http://www.coopsoft.com/ar/CalamityArticle.html) - critique of Java's fork/join library, particularly its application of work stealing to non-strict computation * [Scheduling techniques for concurrent systems](https://www.stanford.edu/~ouster/cgi-bin/papers/coscheduling.pdf) @@ -81,7 +81,7 @@ Rust, as well as publications about Rust. * [Ownership is Theft: Experiences Building an Embedded OS in Rust - Amit Levy, et. al.](https://amitlevy.com/papers/tock-plos2015.pdf) * [You can't spell trust without Rust](https://raw.githubusercontent.com/Gankro/thesis/master/thesis.pdf). Alexis Beingessner's master's thesis. * [Rust-Bio: a fast and safe bioinformatics library](https://academic.oup.com/bioinformatics/article/32/3/444/1743419). Johannes Köster -* [Safe, Correct, and Fast Low-Level Networking](https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.704.1768). Robert Clipsham's master's thesis. +* [Safe, Correct, and Fast Low-Level Networking](https://octarineparrot.com/assets/msci_paper.pdf). Robert Clipsham's master's thesis. * [Formalizing Rust traits](https://open.library.ubc.ca/cIRcle/collections/ubctheses/24/items/1.0220521). Jonatan Milewski's master's thesis. * [Rust as a Language for High Performance GC Implementation](https://users.cecs.anu.edu.au/~steveb/downloads/pdf/rust-ismm-2016.pdf) * [Simple Verification of Rust Programs via Functional Purification](https://github.com/Kha/electrolysis). Sebastian Ullrich's master's thesis. diff --git a/src/doc/rustc-dev-guide/src/appendix/humorust.md b/src/doc/rustc-dev-guide/src/appendix/humorust.md index bc8255439..1b199d98a 100644 --- a/src/doc/rustc-dev-guide/src/appendix/humorust.md +++ b/src/doc/rustc-dev-guide/src/appendix/humorust.md @@ -3,7 +3,7 @@ What's a project without a sense of humor? And frankly some of these are enlightening? -- [Weird exprs test](https://github.com/rust-lang/rust/blob/master/src/test/ui/weird-exprs.rs) +- [Weird exprs test](https://github.com/rust-lang/rust/blob/master/tests/ui/weird-exprs.rs) - [Ferris Rap](http://fitzgeraldnick.com/2018/12/13/rust-raps.html) - [The Genesis of Generic Germination](https://github.com/rust-lang/rust/pull/53645#issue-210543221) - [The Bastion of the Turbofish test](https://github.com/rust-lang/rust/blob/79d8a0fcefa5134db2a94739b1d18daa01fc6e9f/src/test/ui/bastion-of-the-turbofish.rs) diff --git a/src/doc/rustc-dev-guide/src/asm.md b/src/doc/rustc-dev-guide/src/asm.md index 9b5a82f34..3b6b5e093 100644 --- a/src/doc/rustc-dev-guide/src/asm.md +++ b/src/doc/rustc-dev-guide/src/asm.md @@ -361,9 +361,9 @@ can't know ahead of time whether a function will require a frame/base pointer. Various tests for inline assembly are available: -- `src/test/assembly/asm` -- `src/test/ui/asm` -- `src/test/codegen/asm-*` +- `tests/assembly/asm` +- `tests/ui/asm` +- `tests/codegen/asm-*` Every architecture supported by inline assembly must have exhaustive tests in -`src/test/assembly/asm` which test all combinations of register classes and types. +`tests/assembly/asm` which test all combinations of register classes and types. diff --git a/src/doc/rustc-dev-guide/src/backend/monomorph.md b/src/doc/rustc-dev-guide/src/backend/monomorph.md index 21a788203..4a0b55f62 100644 --- a/src/doc/rustc-dev-guide/src/backend/monomorph.md +++ b/src/doc/rustc-dev-guide/src/backend/monomorph.md @@ -10,7 +10,7 @@ execute. Different languages handle this problem differently. For example, in some languages, such as Java, we may not know the most precise type of value until runtime. In the case of Java, this is ok because (almost) all variables are -reference values anyway (i.e. pointers to a stack allocated object). This +reference values anyway (i.e. pointers to a heap allocated object). This flexibility comes at the cost of performance, since all accesses to an object must dereference a pointer. diff --git a/src/doc/rustc-dev-guide/src/borrow_check.md b/src/doc/rustc-dev-guide/src/borrow_check.md index 8e2bb752a..f206da42a 100644 --- a/src/doc/rustc-dev-guide/src/borrow_check.md +++ b/src/doc/rustc-dev-guide/src/borrow_check.md @@ -27,7 +27,7 @@ HIR. Doing borrow checking on MIR has several advantages: ### Major phases of the borrow checker The borrow checker source is found in -[the `rustc_borrow_ck` crate][b_c]. The main entry point is +[the `rustc_borrowck` crate][b_c]. The main entry point is the [`mir_borrowck`] query. [b_c]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/index.html diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping.md b/src/doc/rustc-dev-guide/src/building/bootstrapping.md index 3bacc21d3..543c68c2e 100644 --- a/src/doc/rustc-dev-guide/src/building/bootstrapping.md +++ b/src/doc/rustc-dev-guide/src/building/bootstrapping.md @@ -28,7 +28,7 @@ stage0 compiler, and <span style="background-color: lightgreen; color: black">green</span> nodes are built with the stage1 compiler. -[rustconf22-talk]: https://rustconf.com/schedule#bootstrapping-the-once-and-future-compiler +[rustconf22-talk]: https://www.youtube.com/watch?v=oUIjG-y4zaA ```mermaid graph TD @@ -193,14 +193,14 @@ Build artifacts include, but are not limited to: without building `rustc` from source ('build with stage 0, then test the artifacts'). If you're working on the standard library, this is normally the test command you want. -- `./x.py test src/test/ui` means to build the stage 1 compiler and run +- `./x.py test tests/ui` means to build the stage 1 compiler and run `compiletest` on it. If you're working on the compiler, this is normally the test command you want. #### Examples of what *not* to do -- `./x.py test --stage 0 src/test/ui` is not useful: it runs tests on the - _beta_ compiler and doesn't build `rustc` from source. Use `test src/test/ui` +- `./x.py test --stage 0 tests/ui` is not useful: it runs tests on the + _beta_ compiler and doesn't build `rustc` from source. Use `test tests/ui` instead, which builds stage 1 from source. - `./x.py test --stage 0 compiler/rustc` builds the compiler but runs no tests: it's running `cargo test -p rustc`, but cargo doesn't understand Rust's @@ -386,7 +386,7 @@ recompiling all dependencies. `CARGOFLAGS` will pass arguments to cargo itself (e.g. `--timings`). `CARGOFLAGS_BOOTSTRAP` and `CARGOFLAGS_NOT_BOOTSTRAP` work analogously to `RUSTFLAGS_BOOTSTRAP`. -`--test-args` will pass arguments through to the test runner. For `src/test/ui`, this is +`--test-args` will pass arguments through to the test runner. For `tests/ui`, this is compiletest; for unit tests and doctests this is the `libtest` runner. Most test runner accept `--help`, which you can use to find out the options accepted by the runner. 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 46d4b9c04..24786c0c0 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 @@ -4,7 +4,7 @@ The compiler is built using a tool called `x.py`. You will need to have Python installed to run it. For instructions on how to install Python and other prerequisites, -see [the next page](./prerequisites.md). +see [the `rust-lang/rust` README][readme]. ## Get the source code @@ -13,6 +13,7 @@ the standard library (including `core`, `alloc`, `test`, `proc_macro`, etc), and a bunch of tools (e.g. `rustdoc`, the bootstrapping infrastructure, etc). [repo]: https://github.com/rust-lang/rust +[readme]: https://github.com/rust-lang/rust#building-on-a-unix-like-system The very first step to work on `rustc` is to clone the repository: @@ -21,67 +22,15 @@ git clone https://github.com/rust-lang/rust.git cd rust ``` -There are also submodules for things like LLVM, `clippy`, `miri`, etc. The -build tool will automatically clone and sync these for you. But if you want to, -you can do the following: - -```sh -# first time -git submodule update --init --recursive - -# subsequent times (to pull new commits) -git submodule update -``` - -## Create a `config.toml` - -To start, run `./x.py setup`. This will do some initialization and create a -`config.toml` for you with reasonable defaults. These defaults are specified -indirectly via the `profile` setting, which points to one of the TOML files in -`src/bootstrap/defaults.` - -Alternatively, you can write `config.toml` by hand. See `config.toml.example` -for all the available settings and explanations of them. The following settings -are of particular interest, and `config.toml.example` has full explanations. - -You may want to change some of the following settings (and possibly others, such as -`llvm.ccache`): - -```toml -[llvm] -# Whether to use Rust CI built LLVM instead of locally building it. -download-ci-llvm = true # Download a pre-built LLVM? -assertions = true # LLVM assertions on? -ccache = "/path/to/ccache" # Use ccache when building LLVM? - -[rust] -debug-logging = true # Leave debug! and trace! calls in rustc? -incremental = true # Build rustc with incremental compilation? -``` - -If you set `download-ci-llvm = true`, in some circumstances, such as when -updating the version of LLVM used by `rustc`, you may want to temporarily -disable this feature. See the ["Updating LLVM" section] for more. - -["Updating LLVM" section]: ../backend/updating-llvm.md#feature-updates - -If you have already built `rustc` and you change settings related to LLVM, then you may have to -execute `rm -rf build` for subsequent configuration changes to take effect. Note that `./x.py -clean` will not cause a rebuild of LLVM. - ## What is `x.py`? -`x.py` is the script used to orchestrate the tooling in the `rustc` repository. -It is the script that can build docs, run tests, and compile `rustc`. -It is the now preferred way to build `rustc` and it replaces the old makefiles -from before. Below are the different ways to utilize `x.py` in order to -effectively deal with the repo for various common tasks. +`x.py` is the build tool for the `rust` repository. It can build docs, run tests, and compile the +compiler and standard library. This chapter focuses on the basics to be productive, but -if you want to learn more about `x.py`, read its README.md -[here](https://github.com/rust-lang/rust/blob/master/src/bootstrap/README.md). -To read more about the bootstrap process and why `x.py` is necessary, -[read this chapter][bootstrap]. +if you want to learn more about `x.py`, [read this chapter][bootstrap]. + +[bootstrap]: ./bootstrapping.md ### Running `x.py` slightly more conveniently @@ -91,48 +40,26 @@ of a checkout. It also looks up the appropriate version of `python` to use. You can install it with `cargo install --path src/tools/x`. -[bootstrap]: ./bootstrapping.md - -## Building the Compiler +## Create a `config.toml` -To build a compiler, run `./x.py build`. This will build up to the stage1 compiler, -including `rustdoc`, producing a usable compiler toolchain from the source -code you have checked out. +To start, run `./x.py setup`. This will do some initialization and create a +`config.toml` for you with reasonable defaults. -Note that building will require a relatively large amount of storage space. -You may want to have upwards of 10 or 15 gigabytes available to build the compiler. +Alternatively, you can write `config.toml` by hand. See `config.toml.example` for all the available +settings and explanations of them. See `src/bootstrap/defaults` for common settings to change. -There are many flags you can pass to the build command of `x.py` that can be -beneficial to cutting down compile times or fitting other things you might -need to change. They are: - -```txt -Options: - -v, --verbose use verbose output (-vv for very verbose) - -i, --incremental use incremental compilation - --config FILE TOML configuration file for build - --build BUILD build target of the stage0 compiler - --host HOST host targets to build - --target TARGET target targets to build - --on-fail CMD command to run on failure - --stage N stage to build - --keep-stage N stage to keep without recompiling - --src DIR path to the root of the Rust checkout - -j, --jobs JOBS number of jobs to run in parallel - -h, --help print this help message -``` +If you have already built `rustc` and you change settings related to LLVM, then you may have to +execute `rm -rf build` for subsequent configuration changes to take effect. Note that `./x.py +clean` will not cause a rebuild of LLVM. -For hacking, often building the stage 1 compiler is enough, which saves a lot -of time. But for final testing and release, the stage 2 compiler is used. +## Building the Compiler -`./x.py check` is really fast to build the Rust compiler. -It is, in particular, very useful when you're doing some kind of -"type-based refactoring", like renaming a method, or changing the -signature of some function. +Note that building will require a relatively large amount of storage space. +You may want to have upwards of 10 or 15 gigabytes available to build the compiler. Once you've created a `config.toml`, you are now ready to run `x.py`. There are a lot of options here, but let's start with what is -probably the best "go to" command for building a local rust: +probably the best "go to" command for building a local compiler: ```bash ./x.py build library @@ -156,6 +83,10 @@ see [the section on avoiding rebuilds for std][keep-stage]. [keep-stage]: ./suggested.md#faster-builds-with---keep-stage +Sometimes you don't need a full build. When doing some kind of +"type-based refactoring", like renaming a method, or changing the +signature of some function, you can use `./x.py check` instead for a much faster build. + 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 --stage 2 compiler/rustc`) has quite a few more steps: @@ -177,6 +108,9 @@ Instead, you can just build using the bootstrap compiler. ./x.py build --stage 0 library ``` +If you choose the `library` profile when running `x.py setup`, you can omit `--stage 0` (it's the +default). + ## Creating a rustup toolchain Once you have successfully built `rustc`, you will have created a bunch @@ -285,14 +219,14 @@ in other sections: - `./x.py build` – builds everything using the stage 1 compiler, not just up to `std` - `./x.py build --stage 2` – builds everything with the stage 2 compiler including - `rustdoc` (which doesn't take too long) + `rustdoc` - Running tests (see the [section on running tests](../tests/running.html) for more details): - `./x.py test library/std` – runs the unit tests and integration tests from `std` - - `./x.py test src/test/ui` – runs the `ui` test suite - - `./x.py test src/test/ui/const-generics` - runs all the tests in + - `./x.py test tests/ui` – runs the `ui` test suite + - `./x.py test tests/ui/const-generics` - runs all the tests in the `const-generics/` subdirectory of the `ui` test suite - - `./x.py test src/test/ui/const-generics/const-types.rs` - runs + - `./x.py test tests/ui/const-generics/const-types.rs` - runs the single test `const-types.rs` from the `ui` test suite ### Cleaning out build directories diff --git a/src/doc/rustc-dev-guide/src/building/prerequisites.md b/src/doc/rustc-dev-guide/src/building/prerequisites.md index 100b14aca..8fee0a4b5 100644 --- a/src/doc/rustc-dev-guide/src/building/prerequisites.md +++ b/src/doc/rustc-dev-guide/src/building/prerequisites.md @@ -2,48 +2,7 @@ ## Dependencies -Before building the compiler, you need the following things installed: - -* `python` 3 or 2.7 (under the name `python`; `python2` or `python3` will not work) -* `curl` -* `git` -* `ssl` which comes in `libssl-dev` or `openssl-devel` -* `pkg-config` if you are compiling on Linux and targeting Linux -* `libstdc++-static` may be required on some Linux distributions such as Fedora and Ubuntu - -If building LLVM from source (the default), you'll need additional tools: - -* `g++`, `clang++`, or MSVC with versions listed on <!-- date-check: Aug 2022 --> - [LLVM's documentation](https://releases.llvm.org/13.0.0/docs/GettingStarted.html#host-c-toolchain-both-compiler-and-standard-library) -* `ninja`, or GNU `make` 3.81 or later (ninja is recommended, especially on Windows) -* `cmake` 3.13.4 or later - -Otherwise, you'll need LLVM installed and `llvm-config` in your path. -See [this section for more info][sysllvm]. - -[sysllvm]: ./new-target.md#using-pre-built-llvm - -### Windows - -* Install [winget](https://github.com/microsoft/winget-cli) - -`winget` is a Windows package manager. It will make package installation easy -on Windows. - -Run the following in a terminal: - -```powershell -winget install -e Python.Python.3 -winget install -e Kitware.CMake -``` - -If any of those is installed already, winget will detect it. Then edit your system's `PATH` variable -and add: `C:\Program Files\CMake\bin`. See -[this guide on editing the system `PATH`](https://www.java.com/en/download/help/path.html) from the -Java documentation. - -For more information about building on Windows, -see [the `rust-lang/rust` README](https://github.com/rust-lang/rust#building-on-windows). +See [the `rust-lang/rust` README](https://github.com/rust-lang/rust#dependencies). ## Hardware @@ -65,8 +24,8 @@ powerful, a common strategy is to only use `./x.py check` on your local machine and let the CI build test your changes when you push to a PR branch. Building the compiler takes more than half an hour on my moderately powerful -laptop. The first time you build the compiler, LLVM will also be built unless -you use CI-built LLVM ([see here][config]). +laptop. We suggest downloading LLVM from CI so you don't have to build it from source +([see here][config]). Like `cargo`, the build system will use as many cores as possible. Sometimes this can cause you to run low on memory. You can use `-j` to adjust the number @@ -80,10 +39,3 @@ longer (especially after a rebase), but will save a ton of space from the incremental caches. [config]: ./how-to-build-and-run.md#create-a-configtoml - -## `rustc` and toolchain installation - -Follow the installation given in the [Rust book][install] to install a working -`rustc` and the necessary C/++ toolchain on your platform. - -[install]: https://doc.rust-lang.org/book/ch01-01-installation.html diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index a85229c6a..f81daa5bc 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -34,10 +34,10 @@ you can write: <!-- date-check: nov 2022 --><!-- the date comment is for the edi "--json-output" ], "rust-analyzer.rustfmt.overrideCommand": [ - "./build/$TARGET_TRIPLE/stage0/bin/rustfmt", + "./build/host/stage0/bin/rustfmt", "--edition=2021" ], - "rust-analyzer.procMacro.server": "./build/$TARGET_TRIPLE/stage0/libexec/rust-analyzer-proc-macro-srv", + "rust-analyzer.procMacro.server": "./build/host/stage0/libexec/rust-analyzer-proc-macro-srv", "rust-analyzer.procMacro.enable": true, "rust-analyzer.cargo.buildScripts.enable": true, "rust-analyzer.cargo.buildScripts.invocationLocation": "root", @@ -48,7 +48,7 @@ you can write: <!-- date-check: nov 2022 --><!-- the date comment is for the edi "check", "--json-output" ], - "rust-analyzer.cargo.sysroot": "./build/$TARGET_TRIPLE/stage0-sysroot", + "rust-analyzer.cargo.sysroot": "./build/host/stage0-sysroot", "rust-analyzer.rustc.source": "./Cargo.toml", } ``` @@ -56,11 +56,6 @@ you can write: <!-- date-check: nov 2022 --><!-- the date comment is for the edi in your `.vscode/settings.json` file. This will ask `rust-analyzer` to use `./x.py check` to check the sources, and the stage 0 rustfmt to format them. -> NOTE: Make sure to replace `TARGET_TRIPLE` in the `rust-analyzer.rustfmt.overrideCommand` -> setting with the appropriate target triple for your machine. An example of such -> a triple is `x86_64-unknown-linux-gnu`. An easy way to check your target triple -> is to run `rustc -vV` and checking the `host` value of its output. - If you have enough free disk space and you would like to be able to run `x.py` commands while rust-analyzer runs in the background, you can also add `--build-dir build-rust-analyzer` to the `overrideCommand` to avoid x.py locking. @@ -177,8 +172,8 @@ rebuild. That ought to fix the problem. You can also use `--keep-stage 1` when running tests. Something like this: -- Initial test run: `./x.py test src/test/ui` -- Subsequent test run: `./x.py test src/test/ui --keep-stage 1` +- Initial test run: `./x.py test tests/ui` +- Subsequent test run: `./x.py test tests/ui --keep-stage 1` ## Fine-tuning optimizations diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md index 35458b55c..eac9aeb6d 100644 --- a/src/doc/rustc-dev-guide/src/compiler-debugging.md +++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md @@ -128,7 +128,7 @@ fn main() { } ``` -```bash +``` $ rustc +stage1 error.rs error[E0277]: cannot add `()` to `{integer}` --> error.rs:2:7 @@ -143,7 +143,7 @@ error: aborting due to previous error Now, where does the error above come from? -```bash +``` $ RUST_BACKTRACE=1 rustc +stage1 error.rs -Z treat-err-as-bug error[E0277]: the trait bound `{integer}: std::ops::Add<()>` is not satisfied --> error.rs:2:7 @@ -185,6 +185,40 @@ stack backtrace: Cool, now I have a backtrace for the error! +## Getting the the error creation location + +`-Z track-diagnostics` can help figure out where errors are emitted. It uses `#[track_caller]` +for this and prints its location alongside the error: + +``` +$ RUST_BACKTRACE=1 rustc +stage1 error.rs -Z track-diagnostics +error[E0277]: cannot add `()` to `{integer}` + --> src\error.rs:2:7 + | +2 | 1 + (); + | ^ no implementation for `{integer} + ()` +-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs:638:39 + | + = help: the trait `Add<()>` is not implemented for `{integer}` + = help: the following other types implement trait `Add<Rhs>`: + <&'a f32 as Add<f32>> + <&'a f64 as Add<f64>> + <&'a i128 as Add<i128>> + <&'a i16 as Add<i16>> + <&'a i32 as Add<i32>> + <&'a i64 as Add<i64>> + <&'a i8 as Add<i8>> + <&'a isize as Add<isize>> + and 48 others + +For more information about this error, try `rustc --explain E0277`. +``` + +This is similar but different to `-Z treat-err-as-bug`: +- it will print the locations for all errors emitted +- it does not require a compiler built with debug symbols +- you don't have to read through a big stack trace. + ## Getting logging output The compiler uses the [`tracing`] crate for logging. diff --git a/src/doc/rustc-dev-guide/src/compiler-src.md b/src/doc/rustc-dev-guide/src/compiler-src.md index ad6968bb4..1f55a9d09 100644 --- a/src/doc/rustc-dev-guide/src/compiler-src.md +++ b/src/doc/rustc-dev-guide/src/compiler-src.md @@ -147,14 +147,14 @@ You can read more about rustdoc in [this chapter][rustdocch]. ## Tests -The test suite for all of the above is in [`src/test/`]. You can read more +The test suite for all of the above is in [`tests/`]. You can read more about the test suite [in this chapter][testsch]. The test harness itself is in [`src/tools/compiletest`]. [testsch]: ./tests/intro.md -[`src/test/`]: https://github.com/rust-lang/rust/tree/master/src/test +[`tests/`]: https://github.com/rust-lang/rust/tree/master/tests [`src/tools/compiletest`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest ## Build System diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 41ad1c915..bc39508a4 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -185,7 +185,7 @@ As a developer to this repository, you don't have to treat the following externa differently from other crates that are directly in this repo: * [Clippy](https://github.com/rust-lang/rust-clippy) -* [Miri](https://github.com/rust-lang/miri) +* [Miri] * [rustfmt](https://github.com/rust-lang/rustfmt) * [rust-analyzer](https://github.com/rust-lang/rust-analyzer) @@ -348,7 +348,7 @@ the entire stage 2 compiler and compile the various books published on [doc.rust-lang.org][docs]. When updating documentation for the standard library, first try `./x.py doc library`. If that fails, or if you need to see the output from the latest version of `rustdoc`, add `--stage 1`. -Results should appear in `build/$TARGET/doc`. +Results should appear in `build/host/doc`. [docs]: https://doc.rust-lang.org @@ -549,3 +549,4 @@ are: [ro]: https://www.rustaceans.org/ [rctd]: tests/intro.md [cheatsheet]: https://bors.rust-lang.org/ +[Miri]: https://github.com/rust-lang/miri diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index e1d5fbe1a..b50b7bd18 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/src/diagnostics.md @@ -269,7 +269,7 @@ book][rustc-lint-levels] and the [reference][reference-diagnostics]. ### Finding the source of errors -There are two main ways to find where a given error is emitted: +There are three main ways to find where a given error is emitted: - `grep` for either a sub-part of the error message/label or error code. This usually works well and is straightforward, but there are some cases where @@ -287,6 +287,8 @@ There are two main ways to find where a given error is emitted: - The _construction_ of the error is far away from where it is _emitted_, a problem similar to the one we faced with the `grep` approach. In some cases, we buffer multiple errors in order to emit them in order. +- Invoking `rustc` with `-Z track-diagnostics` will print error creation + locations alongside the error. The regular development practices apply: judicious use of `debug!()` statements and use of a debugger to trigger break points in order to figure out in what diff --git a/src/doc/rustc-dev-guide/src/git.md b/src/doc/rustc-dev-guide/src/git.md index 65397e349..cac3d6534 100644 --- a/src/doc/rustc-dev-guide/src/git.md +++ b/src/doc/rustc-dev-guide/src/git.md @@ -16,6 +16,10 @@ started sections of [this tutorial from Atlassian][atlassian-git]. GitHub also provides [documentation] and [guides] for beginners, or you can consult the more in depth [book from Git]. +This guide is incomplete. If you run into trouble with git that this page doesn't help with, +please [open an issue] so we can document how to fix it. + +[open an issue]: https://github.com/rust-lang/rustc-dev-guide/issues/new [book from Git]: https://git-scm.com/book/en/v2/ [atlassian-git]: https://www.atlassian.com/git/tutorials/what-is-version-control [documentation]: https://docs.github.com/en/get-started/quickstart/set-up-git @@ -58,7 +62,7 @@ and PRs: 1. Ensure that you're making your changes on top of master: `git checkout master`. 2. Get the latest changes from the Rust repo: `git pull upstream master --ff-only`. - (see [No-Merge Policy](#keeping-things-up-to-date) for more info about this). + (see [No-Merge Policy][no-merge-policy] for more info about this). 3. Make a new branch for your change: `git checkout -b issue-12345-fix`. 4. Make some changes to the repo and test them. 5. Stage your changes via `git add src/changed/file.rs src/another/change.rs` @@ -76,7 +80,7 @@ pulling-and-rebasing, you can use `git push --force-with-lease`). If you end up needing to rebase and are hitting conflicts, see [Rebasing](#rebasing). If you want to track upstream while working on long-running feature/issue, see -[Keeping things up to date](#keeping-things-up-to-date). +[Keeping things up to date][no-merge-policy]. If your reviewer requests changes, the procedure for those changes looks much the same, with some steps skipped: @@ -86,6 +90,8 @@ the same, with some steps skipped: 2. Make, stage, and commit your additional changes just like before. 3. Push those changes to your fork: `git push`. + [no-merge-policy]: #keeping-things-up-to-date + ## Troubleshooting git issues You don't need to clone `rust-lang/rust` from scratch if it's out of date! @@ -93,6 +99,14 @@ Even if you think you've messed it up beyond repair, there are ways to fix the git state that don't require downloading the whole repository again. Here are some common issues you might run into: +### I made a merge commit by accident. + +Git has two ways to update your branch with the newest changes: merging and rebasing. +Rust [uses rebasing][no-merge-policy]. If you make a merge commit, it's not too hard to fix: +`git rebase -i upstream/master`. + +See [Rebasing](#rebasing) for more about rebasing. + ### I deleted my fork on GitHub! This is not a problem from git's perspective. If you run `git remote -v`, @@ -100,20 +114,72 @@ it will say something like this: ``` $ git remote -v -origin https://github.com//rust-lang/rust (fetch) -origin https://github.com//rust-lang/rust (push) -personal https://github.com/jyn514/rust (fetch) -personal https://github.com/jyn514/rust (push) +origin git@github.com:jyn514/rust.git (fetch) +origin git@github.com:jyn514/rust.git (push) +upstream https://github.com/rust-lang/rust (fetch) +upstream https://github.com/rust-lang/rust (fetch) ``` If you renamed your fork, you can change the URL like this: ```console -git remote set-url personal <URL> +git remote set-url origin <URL> ``` where the `<URL>` is your new fork. +### I changed a submodule by accident + +Usually people notice this when rustbot posts a comment on github that `cargo` has been modified: + +![rustbot submodule comment](./img/rustbot-submodules.png) + +You might also notice conflicts in the web UI: + +![conflict in src/tools/cargo](./img/submodule-conflicts.png) + +The most common cause is that you rebased after a change and ran `git add .` without first running +`x.py` to update the submodules. Alternatively, you might have run `cargo fmt` instead of `x fmt` +and modified files in a submodule, then committed the changes. + +To fix it, do the following things: + +1. See which commit has the accidental changes: `git log --stat -n1 src/tools/cargo` +2. Revert the changes to that commit: `git checkout <my-commit>~ src/tools/cargo`. Type `~` + literally but replace `<my-commit>` with the output from step 1. +3. Tell git to commit the changes: `git commit --fixup <my-commit>` +4. Repeat steps 1-3 for all the submodules you modified. + - If you modified the submodule in several different commits, you will need to repeat steps 1-3 + for each commit you modified. You'll know when to stop when the `git log` command shows a commit + that's not authored by you. +5. Squash your changes into the existing commits: `git rebase --autosquash -i upstream/master` +6. [Push your changes](#standard-process). + +### I see "error: cannot rebase" when I try to rebase + +These are two common errors to see when rebasing: +``` +error: cannot rebase: Your index contains uncommitted changes. +error: Please commit or stash them. +``` +``` +error: cannot rebase: You have unstaged changes. +error: Please commit or stash them. +``` + +(See https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F#_the_three_states for the difference between the two.) + +This means you have made changes since the last time you made a commit. To be able to rebase, either +commit your changes, or make a temporary commit called a "stash" to have them still not be commited +when you finish rebasing. You may want to configure git to make this "stash" automatically, which +will prevent the "cannot rebase" error in nearly all cases: + +``` +git config --global rebase.autostash true +``` + +See https://git-scm.com/book/en/v2/Git-Tools-Stashing-and-Cleaning for more info about stashing. + ### I see 'Untracked Files: src/stdarch'? This is left over from the move to the `library/` directory. @@ -135,6 +201,24 @@ and just want to get a clean copy of the repository back, you can use `git reset git reset --hard master ``` +### Git is trying to rebase commits I didn't write? + +If you see many commits in your rebase list, or merge commits, or commits by other people that you +didn't write, it likely means you're trying to rebase over the wrong branch. For example, you may +have a `rust-lang/rust` remote `upstream`, but ran `git rebase origin/master` instead of `git rebase +upstream/master`. The fix is to abort the rebase and use the correct branch instead: + +``` +git rebase --abort +git rebase -i upstream/master +``` + +<details><summary>Click here to see an example of rebasing over the wrong branch</summary> + +![Interactive rebase over the wrong branch](img/other-peoples-commits.png) + +</details> + ### Quick note about submodules When updating your local repository with `git pull`, you may notice that sometimes @@ -269,9 +353,8 @@ and rebase them: ``` git checkout master git pull upstream master --ff-only # to make certain there are no merge commits -git checkout feature_branch -git rebase master -git push --force-with-lease (set origin to be the same as local) +git rebase master feature_branch +git push --force-with-lease # (set origin to be the same as local) ``` To avoid merges as per the [No-Merge Policy](#no-merge-policy), you may want to use @@ -279,7 +362,7 @@ To avoid merges as per the [No-Merge Policy](#no-merge-policy), you may want to to ensure that Git doesn't create merge commits when `git pull`ing, without needing to pass `--ff-only` or `--rebase` every time. -You can also `git push --force-with-lease` from master to keep your origin's master in sync with +You can also `git push --force-with-lease` from master to keep your fork's master in sync with upstream. ## Advanced Rebasing @@ -385,6 +468,44 @@ tradeoff. The main advantage is the generally linear commit history. This greatly simplifies bisecting and makes the history and commit log much easier to follow and understand. +## Tips for reviewing + +**NOTE**: This section is for *reviewing* PRs, not authoring them. + +### Hiding whitespace + +Github has a button for disabling whitespace changes that may be useful. +You can also use `git diff -w origin/master` to view changes locally. + +![hide whitespace](./img/github-whitespace-changes.png) + +### Fetching PRs + +To checkout PRs locally, you can use `git fetch upstream pull/NNNNN/head && git checkout +FETCH_HEAD`. + +You can also use github's cli tool. Github shows a button on PRs where you can copy-paste the +command to check it out locally. See <https://cli.github.com/> for more info. + +![`gh` suggestion](./img/github-cli.png) + +### Moving large sections of code + +Git and Github's default diff view for large moves *within* a file is quite poor; it will show each +line as deleted and each line as added, forcing you to compare each line yourself. Git has an option +to show moved lines in a different color: + +``` +git log -p --color-moved=dimmed-zebra --color-moved-ws=allow-indentation-change +``` + +See [the docs for `--color-moved`](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---color-movedltmodegt) for more info. + +### range-diff + +See [the relevant section for PR authors](#git-range-diff). This can be useful for comparing code +that was force-pushed to make sure there are no unexpected changes. + ## Git submodules **NOTE**: submodules are a nice thing to know about, but it *isn't* an absolute diff --git a/src/doc/rustc-dev-guide/src/img/github-cli.png b/src/doc/rustc-dev-guide/src/img/github-cli.png Binary files differnew file mode 100644 index 000000000..c3b0e7707 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/img/github-cli.png diff --git a/src/doc/rustc-dev-guide/src/img/github-whitespace-changes.png b/src/doc/rustc-dev-guide/src/img/github-whitespace-changes.png Binary files differnew file mode 100644 index 000000000..9a19a10aa --- /dev/null +++ b/src/doc/rustc-dev-guide/src/img/github-whitespace-changes.png diff --git a/src/doc/rustc-dev-guide/src/img/other-peoples-commits.png b/src/doc/rustc-dev-guide/src/img/other-peoples-commits.png Binary files differnew file mode 100644 index 000000000..e4fc2c797 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/img/other-peoples-commits.png diff --git a/src/doc/rustc-dev-guide/src/img/rustbot-submodules.png b/src/doc/rustc-dev-guide/src/img/rustbot-submodules.png Binary files differnew file mode 100644 index 000000000..c2e6937cb --- /dev/null +++ b/src/doc/rustc-dev-guide/src/img/rustbot-submodules.png diff --git a/src/doc/rustc-dev-guide/src/img/submodule-conflicts.png b/src/doc/rustc-dev-guide/src/img/submodule-conflicts.png Binary files differnew file mode 100644 index 000000000..e90a6bbe8 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/img/submodule-conflicts.png diff --git a/src/doc/rustc-dev-guide/src/incrcomp-debugging.md b/src/doc/rustc-dev-guide/src/incrcomp-debugging.md index ba312c959..3606943dd 100644 --- a/src/doc/rustc-dev-guide/src/incrcomp-debugging.md +++ b/src/doc/rustc-dev-guide/src/incrcomp-debugging.md @@ -6,7 +6,7 @@ There are various ways to write tests against the dependency graph. The simplest mechanisms are the `#[rustc_if_this_changed]` and `#[rustc_then_this_would_need]` annotations. These are used in ui tests to test whether the expected set of paths exist in the dependency graph. -As an example, see `src/test/ui/dep-graph/dep-graph-caller-callee.rs`. +As an example, see `tests/ui/dep-graph/dep-graph-caller-callee.rs`. The idea is that you can annotate a test like: diff --git a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md index b186f4820..b29b32a62 100644 --- a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md +++ b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md @@ -297,15 +297,15 @@ Expected results for both the `mir-opt` tests and the `coverage*` tests under ```shell $ ./x.py test mir-opt --bless -$ ./x.py test src/test/run-make-fulldeps/coverage --bless +$ ./x.py test tests/run-make-fulldeps/coverage --bless ``` -[mir-opt-test]: https://github.com/rust-lang/rust/blob/master/src/test/mir-opt/instrument_coverage.rs -[coverage-test-samples]: https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/coverage -[`coverage-reports`]: https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/coverage-reports -[`coverage-spanview`]: https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/coverage-spanview +[mir-opt-test]: https://github.com/rust-lang/rust/blob/master/tests/mir-opt/instrument_coverage.rs +[coverage-test-samples]: https://github.com/rust-lang/rust/tree/master/tests/run-make-fulldeps/coverage +[`coverage-reports`]: https://github.com/rust-lang/rust/tree/master/tests/run-make-fulldeps/coverage-reports +[`coverage-spanview`]: https://github.com/rust-lang/rust/tree/master/tests/run-make-fulldeps/coverage-spanview [spanview-debugging]: compiler-debugging.md#viewing-spanview-output -[`coverage-llvmir`]: https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/coverage-llvmir +[`coverage-llvmir`]: https://github.com/rust-lang/rust/tree/master/tests/run-make-fulldeps/coverage-llvmir ## Implementation Details of the `InstrumentCoverage` MIR Pass diff --git a/src/doc/rustc-dev-guide/src/memory.md b/src/doc/rustc-dev-guide/src/memory.md index cde2f454c..e5122deb2 100644 --- a/src/doc/rustc-dev-guide/src/memory.md +++ b/src/doc/rustc-dev-guide/src/memory.md @@ -16,18 +16,19 @@ types for equality: for each interned type `X`, we implemented [`PartialEq for X`][peqimpl], so we can just compare pointers. The [`CtxtInterners`] type contains a bunch of maps of interned types and the arena itself. -[peqimpl]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#implementations +[peqimpl]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#implementations [`CtxtInterners`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.CtxtInterners.html#structfield.arena -### Example: `ty::TyS` +### Example: `ty::TyKind` -Taking the example of [`ty::TyS`] which represents a type in the compiler (you +Taking the example of [`ty::TyKind`] which represents a type in the compiler (you can read more [here](./ty.md)). Each time we want to construct a type, the compiler doesn’t naively allocate from the buffer. Instead, we check if that type was already constructed. If it was, we just get the same pointer we had before, otherwise we make a fresh pointer. With this schema if we want to know if two types are the same, all we need to do is compare the pointers which is -efficient. `TyS` is carefully setup so you never construct them on the stack. +efficient. `TyKind` should never be constructed on the stack, and it would be unusable +if done so. You always allocate them from this arena and you always intern them so they are unique. @@ -52,7 +53,7 @@ allocate, and which are found in this module. Here are a few examples: [`TraitRef`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TraitRef.html [`Predicate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Predicate.html -[`ty::TyS`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html +[`ty::TyKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/sty/type.TyKind.html ## The tcx and how it uses lifetimes diff --git a/src/doc/rustc-dev-guide/src/mir/optimizations.md b/src/doc/rustc-dev-guide/src/mir/optimizations.md index cef785ea9..037cf5874 100644 --- a/src/doc/rustc-dev-guide/src/mir/optimizations.md +++ b/src/doc/rustc-dev-guide/src/mir/optimizations.md @@ -28,13 +28,13 @@ optimizes it, and returns the improved MIR. ## Quickstart for adding a new optimization -1. Make a Rust source file in `src/test/mir-opt` that shows the code you want to +1. Make a Rust source file in `tests/mir-opt` that shows the code you want to optimize. This should be kept simple, so avoid `println!` or other formatting code if it's not necessary for the optimization. The reason for this is that `println!`, `format!`, etc. generate a lot of MIR that can make it harder to understand what the optimization does to the test. -2. Run `./x.py test --bless src/test/mir-opt/<your-test>.rs` to generate a MIR +2. Run `./x.py test --bless tests/mir-opt/<your-test>.rs` to generate a MIR dump. Read [this README][mir-opt-test-readme] for instructions on how to dump things. @@ -51,10 +51,10 @@ optimizes it, and returns the improved MIR. [`run_optimization_passes()`] function, 3. and then start modifying the copied optimization. -5. Rerun `./x.py test --bless src/test/mir-opt/<your-test>.rs` to regenerate the +5. Rerun `./x.py test --bless tests/mir-opt/<your-test>.rs` to regenerate the MIR dumps. Look at the diffs to see if they are what you expect. -6. Run `./x.py test src/test/ui` to see if your optimization broke anything. +6. Run `./x.py test tests/ui` to see if your optimization broke anything. 7. If there are issues with your optimization, experiment with it a bit and repeat steps 5 and 6. @@ -70,7 +70,7 @@ optimizes it, and returns the improved MIR. If you have any questions along the way, feel free to ask in `#t-compiler/wg-mir-opt` on Zulip. -[mir-opt-test-readme]: https://github.com/rust-lang/rust/blob/master/src/test/mir-opt/README.md +[mir-opt-test-readme]: https://github.com/rust-lang/rust/blob/master/tests/mir-opt/README.md [`compiler/rustc_mir_transform/src`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_mir_transform/src <!--- TODO: Change NoLandingPads. [#1232](https://github.com/rust-lang/rustc-dev-guide/issues/1232) --> [`no_landing_pads`]: https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_transform/src/no_landing_pads.rs diff --git a/src/doc/rustc-dev-guide/src/mir/passes.md b/src/doc/rustc-dev-guide/src/mir/passes.md index 5528b7762..4c7feb04e 100644 --- a/src/doc/rustc-dev-guide/src/mir/passes.md +++ b/src/doc/rustc-dev-guide/src/mir/passes.md @@ -33,9 +33,8 @@ basically consists of one method, `run_pass`, that simply gets an came from). The MIR is therefore modified in place (which helps to keep things efficient). -A good example of a basic MIR pass is [`NoLandingPads`], which walks -the MIR and removes all edges that are due to unwinding – this is -used when configured with `panic=abort`, which never unwinds. As you +A basic example of a MIR pass is [`RemoveStorageMarkers`], which walks +the MIR and removes all storage marks if they won't be emitted during codegen. As you can see from its source, a MIR pass is defined by first defining a dummy type, a struct with no fields, something like: @@ -97,6 +96,5 @@ alternatives in [rust-lang/rust#41710]. [rust-lang/rust#41710]: https://github.com/rust-lang/rust/issues/41710 [mirtransform]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/ -<!--- TODO: Change NoLandingPads. [#1232](https://github.com/rust-lang/rustc-dev-guide/issues/1232) --> -[`NoLandingPads`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/no_landing_pads/struct.NoLandingPads.html +[`RemoveStorageMarkers`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/remove_storage_markers/struct.RemoveStorageMarkers.html [MIR visitor]: ./visitor.html diff --git a/src/doc/rustc-dev-guide/src/mir/visitor.md b/src/doc/rustc-dev-guide/src/mir/visitor.md index 5c21d5304..505b700b3 100644 --- a/src/doc/rustc-dev-guide/src/mir/visitor.md +++ b/src/doc/rustc-dev-guide/src/mir/visitor.md @@ -37,12 +37,10 @@ code that will execute whenever a `foo` is found. If you want to recursively walk the contents of the `foo`, you then invoke the `super_foo` method. (NB. You never want to override `super_foo`.) -A very simple example of a visitor can be found in [`NoLandingPads`]. -That visitor doesn't even require any state: it just visits all -terminators and removes their `unwind` successors. +A very simple example of a visitor can be found in [`LocalUseCounter`]. +By implementing `visit_local` method, this visitor counts how many times each local is used. -<!--- TODO: Change NoLandingPads. [#1232](https://github.com/rust-lang/rustc-dev-guide/issues/1232) --> -[`NoLandingPads`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/no_landing_pads/struct.NoLandingPads.html +[`LocalUseCounter`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/simplify_try/struct.LocalUseCounter.html ## Traversal diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md index ceb0efdb2..ca37f94b2 100644 --- a/src/doc/rustc-dev-guide/src/overview.md +++ b/src/doc/rustc-dev-guide/src/overview.md @@ -374,7 +374,7 @@ For more details on bootstrapping, see - Lexical Analysis: Lex the user program to a stream of tokens - Guide: [Lexing and Parsing](the-parser.md) - Lexer definition: [`rustc_lexer`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/index.html) - - Main entry point: [`rustc_lexer::first_token`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/fn.first_token.html) + - Main entry point: [`rustc_lexer::cursor::Cursor::advance_token`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/cursor/struct.Cursor.html#method.advance_token) - Parsing: Parse the stream of tokens to an Abstract Syntax Tree (AST) - Guide: [Lexing and Parsing](the-parser.md) - Guide: [Macro Expansion](macro-expansion.md) diff --git a/src/doc/rustc-dev-guide/src/profile-guided-optimization.md b/src/doc/rustc-dev-guide/src/profile-guided-optimization.md index db2624e92..69c0599a0 100644 --- a/src/doc/rustc-dev-guide/src/profile-guided-optimization.md +++ b/src/doc/rustc-dev-guide/src/profile-guided-optimization.md @@ -131,8 +131,8 @@ in [run-make tests][rmake-tests] (the relevant tests have `pgo` in their name). There is also a [codegen test][codegen-test] that checks that some expected instrumentation artifacts show up in LLVM IR. -[rmake-tests]: https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps -[codegen-test]: https://github.com/rust-lang/rust/blob/master/src/test/codegen/pgo-instrumentation.rs +[rmake-tests]: https://github.com/rust-lang/rust/tree/master/tests/run-make-fulldeps +[codegen-test]: https://github.com/rust-lang/rust/blob/master/tests/codegen/pgo-instrumentation.rs ## Additional Information 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 abd2b0155..76ebf10e8 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 @@ -62,7 +62,8 @@ the result of `type_of(bar)` might yield a different result than what we have in the cache and, transitively, the result of `type_check_item(foo)` might have changed too. We thus re-run `type_check_item(foo)`, which in turn will re-run `type_of(bar)`, which will yield an up-to-date result -because it reads the up-to-date version of `Hir(bar)`. +because it reads the up-to-date version of `Hir(bar)`. Also, we re-run +`type_check_item(bar)` because result of `type_of(bar)` might have changed. ## The Problem With The Basic Algorithm: False Positives diff --git a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md index 8a08f1e04..296d88f6e 100644 --- a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md +++ b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md @@ -201,8 +201,8 @@ OK as long as the mutation is not observable. This is achieved by two things: - Before a result is stolen, we make sure to eagerly run all queries that might ever need to read that result. This has to be done manually by calling those queries. -- Whenever a query tries to access a stolen result, we make the compiler ICE so - that such a condition cannot go unnoticed. +- Whenever a query tries to access a stolen result, we make an ICE + (Internal Compiler Error) so that such a condition cannot go unnoticed. This is not an ideal setup because of the manual intervention needed, so it should be used sparingly and only when it is well known which queries might diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 268a56558..5dbffac8d 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -223,7 +223,7 @@ Let's go over these elements one by one: - **Query modifiers:** various flags and options that customize how the query is processed (mostly with respect to [incremental compilation][incrcomp]). -[Key]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_query_impl/keys/trait.Key.html +[Key]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/keys/trait.Key.html [incrcomp]: queries/incremental-compilation-in-detail.html#query-modifiers So, to add a query: diff --git a/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md b/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md index 5ce93c3df..bb19ad9d3 100644 --- a/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md +++ b/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md @@ -7,7 +7,7 @@ To get diagnostics from the compiler, configure `rustc_interface::Config` to output diagnostic to a buffer, and run `TyCtxt.analysis`. The following was tested -with <!-- date-check: June 2022 --> `nightly-2022-06-05` (See [here][example] +with <!-- date-check: Jan 2023 --> `nightly-2022-12-19` (See [here][example] for the complete example): [example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-driver-getting-diagnostics.rs @@ -24,11 +24,7 @@ let config = rustc_interface::Config { ), }, /* other config */ - }, - // Redirect the diagnostic output of the compiler to a buffer. - diagnostic_output: rustc_session::DiagnosticOutput::Raw(Box::from(DiagnosticSink( - buffer.clone(), - ))), + }, /* other config */ }; rustc_interface::run_compiler(config, |compiler| { diff --git a/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md b/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md index ce53f3861..5b495b4fe 100644 --- a/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md +++ b/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md @@ -5,7 +5,7 @@ ## Getting the type of an expression To get the type of an expression, use the `global_ctxt` to get a `TyCtxt`. -The following was tested with <!-- date-check: June 2022 --> `nightly-2022-06-05` +The following was tested with <!-- date-check: Jan 2023 --> `nightly-2022-12-19` (see [here][example] for the complete example): [example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-driver-interacting-with-the-ast.rs diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md index c85e82e96..a8cc0c376 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md @@ -191,7 +191,7 @@ Some extra reading about `make_test` can be found So that's rustdoc's code in a nutshell, but there's more things in the repo that deal with it. Since we have the full `compiletest` suite at hand, there's -a set of tests in `src/test/rustdoc` that make sure the final HTML is what we +a set of tests in `tests/rustdoc` that make sure the final HTML is what we expect in various situations. These tests also use a supplementary script, `src/etc/htmldocck.py`, that allows it to look through the final HTML using XPath notation to get a precise look at the output. The full description of all @@ -204,7 +204,7 @@ directory relative to the test file with the comment. If you need to build docs for the auxiliary file, use `// build-aux-docs`. In addition, there are separate tests for the search index and rustdoc's -ability to query it. The files in `src/test/rustdoc-js` each contain a +ability to query it. The files in `tests/rustdoc-js` each contain a different search query and the expected results, broken out by search tab. These files are processed by a script in `src/tools/rustdoc-js` and the Node.js runtime. These tests don't have as thorough of a writeup, but a broad example diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md index 23428efd6..d58b27bb7 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc.md +++ b/src/doc/rustc-dev-guide/src/rustdoc.md @@ -46,17 +46,17 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) * Use `./x.py build` to make a usable rustdoc you can run on other projects. * Add `library/test` to be able to use `rustdoc --test`. - * Run `rustup toolchain link stage2 build/$TARGET/stage2` to add a + * Run `rustup toolchain link stage2 build/host/stage2` to add a custom toolchain called `stage2` to your rustup environment. After running that, `cargo +stage2 doc` in any directory will build with your locally-compiled rustdoc. * Use `./x.py doc library` to use this rustdoc to generate the standard library docs. - * The completed docs will be available in `build/$TARGET/doc` (under `core`, `alloc`, and `std`). + * The completed docs will be available in `build/host/doc` (under `core`, `alloc`, and `std`). * If you want to copy those docs to a webserver, copy all of - `build/$TARGET/doc`, since that's where the CSS, JS, fonts, and landing + `build/host/doc`, since that's where the CSS, JS, fonts, and landing page are. -* Use `./x.py test src/test/rustdoc*` to run the tests using a stage1 +* Use `./x.py test tests/rustdoc*` to run the tests using a stage1 rustdoc. * See [Rustdoc internals] for more information about tests. @@ -72,13 +72,13 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) `doctest.rs`. * The Markdown renderer is loaded up in `html/markdown.rs`, including functions for extracting doctests from a given block of Markdown. -* The tests on the structure of rustdoc HTML output are located in `src/test/rustdoc`, where +* The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, where they're handled by the test runner of rustbuild and the supplementary script `src/etc/htmldocck.py`. ## Tests -* All paths in this section are relative to `src/test` in the rust-lang/rust repository. +* All paths in this section are relative to `tests` in the rust-lang/rust repository. * Tests on search index generation are located in `rustdoc-js`, as a series of JavaScript files that encode queries on the standard library search index and expected results. diff --git a/src/doc/rustc-dev-guide/src/sanitizers.md b/src/doc/rustc-dev-guide/src/sanitizers.md index a088d62ed..21b07ec99 100644 --- a/src/doc/rustc-dev-guide/src/sanitizers.md +++ b/src/doc/rustc-dev-guide/src/sanitizers.md @@ -9,6 +9,9 @@ The rustc compiler contains support for following sanitizers: forward-edge control flow protection. * [Hardware-assisted AddressSanitizer][clang-hwasan] a tool similar to AddressSanitizer but based on partial hardware assistance. +* [KernelControlFlowIntegrity][clang-kcfi] LLVM Kernel Control Flow Integrity + (KCFI) provides forward-edge control flow protection for operating systems + kernels. * [LeakSanitizer][clang-lsan] a run-time memory leak detector. * [MemorySanitizer][clang-msan] a detector of uninitialized reads. * [ThreadSanitizer][clang-tsan] a fast data race detector. @@ -16,9 +19,9 @@ The rustc compiler contains support for following sanitizers: ## How to use the sanitizers? To enable a sanitizer compile with `-Z sanitizer=...` option, where value is one -of `address`, `cfi`, `hwaddress`, `leak`, `memory` or `thread`. For more details -on how to use sanitizers please refer to the sanitizer flag in [the unstable -book](https://doc.rust-lang.org/unstable-book/). +of `address`, `cfi`, `hwaddress`, `kcfi`, `leak`, `memory` or `thread`. For more +details on how to use sanitizers please refer to the sanitizer flag in [the +unstable book](https://doc.rust-lang.org/unstable-book/). ## How are sanitizers implemented in rustc? @@ -73,8 +76,8 @@ implementation: ## Testing sanitizers Sanitizers are validated by code generation tests in -[`src/test/codegen/sanitize*.rs`][test-cg] and end-to-end functional tests in -[`src/test/ui/sanitize/`][test-ui] directory. +[`tests/codegen/sanitize*.rs`][test-cg] and end-to-end functional tests in +[`tests/ui/sanitize/`][test-ui] directory. Testing sanitizer functionality requires the sanitizer runtimes (built when `sanitizer = true` in `config.toml`) and target providing support for particular @@ -82,8 +85,8 @@ sanitizer. When sanitizer is unsupported on given target, sanitizers tests will be ignored. This behaviour is controlled by compiletest `needs-sanitizer-*` directives. -[test-cg]: https://github.com/rust-lang/rust/tree/master/src/test/codegen -[test-ui]: https://github.com/rust-lang/rust/tree/master/src/test/ui/sanitize +[test-cg]: https://github.com/rust-lang/rust/tree/master/tests/codegen +[test-ui]: https://github.com/rust-lang/rust/tree/master/tests/ui/sanitize ## Enabling sanitizer on a new target @@ -95,7 +98,7 @@ To enable a sanitizer on a new target which is already supported by LLVM: 2. [Build the runtime for the target and include it in the libdir.][sanitizer-targets] 3. [Teach compiletest that your target now supports the sanitizer.][compiletest-definition] Tests marked with `needs-sanitizer-*` should now run on the target. -4. Run tests `./x.py test --force-rerun src/test/ui/sanitize/` to verify. +4. Run tests `./x.py test --force-rerun tests/ui/sanitize/` to verify. 5. [--enable-sanitizers in the CI configuration][ci-configuration] to build and distribute the sanitizer runtime as part of the release process. @@ -109,6 +112,7 @@ To enable a sanitizer on a new target which is already supported by LLVM: * [AddressSanitizer in Clang][clang-asan] * [ControlFlowIntegrity in Clang][clang-cfi] * [Hardware-assisted AddressSanitizer][clang-hwasan] +* [KernelControlFlowIntegrity in Clang][clang-kcfi] * [LeakSanitizer in Clang][clang-lsan] * [MemorySanitizer in Clang][clang-msan] * [ThreadSanitizer in Clang][clang-tsan] @@ -116,6 +120,7 @@ To enable a sanitizer on a new target which is already supported by LLVM: [clang-asan]: https://clang.llvm.org/docs/AddressSanitizer.html [clang-cfi]: https://clang.llvm.org/docs/ControlFlowIntegrity.html [clang-hwasan]: https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html +[clang-kcfi]: https://clang.llvm.org/docs/ControlFlowIntegrity.html#fsanitize-kcfi [clang-lsan]: https://clang.llvm.org/docs/LeakSanitizer.html [clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html [clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html diff --git a/src/doc/rustc-dev-guide/src/serialization.md b/src/doc/rustc-dev-guide/src/serialization.md index 5d8434b55..691d21bc2 100644 --- a/src/doc/rustc-dev-guide/src/serialization.md +++ b/src/doc/rustc-dev-guide/src/serialization.md @@ -162,5 +162,5 @@ for `Encodable<CacheEncoder>`. [`rustc_metadata::rmeta::decoder::DecodeContext`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/decoder/struct.DecodeContext.html [`rustc_metadata::rmeta::encoder::EncodeContext`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/encoder/struct.EncodeContext.html [`rustc_serialize`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_serialize/index.html -[`TyDecoder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/codec/trait.TyEncoder.html -[`TyEncoder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/codec/trait.TyDecoder.html +[`TyDecoder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/codec/trait.TyDecoder.html +[`TyEncoder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/codec/trait.TyEncoder.html diff --git a/src/doc/rustc-dev-guide/src/tests/adding.md b/src/doc/rustc-dev-guide/src/tests/adding.md index 2fb1e0b65..632614539 100644 --- a/src/doc/rustc-dev-guide/src/tests/adding.md +++ b/src/doc/rustc-dev-guide/src/tests/adding.md @@ -12,7 +12,7 @@ This will depend on the nature of the change and what you want to exercise. Here are some rough guidelines: - The majority of compiler tests are done with [compiletest]. - - The majority of compiletest tests are [UI](ui.md) tests in the [`src/test/ui`] directory. + - The majority of compiletest tests are [UI](ui.md) tests in the [`tests/ui`] directory. - Changes to the standard library are usually tested within the standard library itself. - The majority of standard library tests are written as doctests, which illustrate and exercise typical API behavior. @@ -30,7 +30,7 @@ Here are some rough guidelines: - Check out the [compiletest] chapter for more specialized test suites. [compiletest]: compiletest.md -[`src/test/ui`]: https://github.com/rust-lang/rust/tree/master/src/test/ui/ +[`tests/ui`]: https://github.com/rust-lang/rust/tree/master/tests/ui/ ## UI test walkthrough @@ -41,13 +41,13 @@ For this tutorial, we'll be adding a test for an async error message. ### Step 1. Add a test file The first step is to create a Rust source file somewhere in the -[`src/test/ui`] tree. +[`tests/ui`] tree. When creating a test, do your best to find a good location and name (see [Test organization](ui.md#test-organization) for more). Since naming is the hardest part of development, everything should be downhill from here! -Let's place our async test at `src/test/ui/async-await/await-without-async.rs`: +Let's place our async test at `tests/ui/async-await/await-without-async.rs`: ```rust,ignore // Check what happens when using await in a non-async fn. @@ -84,19 +84,19 @@ The next step is to create the expected output from the compiler. This can be done with the `--bless` option: ```sh -./x.py test src/test/ui/async-await/await-without-async.rs --bless +./x.py test tests/ui/async-await/await-without-async.rs --bless ``` This will build the compiler (if it hasn't already been built), compile the test, and place the output of the compiler in a file called -`src/test/ui/async-await/await-without-async.stderr`. +`tests/ui/async-await/await-without-async.stderr`. However, this step will fail! You should see an error message, something like this: -> error: /rust/src/test/ui/async-await/await-without-async.rs:7: unexpected +> error: /rust/tests/ui/async-await/await-without-async.rs:7: unexpected > error: '7:10: 7:16: `await` is only allowed inside `async` functions and -> blocks [E0728]' +> blocks E0728' ### Step 3. Add error annotations @@ -118,7 +118,7 @@ annotations](ui.md#error-annotations) section). Save that, and run the test again: ```sh -./x.py test src/test/ui/async-await/await-without-async.rs +./x.py test tests/ui/async-await/await-without-async.rs ``` It should now pass, yay! @@ -131,7 +131,7 @@ If you are adding a new diagnostic message, now would be a good time to also consider how readable the message looks overall, particularly for people new to Rust. -Our example `src/test/ui/async-await/await-without-async.stderr` file should +Our example `tests/ui/async-await/await-without-async.stderr` file should look like this: ```text @@ -166,7 +166,7 @@ The final step before posting a PR is to check if you have affected anything els Running the UI suite is usually a good start: ```sh -./x.py test src/test/ui +./x.py test tests/ui ``` If other tests start failing, you may need to investigate what has changed diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index 70cef2ad3..9f0c56dc4 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -26,11 +26,11 @@ suite. ## Test suites -All of the tests are in the [`src/test`] directory. +All of the tests are in the [`tests`] directory. The tests are organized into "suites", with each suite in a separate subdirectory. Each test suite behaves a little differently, with different compiler behavior and different checks for correctness. -For example, the [`src/test/incremental`] directory contains tests for +For example, the [`tests/incremental`] directory contains tests for incremental compilation. The various suites are defined in [`src/tools/compiletest/src/common.rs`] in the `pub enum Mode` declaration. @@ -62,12 +62,12 @@ The following test suites are available, with links for more information: - `rustdoc-json` — tests on the JSON output of rustdoc. - `rustdoc-ui` — tests on the terminal output of rustdoc. -[`src/test`]: https://github.com/rust-lang/rust/blob/master/src/test +[`tests`]: https://github.com/rust-lang/rust/blob/master/tests [`src/tools/compiletest/src/common.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/common.rs ### Pretty-printer tests -The tests in [`src/test/pretty`] exercise the "pretty-printing" functionality of `rustc`. +The tests in [`tests/pretty`] exercise the "pretty-printing" functionality of `rustc`. The `-Z unpretty` CLI option for `rustc` causes it to translate the input source into various different formats, such as the Rust source after macro expansion. @@ -119,11 +119,11 @@ The header commands for pretty-printing tests are: pretty-printing rounds will be compared to ensure that the pretty-printed output converges to a steady state. -[`src/test/pretty`]: https://github.com/rust-lang/rust/tree/master/src/test/pretty +[`tests/pretty`]: https://github.com/rust-lang/rust/tree/master/tests/pretty ### Incremental tests -The tests in [`src/test/incremental`] exercise incremental compilation. +The tests in [`tests/incremental`] exercise incremental compilation. They use [revision headers](#revisions) to tell compiletest to run the compiler in a series of steps. Compiletest starts with an empty directory with the `-C incremental` flag, and @@ -168,12 +168,12 @@ cause an Internal Compiler Error (ICE). This is a highly specialized header to check that the incremental cache continues to work after an ICE. -[`src/test/incremental`]: https://github.com/rust-lang/rust/tree/master/src/test/incremental +[`tests/incremental`]: https://github.com/rust-lang/rust/tree/master/tests/incremental ### Debuginfo tests -The tests in [`src/test/debuginfo`] test debuginfo generation. +The tests in [`tests/debuginfo`] test debuginfo generation. They build a program, launch a debugger, and issue commands to the debugger. A single test can work with cdb, gdb, and lldb. @@ -237,12 +237,12 @@ test based on the debugger currently being used: NOTE: The "Rust" version of LLDB doesn't exist anymore, so this will always be ignored. This should probably be removed. -[`src/test/debuginfo`]: https://github.com/rust-lang/rust/tree/master/src/test/debuginfo +[`tests/debuginfo`]: https://github.com/rust-lang/rust/tree/master/tests/debuginfo ### Codegen tests -The tests in [`src/test/codegen`] test LLVM code generation. +The tests in [`tests/codegen`] test LLVM code generation. They compile the test with the `--emit=llvm-ir` flag to emit LLVM IR. They then run the LLVM [FileCheck] tool. The test is annotated with various `// CHECK` comments to check the generated code. @@ -250,13 +250,13 @@ See the FileCheck documentation for a tutorial and more information. See also the [assembly tests](#assembly-tests) for a similar set of tests. -[`src/test/codegen`]: https://github.com/rust-lang/rust/tree/master/src/test/codegen +[`tests/codegen`]: https://github.com/rust-lang/rust/tree/master/tests/codegen [FileCheck]: https://llvm.org/docs/CommandGuide/FileCheck.html ### Assembly tests -The tests in [`src/test/assembly`] test LLVM assembly output. +The tests in [`tests/assembly`] test LLVM assembly output. They compile the test with the `--emit=asm` flag to emit a `.s` file with the assembly output. They then run the LLVM [FileCheck] tool. @@ -271,12 +271,12 @@ See the FileCheck documentation for a tutorial and more information. See also the [codegen tests](#codegen-tests) for a similar set of tests. -[`src/test/assembly`]: https://github.com/rust-lang/rust/tree/master/src/test/assembly +[`tests/assembly`]: https://github.com/rust-lang/rust/tree/master/tests/assembly ### Codegen-units tests -The tests in [`src/test/codegen-units`] test the +The tests in [`tests/codegen-units`] test the [monomorphization](../backend/monomorph.md) collector and CGU partitioning. These tests work by running `rustc` with a flag to print the result of the @@ -295,12 +295,12 @@ where `cgu` is a space separated list of the CGU names and the linkage information in brackets. For example: `//~ MONO_ITEM static function::FOO @@ statics[Internal]` -[`src/test/codegen-units`]: https://github.com/rust-lang/rust/tree/master/src/test/codegen-units +[`tests/codegen-units`]: https://github.com/rust-lang/rust/tree/master/tests/codegen-units ### Mir-opt tests -The tests in [`src/test/mir-opt`] check parts of the generated MIR to make +The tests in [`tests/mir-opt`] check parts of the generated MIR to make sure it is generated correctly and is doing the expected optimizations. Check out the [MIR Optimizations](../mir/optimizations.md) chapter for more. @@ -345,12 +345,12 @@ problematic in the presence of pointers in constants or other bit width dependent things. In that case you can add `// EMIT_MIR_FOR_EACH_BIT_WIDTH` to your test, causing separate files to be generated for 32bit and 64bit systems. -[`src/test/mir-opt`]: https://github.com/rust-lang/rust/tree/master/src/test/mir-opt +[`tests/mir-opt`]: https://github.com/rust-lang/rust/tree/master/tests/mir-opt ### Run-make tests -The tests in [`src/test/run-make`] are general-purpose tests using Makefiles +The tests in [`tests/run-make`] are general-purpose tests using Makefiles which provide the ultimate in flexibility. These should be used as a last resort. If possible, you should use one of the other test suites. @@ -365,18 +365,18 @@ There is a [`tools.mk`] Makefile which you can include which provides a bunch of utilities to make it easier to run commands and compare outputs. Take a look at some of the other tests for some examples on how to get started. -[`tools.mk`]: https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/tools.mk -[`src/test/run-make`]: https://github.com/rust-lang/rust/tree/master/src/test/run-make +[`tools.mk`]: https://github.com/rust-lang/rust/blob/master/tests/run-make-fulldeps/tools.mk +[`tests/run-make`]: https://github.com/rust-lang/rust/tree/master/tests/run-make ### Valgrind tests -The tests in [`src/test/run-pass-valgrind`] are for use with [Valgrind]. +The tests in [`tests/run-pass-valgrind`] are for use with [Valgrind]. These are currently vestigial, as Valgrind is no longer used in CI. These may be removed in the future. [Valgrind]: https://valgrind.org/ -[`src/test/run-pass-valgrind`]: https://github.com/rust-lang/rust/tree/master/src/test/run-pass-valgrind +[`tests/run-pass-valgrind`]: https://github.com/rust-lang/rust/tree/master/tests/run-pass-valgrind ## Building auxiliary crates @@ -501,7 +501,7 @@ To run the tests in a different mode, you need to pass the `--compare-mode` CLI flag: ```bash -./x.py test src/test/ui --compare-mode=chalk +./x.py test tests/ui --compare-mode=chalk ``` The possible compare modes are: @@ -517,10 +517,10 @@ tests support different output for different modes. In CI, compare modes are only used in one Linux builder, and only with the following settings: -* `src/test/debuginfo`: Uses `split-dwarf` mode. +* `tests/debuginfo`: Uses `split-dwarf` mode. This helps ensure that none of the debuginfo tests are affected when enabling split-DWARF. Note that compare modes are separate to [revisions](#revisions). -All revisions are tested when running `./x.py test src/test/ui`, however +All revisions are tested when running `./x.py test tests/ui`, however compare-modes must be manually run individually via the `--compare-mode` flag. diff --git a/src/doc/rustc-dev-guide/src/tests/docker.md b/src/doc/rustc-dev-guide/src/tests/docker.md index feb614c51..0d9e0a492 100644 --- a/src/doc/rustc-dev-guide/src/tests/docker.md +++ b/src/doc/rustc-dev-guide/src/tests/docker.md @@ -21,7 +21,7 @@ directory. From there, you can run `../src/ci/run.sh` which will run the build as defined by the image. Alternatively, you can run individual commands to do specific tasks. For -example, you can run `python3 ../x.py test src/test/ui` to just run UI tests. +example, you can run `python3 ../x.py test tests/ui` to just run UI tests. Note that there is some configuration in the [`src/ci/run.sh`] script that you may need to recreate. Particularly, set `submodules = false` in your `config.toml` so that it doesn't attempt to modify the read-only directory. diff --git a/src/doc/rustc-dev-guide/src/tests/headers.md b/src/doc/rustc-dev-guide/src/tests/headers.md index bfa637f34..5b71f3ea1 100644 --- a/src/doc/rustc-dev-guide/src/tests/headers.md +++ b/src/doc/rustc-dev-guide/src/tests/headers.md @@ -244,12 +244,12 @@ described below: - Examples: `/path/to/rust`, `/path/to/build/root` - `{{src-base}}`: The directory where the test is defined. This is equivalent to `$DIR` for [output normalization]. - - Example: `/path/to/rust/src/test/ui/error-codes` + - Example: `/path/to/rust/tests/ui/error-codes` - `{{build-base}}`: The base directory where the test's output goes. This is equivalent to `$TEST_BUILD_DIR` for [output normalization]. - Example: `/path/to/rust/build/x86_64-unknown-linux-gnu/test/ui` -See [`src/test/ui/commandline-argfile.rs`](https://github.com/rust-lang/rust/blob/a5029ac0ab372aec515db2e718da6d7787f3d122/src/test/ui/commandline-argfile.rs) +See [`tests/ui/commandline-argfile.rs`](https://github.com/rust-lang/rust/blob/master/tests/ui/commandline-argfile.rs) for an example of a test that uses this substitution. [output normalization]: ui.md#normalization diff --git a/src/doc/rustc-dev-guide/src/tests/intro.md b/src/doc/rustc-dev-guide/src/tests/intro.md index 66e0a9eef..adc5d58ec 100644 --- a/src/doc/rustc-dev-guide/src/tests/intro.md +++ b/src/doc/rustc-dev-guide/src/tests/intro.md @@ -16,13 +16,13 @@ Almost all of them are driven by `./x.py test`, with some exceptions noted below The main test harness for testing the compiler itself is a tool called [compiletest]. It supports running different styles of tests, called *test suites*. -The tests are all located in the [`src/test`] directory. +The tests are all located in the [`tests`] directory. The [Compiletest chapter][compiletest] goes into detail on how to use this tool. -> Example: `./x.py test src/test/ui` +> Example: `./x.py test tests/ui` [compiletest]: compiletest.md -[`src/test`]: https://github.com/rust-lang/rust/tree/master/src/test +[`tests`]: https://github.com/rust-lang/rust/tree/master/tests ### Package tests diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md index 5d1441936..96c869109 100644 --- a/src/doc/rustc-dev-guide/src/tests/running.md +++ b/src/doc/rustc-dev-guide/src/tests/running.md @@ -37,7 +37,7 @@ modifying rustc to see if things are generally working correctly would be the following: ```bash -./x.py test src/test/ui +./x.py test tests/ui ``` This will run the `ui` test suite. Of course, the choice @@ -46,20 +46,20 @@ doing. For example, if you are hacking on debuginfo, you may be better off with the debuginfo test suite: ```bash -./x.py test src/test/debuginfo +./x.py test tests/debuginfo ``` If you only need to test a specific subdirectory of tests for any given test suite, you can pass that directory to `./x.py test`: ```bash -./x.py test src/test/ui/const-generics +./x.py test tests/ui/const-generics ``` Likewise, you can test a single file by passing its path: ```bash -./x.py test src/test/ui/const-generics/const-test.rs +./x.py test tests/ui/const-generics/const-test.rs ``` ### Run only the tidy script @@ -125,7 +125,7 @@ you may pass the full file path to achieve this, or alternatively one may invoke `x.py` with the `--test-args` option: ```bash -./x.py test src/test/ui --test-args issue-1234 +./x.py test tests/ui --test-args issue-1234 ``` Under the hood, the test runner invokes the standard Rust test runner @@ -137,10 +137,10 @@ filtering for tests that include "issue-1234" in the name. (Thus If you have changed the compiler's output intentionally, or you are making a new test, you can pass `--bless` to the test subcommand. E.g. -if some tests in `src/test/ui` are failing, you can run +if some tests in `tests/ui` are failing, you can run ```text -./x.py test src/test/ui --bless +./x.py test tests/ui --bless ``` to automatically adjust the `.stderr`, `.stdout` or `.fixed` files of @@ -165,10 +165,10 @@ Pass UI tests now have three modes, `check-pass`, `build-pass` and `run-pass`. When `--pass $mode` is passed, these tests will be forced to run under the given `$mode` unless the directive `// ignore-pass` exists in the test file. For example, you can run all the tests in -`src/test/ui` as `check-pass`: +`tests/ui` as `check-pass`: ```bash -./x.py test src/test/ui --pass check +./x.py test tests/ui --pass check ``` By passing `--pass $mode`, you can reduce the testing time. For each @@ -181,7 +181,7 @@ You can further enable the `--incremental` flag to save additional time in subsequent rebuilds: ```bash -./x.py test src/test/ui --incremental --test-args issue-1234 +./x.py test tests/ui --incremental --test-args issue-1234 ``` If you don't want to include the flag with every command, you can @@ -205,7 +205,7 @@ mode, a test `foo.rs` will first look for expected output in The following will run the UI test suite in Polonius mode: ```bash -./x.py test src/test/ui --compare-mode=polonius +./x.py test tests/ui --compare-mode=polonius ``` See [Compare modes](compiletest.md#compare-modes) for more details. @@ -218,7 +218,7 @@ Most tests are just `rs` files, so after you can do something like: ```bash -rustc +stage1 src/test/ui/issue-1234.rs +rustc +stage1 tests/ui/issue-1234.rs ``` This is much faster, but doesn't always work. For example, some tests @@ -242,7 +242,7 @@ machine, e.g. for RISC-V ``` The binary will be created at -`./build/$HOST_ARCH/stage2-tools/$TARGET_ARCH/release/remote-test-server`. Copy +`./build/host/stage2-tools/$TARGET_ARCH/release/remote-test-server`. Copy this over to the remote machine. On the remote machine, run the `remote-test-server` with the `--bind @@ -272,7 +272,7 @@ variable then use `x.py` as usual. For example, to run `ui` tests for a RISC-V machine with the IP address `1.2.3.4` use ```sh export TEST_DEVICE_ADDR="1.2.3.4:12345" -./x.py test src/test/ui --target riscv64gc-unknown-linux-gnu +./x.py test tests/ui --target riscv64gc-unknown-linux-gnu ``` If `remote-test-server` was run with the verbose flag, output on the test machine diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md index 3556f4e23..cc32ad1d3 100644 --- a/src/doc/rustc-dev-guide/src/tests/ui.md +++ b/src/doc/rustc-dev-guide/src/tests/ui.md @@ -6,18 +6,18 @@ UI tests are a particular [test suite](compiletest.md#test-suites) of compiletes ## Introduction -The tests in [`src/test/ui`] are a collection of general-purpose tests which +The tests in [`tests/ui`] are a collection of general-purpose tests which primarily focus on validating the console output of the compiler, but can be used for many other purposes. For example, tests can also be configured to [run the resulting program](#controlling-passfail-expectations) to verify its behavior. -[`src/test/ui`]: https://github.com/rust-lang/rust/blob/master/src/test/ui +[`tests/ui`]: https://github.com/rust-lang/rust/blob/master/tests/ui ## General structure of a test -A test consists of a Rust source file located anywhere in the `src/test/ui` directory. -For example, [`src/test/ui/hello.rs`] is a basic hello-world test. +A test consists of a Rust source file located anywhere in the `tests/ui` directory. +For example, [`tests/ui/hello.rs`] is a basic hello-world test. Compiletest will use `rustc` to compile the test, and compare the output against the expected output which is stored in a `.stdout` or `.stderr` file @@ -40,7 +40,7 @@ By default, a test is built as an executable binary. If you need a different crate type, you can use the `#![crate_type]` attribute to set it as needed. -[`src/test/ui/hello.rs`]: https://github.com/rust-lang/rust/blob/master/src/test/ui/hello.rs +[`tests/ui/hello.rs`]: https://github.com/rust-lang/rust/blob/master/tests/ui/hello.rs ## Output comparison @@ -99,7 +99,7 @@ platforms, mainly about filenames. Compiletest makes the following replacements on the compiler output: - The directory where the test is defined is replaced with `$DIR`. - Example: `/path/to/rust/src/test/ui/error-codes` + Example: `/path/to/rust/tests/ui/error-codes` - The directory to the standard library source is replaced with `$SRC_DIR`. Example: `/path/to/rust/library` - Line and column numbers for paths in `$SRC_DIR` are replaced with `LL:COL`. @@ -160,8 +160,8 @@ The corresponding reference file will use the normalized output to test both Please see [`ui/transmute/main.rs`][mrs] and [`main.stderr`] for a concrete usage example. -[mrs]: https://github.com/rust-lang/rust/blob/master/src/test/ui/transmute/main.rs -[`main.stderr`]: https://github.com/rust-lang/rust/blob/master/src/test/ui/transmute/main.stderr +[mrs]: https://github.com/rust-lang/rust/blob/master/tests/ui/transmute/main.rs +[`main.stderr`]: https://github.com/rust-lang/rust/blob/master/tests/ui/transmute/main.stderr Besides `normalize-stderr-32bit` and `-64bit`, one may use any target information or stage supported by [`ignore-X`](headers.md#ignoring-tests) @@ -387,7 +387,7 @@ Tests with the `*-pass` headers can be overridden with the `--pass` command-line option: ```sh -./x.py test src/test/ui --pass check +./x.py test tests/ui --pass check ``` The `--pass` option only affects UI tests. @@ -426,30 +426,30 @@ from the internet – we often name the test after the issue plus a short description. Ideally, the test should be added to a directory that helps identify what piece of code is being tested here (e.g., -`src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs`) +`tests/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs`) When writing a new feature, **create a subdirectory to store your tests**. For example, if you are implementing RFC 1234 ("Widgets"), then it might make -sense to put the tests in a directory like `src/test/ui/rfc1234-widgets/`. +sense to put the tests in a directory like `tests/ui/rfc1234-widgets/`. In other cases, there may already be a suitable directory. (The proper directory structure to use is actually an area of active debate.) -Over time, the [`src/test/ui`] directory has grown very fast. +Over time, the [`tests/ui`] directory has grown very fast. There is a check in [tidy](intro.md#tidy) that will ensure none of the subdirectories has more than 1000 entries. Having too many files causes problems because it isn't editor/IDE friendly and the GitHub UI won't show more than 1000 entries. -However, since `src/test/ui` (UI test root directory) and `src/test/ui/issues` +However, since `tests/ui` (UI test root directory) and `tests/ui/issues` directories have more than 1000 entries, we set a different limit for those directories. So, please avoid putting a new test there and try to find a more relevant place. For example, if your test is related to closures, you should put it in -`src/test/ui/closures`. +`tests/ui/closures`. If you're not sure where is the best place, it's still okay to add to -`src/test/ui/issues/`. +`tests/ui/issues/`. When you reach the limit, you could increase it by tweaking [here][ui test tidy]. @@ -512,7 +512,7 @@ If in the rare case you encounter a test that has different behavior, you can run something like the following to generate the alternate stderr file: ```sh -./x.py test src/test/ui --compare-mode=polonius --bless +./x.py test tests/ui --compare-mode=polonius --bless ``` Currently none of the compare modes are checked in CI for UI tests. diff --git a/src/doc/rustc-dev-guide/src/ty.md b/src/doc/rustc-dev-guide/src/ty.md index 9b35f0d4c..90e17e85f 100644 --- a/src/doc/rustc-dev-guide/src/ty.md +++ b/src/doc/rustc-dev-guide/src/ty.md @@ -119,23 +119,20 @@ or `fn(i32) -> i32` (with type aliases fully expanded). ## `ty::Ty` implementation -[`rustc_middle::ty::Ty`][ty_ty] is actually a type alias to [`&TyS`][tys]. -This type, which is short for "Type Structure", is where the main functionality is located. -You can ignore `TyS` struct in general; you will basically never access it explicitly. -We always pass it by reference using the `Ty` alias. -The only exception is to define inherent methods on types. In particular, `TyS` has a [`kind`][kind] -field of type [`TyKind`][tykind], which represents the key type information. `TyKind` is a big enum +[`rustc_middle::ty::Ty`][ty_ty] is actually a wrapper around +[`Interned<WithCachedTypeInfo<TyKind>>`][tykind]. +You can ignore `Interned` in general; you will basically never access it explicitly. +We always hide them within `Ty` and skip over it via `Deref` impls or methods. +`TyKind` is a big enum with variants to represent many different Rust types (e.g. primitives, references, abstract data types, generics, lifetimes, etc). -`TyS` also has 2 more fields, `flags` and `outer_exclusive_binder`. They +`WithCachedTypeInfo` has a few cached values like `flags` and `outer_exclusive_binder`. They are convenient hacks for efficiency and summarize information about the type that we may want to -know, but they don’t come into the picture as much here. Finally, `ty::TyS`s -are [interned](./memory.md), so that the `ty::Ty` can be a thin pointer-like +know, but they don’t come into the picture as much here. Finally, [`Interned`](./memory.md) allows +the `ty::Ty` to be a thin pointer-like type. This allows us to do cheap comparisons for equality, along with the other benefits of interning. -[tys]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html -[kind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#structfield.kind [tykind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html ## Allocating and working with types diff --git a/src/doc/rustc-dev-guide/src/type-checking.md b/src/doc/rustc-dev-guide/src/type-checking.md index cd58faf22..08f15e30b 100644 --- a/src/doc/rustc-dev-guide/src/type-checking.md +++ b/src/doc/rustc-dev-guide/src/type-checking.md @@ -4,7 +4,7 @@ The [`rustc_typeck`][typeck] crate contains the source for "type collection" and "type checking", as well as a few other bits of related functionality. (It draws heavily on the [type inference] and [trait solving].) -[typeck]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/index.html +[typeck]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/index.html [type inference]: ./type-inference.md [trait solving]: ./traits/resolution.md @@ -39,6 +39,6 @@ type *checking*). For more details, see the [`collect`][collect] module. [queries]: ./query.md -[collect]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/collect/ +[collect]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/collect/index.html **TODO**: actually talk about type checking... [#1161](https://github.com/rust-lang/rustc-dev-guide/issues/1161) diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 2d3b83094..752f1cc4a 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -22,10 +22,11 @@ - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md) - [armv5te-none-eabi](platform-support/armv5te-none-eabi.md) - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md) + - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) - [\*-android and \*-androideabi](platform-support/android.md) - - [\*-fuchsia](platform-support/fuchsia.md) + - [\*-unknown-fuchsia](platform-support/fuchsia.md) - [\*-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) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index ef6eee75f..d4d26654e 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -434,6 +434,9 @@ replacement is purely textual, with no consideration of the current system's pathname syntax. For example `--remap-path-prefix foo=bar` will match `foo/lib.rs` but not `./foo/lib.rs`. +When multiple remappings are given and several of them match, the **last** +matching one is applied. + <a id="option-json"></a> ## `--json`: configure json messages printed by the compiler diff --git a/src/doc/rustc/src/exploit-mitigations.md b/src/doc/rustc/src/exploit-mitigations.md index fa38dd54d..98b49e071 100644 --- a/src/doc/rustc/src/exploit-mitigations.md +++ b/src/doc/rustc/src/exploit-mitigations.md @@ -217,7 +217,7 @@ It is recommended that explicit wrapping methods such as `wrapping_add` be used when wrapping semantics are intended, and that explicit checking and wrapping methods always be used when using Unsafe Rust. -<small id="fn:2">2\. See <https://doc.rust-lang.org/std/primitive.u32.html> +<small id="fn:2">2\. See [the `u32` docs](../std/primitive.u32.html) for more information on the checked, overflowing, saturating, and wrapping methods (using u32 as an example). <a href="#fnref:2" class="reversefootnote" role="doc-backlink">↩</a></small> @@ -575,17 +575,17 @@ defaults (unrelated to `READ_IMPLIES_EXEC`). <https://hacks.mozilla.org/2019/02/fearless-security-thread-safety/>. 3. S. Klabnik and C. Nichols. “What Is Ownership?.” The Rust Programming - Language. <https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html>. + Language. [https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html](../book/ch04-01-what-is-ownership.html). 4. S. Klabnik and C. Nichols. “References and Borrowing.” The Rust Programming Language. - <https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html>. + [https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html](../book/ch04-02-references-and-borrowing.html). 5. S. Klabnik and C. Nichols. “The Slice Type.” The Rust Programming - Language. <https://doc.rust-lang.org/book/ch04-03-slices.html>. + Language. [https://doc.rust-lang.org/book/ch04-03-slices.html](../book/ch04-03-slices.html). 6. S. Klabnik and C. Nichols. “Unsafe Rust.” The Rust Programming Language. - <https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html>. + [https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html](../book/ch19-01-unsafe-rust.html). 7. S. Davidoff. “How Rust’s standard library was vulnerable for years and nobody noticed.” Medium. @@ -696,4 +696,4 @@ defaults (unrelated to `READ_IMPLIES_EXEC`). for Rust #89653.” GitHub. <https://github.com/rust-lang/rust/issues/89653>. 41. “ControlFlowIntegrity.” The Rust Unstable Book. - <https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html#controlflowintegrity>. + [https://doc.rust-lang.org/unstable-book/compiler-flags/sanitizer.html#controlflowintegrity](../unstable-book/compiler-flags/sanitizer.html#controlflowintegrity). diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md index 38fd5c969..da91e2559 100644 --- a/src/doc/rustc/src/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -201,6 +201,8 @@ $ RUSTFLAGS="-C instrument-coverage" \ cargo test --tests ``` +> **Note**: The default for `LLVM_PROFILE_FILE` is `default_%m_%p.profraw`. Versions prior to 1.65 had a default of `default.profraw`, so if using those earlier versions, it is recommended to explicitly set `LLVM_PROFILE_FILE="default_%m_%p.profraw"` to avoid having multiple tests overwrite the `.profraw` files. + Make note of the test binary file paths, displayed after the word "`Running`" in the test output: ```text diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md index 9272b9ac9..858b7bc79 100644 --- a/src/doc/rustc/src/linker-plugin-lto.md +++ b/src/doc/rustc/src/linker-plugin-lto.md @@ -112,7 +112,7 @@ targeting Windows-like targets This is fixed if you explicitly set the target, for example `cargo build --target x86_64-pc-windows-msvc` Without an explicit --target the flags will be passed to all compiler invocations (including build -scripts and proc macros), see [cargo docs on rustflags](https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags) +scripts and proc macros), see [cargo docs on rustflags](../cargo/reference/config.html#buildrustflags) If you have dependencies using the `cc` crate, you will need to set these environment variables: diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d0c3ddf26..160570482 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -124,7 +124,8 @@ target | std | notes -------|:---:|------- `aarch64-apple-ios` | ✓ | ARM64 iOS [`aarch64-apple-ios-sim`](platform-support/aarch64-apple-ios-sim.md) | ✓ | Apple iOS Simulator on ARM64 -`aarch64-fuchsia` | ✓ | ARM64 Fuchsia +`aarch64-fuchsia` | ✓ | Alias for `aarch64-unknown-fuchsia` +`aarch64-unknown-fuchsia` | ✓ | ARM64 Fuchsia [`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android `aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat `aarch64-unknown-none` | * | Bare ARM64, hardfloat @@ -177,7 +178,8 @@ target | std | notes `wasm32-wasi` | ✓ | WebAssembly with WASI `x86_64-apple-ios` | ✓ | 64-bit x86 iOS [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX -`x86_64-fuchsia` | ✓ | 64-bit Fuchsia +`x86_64-fuchsia` | ✓ | Alias for `x86_64-unknown-fuchsia` +`x86_64-unknown-fuchsia` | ✓ | 64-bit Fuchsia [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android `x86_64-pc-solaris` | ✓ | 64-bit Solaris 10/11, illumos `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) @@ -235,6 +237,7 @@ target | std | host | notes `armv6-unknown-netbsd-eabihf` | ? | | [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain) `armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8 +[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ? | | ARM Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7 Linux with uClibc, softfloat [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7 Linux with uClibc, hardfloat `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD diff --git a/src/doc/rustc/src/platform-support/android.md b/src/doc/rustc/src/platform-support/android.md index b2c8e5d4d..e351cfaf8 100644 --- a/src/doc/rustc/src/platform-support/android.md +++ b/src/doc/rustc/src/platform-support/android.md @@ -42,4 +42,4 @@ edition of the [Android NDK]. Supported Android targets are: [Android NDK]: https://developer.android.com/ndk/downloads A list of all supported targets can be found -[here](https://doc.rust-lang.org/rustc/platform-support.html) +[here](../platform-support.html) diff --git a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md index 215290e38..2ce0ccb78 100644 --- a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md +++ b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md @@ -111,7 +111,7 @@ to an SD card to be inserted in the device. The `cargo-3ds` tool mentioned in [Building Rust programs](#building-rust-programs) supports the use of `3dslink` with `cargo 3ds run`. The default Rust test runner is not supported, but -[custom test frameworks](https://doc.rust-lang.org/beta/unstable-book/language-features/custom-test-frameworks.html) +[custom test frameworks](../../unstable-book/language-features/custom-test-frameworks.html) can be used with `cargo 3ds test` to run unit tests on a device. The Rust test suite for `library/std` is not yet supported. diff --git a/src/doc/rustc/src/platform-support/armv7-sony-vita-eabihf.md b/src/doc/rustc/src/platform-support/armv7-sony-vita-eabihf.md new file mode 100644 index 000000000..6619c90b8 --- /dev/null +++ b/src/doc/rustc/src/platform-support/armv7-sony-vita-eabihf.md @@ -0,0 +1,127 @@ +# armv7-sony-vita-eabihf + +**Tier: 3** + +This tier supports the ARM Cortex A9 processor running on a PlayStation Vita console. `armv7-vita-newlibeabihf` aims to have support for `std` crate using `newlib` as a bridge. + +## Designated Developers + +* [@amg98](https://github.com/amg98) + +## Requirements + +This target is cross compiled, and requires installing [VITASDK](https://vitasdk.org/) toolchain on your system. + +## Building + +You can build Rust with support for the target by adding it to the `target` +list in `config.toml`: + +```toml +[build] +build-stage = 1 +target = ["armv7-sony-vita-newlibeabihf"] +``` + +## Cross-compilation + +This target can be cross-compiled from `x86_64` on either Windows, MacOS or Linux systems. Other hosts are not supported for cross-compilation. + +## Testing + +Currently there is no support to run the rustc test suite for this target. + +## Building and Running Rust Programs + +To test your developed rust programs for PlayStation Vita, first you have to prepare a proper executable for the device using the resulting ELF file you get from compilation step. The needed steps can be automated using tools like `cargo-make`. Use the example below as a template for your project: + +```toml +[env] +TITLE = "Rust Hello World" +TITLEID = "RUST00001" +# At least a "sce_sys" folder should be place there for app metadata (title, icons, description...) +# You can find sample assets for that on $VITASDK/share/gcc-arm-vita-eabi/samples/hello_world/sce_sys/ +STATIC_DIR = "static" # Folder where static assets should be placed (sce_sys folder is at $STATIC_DIR/sce_sys) +CARGO_TARGET_DIR = { script = ["echo ${CARGO_TARGET_DIR:=target}"] } +RUST_TARGET_PATH = { script = ["echo $(pwd)"]} +RUST_TARGET = "armv7-sony-vita-newlibeabihf" +CARGO_OUT_DIR = "${CARGO_TARGET_DIR}/${RUST_TARGET}/release" + +[tasks.xbuild] +# This is the command where you get the ELF executable file (e.g. call to cargo build) + +[tasks.strip] +description = "Strip the produced ELF executable." +dependencies = ["xbuild"] +command = "arm-vita-eabi-strip" +args = ["-g", '${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_FS_NAME}.elf'] + +[tasks.velf] +description = "Build an VELF executable from the obtained ELF file." +dependencies = ["strip"] +command = "vita-elf-create" +args = ['${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_NAME}.elf', '${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_NAME}.velf'] + +[tasks.eboot-bin] +description = "Build an `eboot.bin` file from the obtained VELF file." +dependencies = ["velf"] +command = "vita-make-fself" +args = ["-s", '${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_NAME}.velf', '${CARGO_OUT_DIR}/eboot.bin'] + +[tasks.param-sfo] +description = "Build the `param.sfo` manifest using with given TITLE and TITLEID." +command = "vita-mksfoex" +args = ["-s", 'TITLE_ID=${TITLEID}', '${TITLE}', '${CARGO_OUT_DIR}/param.sfo'] + +[tasks.manifest] +description = "List all static resources into a manifest file." +script = [ + 'mkdir -p "${CARGO_OUT_DIR}"', + ''' + if [ -d "${STATIC_DIR}" ]; then + find "${STATIC_DIR}" -type f > "${CARGO_OUT_DIR}/MANIFEST" + else + touch "${CARGO_OUT_DIR}/MANIFEST" + fi + ''' +] + +[tasks.vpk] +description = "Build a VPK distribution of the project executable and resources." +dependencies = ["eboot-bin", "param-sfo", "manifest"] +script_runner = "@rust" +script = [ + ''' + use std::io::BufRead; + use std::fs::File; + + fn main() { + + let crate_name = env!("CARGO_MAKE_CRATE_NAME"); + let static_dir = env!("STATIC_DIR"); + let out_dir = std::path::PathBuf::from(env!("CARGO_OUT_DIR")); + + let mut cmd = ::std::process::Command::new("vita-pack-vpk"); + cmd.arg("-s").arg(out_dir.join("param.sfo")); + cmd.arg("-b").arg(out_dir.join("eboot.bin")); + + // Add files from MANIFEST + if let Ok(file) = File::open(out_dir.join("MANIFEST")) { + let mut reader = ::std::io::BufReader::new(file); + let mut lines = reader.lines(); + while let Some(Ok(line)) = lines.next() { + let p1 = ::std::path::PathBuf::from(line); // path on FS + let p2 = p1.strip_prefix(static_dir).unwrap(); // path in VPK + cmd.arg("--add").arg(format!("{}={}", p1.display(), p2.display())); + } + } + + cmd.arg(out_dir.join(format!("{}.vpk", crate_name))) + .output() + .expect("command failed."); + } + ''' +] +``` + +After running the above script, you should be able to get a *.vpk file in the same folder your *.elf executable resides. Now you can pick it and install it on your own PlayStation Vita using, for example, [VitaShell](https://github.com/TheOfficialFloW/VitaShell/releases) or you can use an emulator. For the time being, the most mature emulator for PlayStation Vita is [Vita3K](https://vita3k.org/), although I personally recommend testing your programs in real hardware, as the emulator is quite experimental. diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index fbf999f97..29e70129a 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -1,4 +1,4 @@ -# `aarch64-fuchsia` and `x86_64-fuchsia` +# `aarch64-unknown-fuchsia` and `x86_64-unknown-fuchsia` **Tier: 2** @@ -67,7 +67,7 @@ This walkthrough will cover: 1. Building a Fuchsia package. 1. Publishing and running a Fuchsia package to a Fuchsia emulator. -For the purposes of this walkthrough, we will only target `x86_64-fuchsia`. +For the purposes of this walkthrough, we will only target `x86_64-unknown-fuchsia`. ## Compiling a Rust binary targeting Fuchsia @@ -83,14 +83,14 @@ to handle the installation of Fuchsia targets for you. This can be done by issui the following commands: ```sh -rustup target add x86_64-fuchsia -rustup target add aarch64-fuchsia +rustup target add x86_64-unknown-fuchsia +rustup target add aarch64-unknown-fuchsia ``` After installing our Fuchsia targets, we can now compile a Rust binary that targets Fuchsia. -To create our Rust project, we can issue a standard `cargo` command as follows: +To create our Rust project, we can use [`cargo`][cargo] as follows: **From base working directory** ```sh @@ -127,7 +127,7 @@ during compilation: **`.cargo/config.toml`** ```txt -[target.x86_64-fuchsia] +[target.x86_64-unknown-fuchsia] rustflags = [ "-Lnative=<SDK_PATH>/arch/x64/lib", @@ -159,10 +159,10 @@ hello_fuchsia/ Finally, we can build our rust binary as: ```sh -cargo build --target x86_64-fuchsia +cargo build --target x86_64-unknown-fuchsia ``` -Now we have a Rust binary at `target/x86_64-fuchsia/debug/hello_fuchsia`, +Now we have a Rust binary at `target/x86_64-unknown-fuchsia/debug/hello_fuchsia`, targeting our desired Fuchsia target. **Current directory structure** @@ -171,7 +171,7 @@ hello_fuchsia/ ┣━ src/ ┃ ┗━ main.rs ┣━ target/ -┃ ┗━ x86_64-fuchsia/ +┃ ┗━ x86_64-unknown-fuchsia/ ┃ ┗━ debug/ ┃ ┗━ hello_fuchsia ┣━ Cargo.toml @@ -193,16 +193,19 @@ configuration in `config.toml`: ```toml [build] -target = ["<host_platform>", "aarch64-fuchsia", "x86_64-fuchsia"] +target = ["<host_platform>", "aarch64-unknown-fuchsia", "x86_64-unknown-fuchsia"] [rust] lld = true -[target.x86_64-fuchsia] +[llvm] +download-ci-llvm = false + +[target.x86_64-unknown-fuchsia] cc = "clang" cxx = "clang++" -[target.aarch64-fuchsia] +[target.aarch64-unknown-fuchsia] cc = "clang" cxx = "clang++" ``` @@ -233,14 +236,14 @@ a script we name `config-env.sh`: # Configure this environment variable to be the path to the downloaded SDK export SDK_PATH="<SDK path goes here>" -export CFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include" -export CXXFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include" -export LDFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -L${SDK_PATH}/arch/arm64/lib" -export CARGO_TARGET_AARCH64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/arm64/sysroot -Lnative=${SDK_PATH}/arch/arm64/sysroot/lib -Lnative=${SDK_PATH}/arch/arm64/lib" -export CFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include" -export CXXFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include" -export LDFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -L${SDK_PATH}/arch/x64/lib" -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" +export CFLAGS_aarch64_unknown_fuchsia="--target=aarch64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export CXXFLAGS_aarch64_unknown_fuchsia="--target=aarch64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export LDFLAGS_aarch64_unknown_fuchsia="--target=aarch64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -L${SDK_PATH}/arch/arm64/lib" +export CARGO_TARGET_AARCH64_UNKNOWN_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/arm64/sysroot -Lnative=${SDK_PATH}/arch/arm64/sysroot/lib -Lnative=${SDK_PATH}/arch/arm64/lib" +export CFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export CXXFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export LDFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -L${SDK_PATH}/arch/x64/lib" +export CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/x64/sysroot -Lnative=${SDK_PATH}/arch/x64/sysroot/lib -Lnative=${SDK_PATH}/arch/x64/lib" ``` Finally, the Rust compiler can be built and installed: @@ -285,7 +288,7 @@ hello_fuchsia/ Using your freshly installed `rustc`, you can compile a binary for Fuchsia using the following options: -* `--target x86_64-fuchsia`/`--target aarch64-fuchsia`: Targets the Fuchsia +* `--target x86_64-unknown-fuchsia`/`--target aarch64-unknown-fuchsia`: Targets the Fuchsia platform of your choice * `-Lnative ${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from the SDK @@ -296,7 +299,7 @@ Putting it all together: ```sh # Configure these for the Fuchsia target of your choice -TARGET_ARCH="<x86_64-fuchsia|aarch64-fuchsia>" +TARGET_ARCH="<x86_64-unknown-fuchsia|aarch64-unknown-fuchsia>" ARCH="<x64|aarch64>" rustc \ @@ -322,16 +325,16 @@ Before moving on, double check your directory structure: **Current directory structure** ```txt hello_fuchsia/ -┣━ src/ (if using rustc) -┃ ┗━ hello_fuchsia.rs ... -┣━ bin/ ... -┃ ┗━ hello_fuchsia ... -┣━ src/ (if using cargo) -┃ ┗━ main.rs ... -┗━ target/ ... - ┗━ x86_64-fuchsia/ ... - ┗━ debug/ ... - ┗━ hello_fuchsia ... +┣━ src/ (if using rustc) +┃ ┗━ hello_fuchsia.rs ... +┣━ bin/ ... +┃ ┗━ hello_fuchsia ... +┣━ src/ (if using cargo) +┃ ┗━ main.rs ... +┗━ target/ ... + ┗━ x86_64-unknown-fuchsia/ ... + ┗━ debug/ ... + ┗━ hello_fuchsia ... ``` With our Rust binary built, we can move to creating a Fuchsia package. @@ -368,7 +371,7 @@ package must contain one. **`pkg/hello_fuchsia.manifest` if using cargo** ```txt -bin/hello_fuchsia=target/x86_64-fuchsia/debug/hello_fuchsia +bin/hello_fuchsia=target/x86_64-unknown-fuchsia/debug/hello_fuchsia lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1 lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so meta/package=pkg/meta/package @@ -543,16 +546,16 @@ structure will look like: **Final directory structure** ```txt hello_fuchsia/ -┣━ src/ (if using rustc) -┃ ┗━ hello_fuchsia.rs ... -┣━ bin/ ... -┃ ┗━ hello_fuchsia ... -┣━ src/ (if using cargo) -┃ ┗━ main.rs ... -┣━ target/ ... -┃ ┗━ x86_64-fuchsia/ ... -┃ ┗━ debug/ ... -┃ ┗━ hello_fuchsia ... +┣━ src/ (if using rustc) +┃ ┗━ hello_fuchsia.rs ... +┣━ bin/ ... +┃ ┗━ hello_fuchsia ... +┣━ src/ (if using cargo) +┃ ┗━ main.rs ... +┣━ target/ ... +┃ ┗━ x86_64-unknown-fuchsia/ ... +┃ ┗━ debug/ ... +┃ ┗━ hello_fuchsia ... ┗━ pkg/ ┣━ meta/ ┃ ┣━ package @@ -641,8 +644,8 @@ Tests can be run in the same way as a regular binary. * If using `cargo`, you can simply pass `test --no-run` to the `cargo` invocation and then repackage and rerun the Fuchsia package. From our previous example, -this would look like `cargo test --target x86_64-fuchsia --no-run`, and moving the executable -binary path found from the line `Executable unittests src/main.rs (target/x86_64-fuchsia/debug/deps/hello_fuchsia-<HASH>)` +this would look like `cargo test --target x86_64-unknown-fuchsia --no-run`, and moving the executable +binary path found from the line `Executable unittests src/main.rs (target/x86_64-unknown-fuchsia/debug/deps/hello_fuchsia-<HASH>)` into `pkg/hello_fuchsia.manifest`. * If using the compiled `rustc`, you can simply pass `--test` @@ -702,7 +705,7 @@ Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and 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: +run the full `tests/ui` test suite: ```sh ( \ @@ -710,8 +713,8 @@ run the full `src/test/ui` test suite: ./x.py \ --config config.toml \ --stage=2 \ - test src/test/ui \ - --target x86_64-fuchsia \ + test tests/ui \ + --target x86_64-unknown-fuchsia \ --run=always --jobs 1 \ --test-args --target-rustcflags \ --test-args -L \ @@ -755,7 +758,7 @@ directory to launch `zxdb`: **In separate terminal** ```sh ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \ - --symbol-path target/x86_64-fuchsia/debug + --symbol-path target/x86_64-unknown-fuchsia/debug ``` * `--symbol-path` gets required symbol paths, which are @@ -851,7 +854,7 @@ source code: ```sh ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \ - --symbol-path target/x86_64-fuchsia/debug \ + --symbol-path target/x86_64-unknown-fuchsia/debug \ --build-dir ${RUST_SRC_PATH}/rust \ --build-dir ${FUCHSIA_SRC_PATH}/fuchsia/out/default ``` @@ -867,7 +870,7 @@ ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \ [Fuchsia]: https://fuchsia.dev/ [source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build [rustup]: https://rustup.rs/ -[cargo]: https://doc.rust-lang.org/cargo/ +[cargo]: ../../cargo/index.html [Fuchsia SDK]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core [overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests [reference for the file format]: https://fuchsia.dev/reference/cml diff --git a/src/doc/rustc/src/targets/custom.md b/src/doc/rustc/src/targets/custom.md index 27ef2f49e..a67cb10fc 100644 --- a/src/doc/rustc/src/targets/custom.md +++ b/src/doc/rustc/src/targets/custom.md @@ -14,4 +14,4 @@ To see it for a different target, add the `--target` flag: rustc +nightly -Z unstable-options --target=wasm32-unknown-unknown --print target-spec-json ``` -To use a custom target, see the (unstable) [`build-std` feature](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std) of `cargo`. +To use a custom target, see the (unstable) [`build-std` feature](../../cargo/reference/unstable.html#build-std) of `cargo`. diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md index 5859df83f..f291cde2e 100644 --- a/src/doc/rustc/src/targets/index.md +++ b/src/doc/rustc/src/targets/index.md @@ -1,7 +1,10 @@ # Targets `rustc` is a cross-compiler by default. This means that you can use any compiler to build for any -architecture. The list of *targets* are the possible architectures that you can build for. +architecture. The list of *targets* are the possible architectures that you can build for. See +the [Platform Support](../platform-support.md) page for a detailed list of targets, or +[Built-in Targets](built-in.md) for instructions on how to view what is available for your version +of `rustc`. To see all the options that you can set with a target, see the docs [here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/struct.Target.html). diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md index e3b086489..8ecf05f0e 100644 --- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md +++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md @@ -9,11 +9,11 @@ are the same: ```rust,no_run /// This is a doc comment. -#[doc = " This is a doc comment."] +#[doc = r" This is a doc comment."] # fn f() {} ``` -(Note the leading space in the attribute version.) +(Note the leading space and the raw string literal in the attribute version.) In most cases, `///` is easier to use than `#[doc]`. One case where the latter is easier is when generating documentation in macros; the `collapse-docs` pass will combine multiple diff --git a/src/doc/unstable-book/src/compiler-flags/branch-protection.md b/src/doc/unstable-book/src/compiler-flags/branch-protection.md index 85403748e..ca5664835 100644 --- a/src/doc/unstable-book/src/compiler-flags/branch-protection.md +++ b/src/doc/unstable-book/src/compiler-flags/branch-protection.md @@ -1,7 +1,7 @@ # `branch-protection` This option lets you enable branch authentication instructions on AArch64. -This option is ignored for non-AArch64 architectures. +This option is only accepted when targeting AArch64 architectures. It takes some combination of the following values, separated by a `,`. - `pac-ret` - Enable pointer authentication for non-leaf functions. @@ -15,4 +15,4 @@ For example, `-Z branch-protection=bti,pac-ret,leaf` is valid, but Rust's standard library does not ship with BTI or pointer authentication enabled by default. In Cargo projects the standard library can be recompiled with pointer authentication using the nightly -[build-std](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std) feature. +[build-std](../../cargo/reference/unstable.html#build-std) feature. diff --git a/src/doc/unstable-book/src/compiler-flags/codegen-backend.md b/src/doc/unstable-book/src/compiler-flags/codegen-backend.md index 3c0cd32fa..67634be69 100644 --- a/src/doc/unstable-book/src/compiler-flags/codegen-backend.md +++ b/src/doc/unstable-book/src/compiler-flags/codegen-backend.md @@ -12,7 +12,7 @@ backend. The library must be of crate type `dylib` and must contain a function named `__rustc_codegen_backend` with a signature of `fn() -> Box<dyn rustc_codegen_ssa::traits::CodegenBackend>`. ## Example -See also the [`hotplug_codegen_backend`](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/hotplug_codegen_backend) test +See also the [`hotplug_codegen_backend`](https://github.com/rust-lang/rust/tree/master/tests/run-make-fulldeps/hotplug_codegen_backend) test for a full example. ```rust,ignore (partial-example) diff --git a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md b/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md index 08c16d95f..dbb741422 100644 --- a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md +++ b/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md @@ -39,7 +39,7 @@ It is strongly recommended to also enable CFG checks for all linked libraries, i To enable CFG in the standard library, use the [cargo `-Z build-std` functionality][build-std] to recompile the standard library with the same configuration options as the main program. -[build-std]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std +[build-std]: ../../cargo/reference/unstable.html#build-std For example: ```cmd diff --git a/src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md b/src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md new file mode 100644 index 000000000..a497a7526 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md @@ -0,0 +1,6 @@ +# `dump-mono-stats-format` + +-------------------- + +The `-Z dump-mono-stats-format` compiler flag controls what file format to use for `-Z dump-mono-stats`. +The default is markdown; currently JSON is also supported. JSON can be useful for programatically manipulating the results (e.g. to find the item that took the longest to compile). diff --git a/src/doc/unstable-book/src/compiler-flags/dump-mono-stats.md b/src/doc/unstable-book/src/compiler-flags/dump-mono-stats.md new file mode 100644 index 000000000..4c8bc8b45 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/dump-mono-stats.md @@ -0,0 +1,14 @@ +# `dump-mono-stats` + +-------------------- + +The `-Z dump-mono-stats` compiler flag generates a file with a list of the monomorphized items in the current crate. +It is useful for investigating compile times. + +It accepts an optional directory where the file will be located. If no directory is specified, the file will be placed in the current directory. + +See also `-Z dump-mono-stats-format` and `-Z print-mono-items`. Unlike `print-mono-items`, +`dump-mono-stats` aggregates monomorphized items by definition and includes a size estimate of how +large the item is when codegened. + +See <https://rustc-dev-guide.rust-lang.org/backend/monomorph.html> for an overview of monomorphized items. diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index b33405f18..70c3a445b 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -14,6 +14,9 @@ This feature allows for use of one of following sanitizers: forward-edge control flow protection. * [HWAddressSanitizer](#hwaddresssanitizer) a memory error detector similar to AddressSanitizer, but based on partial hardware assistance. +* [KernelControlFlowIntegrity](#kernelcontrolflowintegrity) LLVM Kernel Control + Flow Integrity (KCFI) provides forward-edge control flow protection for + operating systems kernels. * [LeakSanitizer](#leaksanitizer) a run-time memory leak detector. * [MemorySanitizer](#memorysanitizer) a detector of uninitialized reads. * [MemTagSanitizer](#memtagsanitizer) fast memory error detector based on @@ -47,10 +50,10 @@ with runtime flag `ASAN_OPTIONS=detect_leaks=1` on macOS. AddressSanitizer is supported on the following targets: * `aarch64-apple-darwin` -* `aarch64-fuchsia` +* `aarch64-unknown-fuchsia` * `aarch64-unknown-linux-gnu` * `x86_64-apple-darwin` -* `x86_64-fuchsia` +* `x86_64-unknown-fuchsia` * `x86_64-unknown-freebsd` * `x86_64-unknown-linux-gnu` @@ -417,8 +420,8 @@ flow using an indirect branch/call to a function with different return and parameter types than the return type expected and arguments intended/passed in the call/branch site, the execution is also terminated (see Fig. 9). -[rust-book-ch19-05]: https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html -[rust-book]: https://doc.rust-lang.org/book/title-page.html +[rust-book-ch19-05]: ../../book/ch19-05-advanced-functions-and-closures.html +[rust-book]: ../../book/title-page.html # HWAddressSanitizer @@ -502,6 +505,32 @@ Registers where the failure occurred (pc 0xaaaae0ae4a98): SUMMARY: HWAddressSanitizer: tag-mismatch (/.../main+0x54a94) ``` +# KernelControlFlowIntegrity + +The LLVM Kernel Control Flow Integrity (CFI) support to the Rust compiler +initially provides forward-edge control flow protection for operating systems +kernels for Rust-compiled code only by aggregating function pointers in groups +identified by their return and parameter types. (See [LLVM commit cff5bef "KCFI +sanitizer"](https://github.com/llvm/llvm-project/commit/cff5bef948c91e4919de8a5fb9765e0edc13f3de).) + +Forward-edge control flow protection for C or C++ and Rust -compiled code "mixed +binaries" (i.e., for when C or C++ and Rust -compiled code share the same +virtual address space) will be provided in later work by defining and using +compatible type identifiers (see Type metadata in the design document in the +tracking issue [#89653](https://github.com/rust-lang/rust/issues/89653)). + +LLVM KCFI can be enabled with `-Zsanitizer=kcfi`. + +LLVM KCFI is supported on the following targets: + +* `aarch64-linux-android` +* `aarch64-unknown-linux-gnu` +* `x86_64-linux-android` +* `x86_64-unknown-linux-gnu` + +See the [Clang KernelControlFlowIntegrity documentation][clang-kcfi] for more +details. + # LeakSanitizer LeakSanitizer is run-time memory leak detector. @@ -662,7 +691,7 @@ It is strongly recommended to combine sanitizers with recompiled and instrumented standard library, for example using [cargo `-Zbuild-std` functionality][build-std]. -[build-std]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std +[build-std]: ../../cargo/reference/unstable.html#build-std # Build scripts and procedural macros @@ -693,6 +722,7 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT [clang-asan]: https://clang.llvm.org/docs/AddressSanitizer.html [clang-cfi]: https://clang.llvm.org/docs/ControlFlowIntegrity.html [clang-hwasan]: https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html +[clang-kcfi]: https://clang.llvm.org/docs/ControlFlowIntegrity.html#fsanitize-kcfi [clang-lsan]: https://clang.llvm.org/docs/LeakSanitizer.html [clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html [clang-scs]: https://clang.llvm.org/docs/ShadowCallStack.html diff --git a/src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md b/src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md index c6516d838..5cb975840 100644 --- a/src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md +++ b/src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md @@ -36,4 +36,4 @@ optimized out, if unused. However, with `make_foo` you can produce a wrapped to inlining of `f`, `Foo::foo` can then be called from a foreign crate. This can lead to miscompilations. -[Clto]: https://doc.rust-lang.org/rustc/codegen-options/index.html#lto +[Clto]: ../../rustc/codegen-options/index.html#lto diff --git a/src/doc/unstable-book/src/language-features/abi-efiapi.md b/src/doc/unstable-book/src/language-features/abi-efiapi.md deleted file mode 100644 index b492da884..000000000 --- a/src/doc/unstable-book/src/language-features/abi-efiapi.md +++ /dev/null @@ -1,23 +0,0 @@ -# `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/auto-traits.md b/src/doc/unstable-book/src/language-features/auto-traits.md index f967c11fc..014e15d1a 100644 --- a/src/doc/unstable-book/src/language-features/auto-traits.md +++ b/src/doc/unstable-book/src/language-features/auto-traits.md @@ -13,8 +13,8 @@ that are automatically implemented for every type, unless the type, or a type it has explicitly opted out via a negative impl. (Negative impls are separately controlled by the `negative_impls` feature.) -[`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html -[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html +[`Send`]: ../../std/marker/trait.Send.html +[`Sync`]: ../../std/marker/trait.Sync.html ```rust,ignore (partial-example) impl !Trait for Type {} diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 56fe9a31b..dfbb468d4 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -33,7 +33,7 @@ of a library. Plugins can extend [Rust's lint infrastructure](../../reference/attributes/diagnostics.md#lint-check-attributes) with additional checks for code style, safety, etc. Now let's write a plugin -[`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs) +[`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/tests/ui-fulldeps/auxiliary/lint-plugin-test.rs) that warns about any item named `lintme`. ```rust,ignore (requires-stage-2) diff --git a/src/doc/unstable-book/src/language-features/unboxed-closures.md b/src/doc/unstable-book/src/language-features/unboxed-closures.md index e4113d72d..3609e7f52 100644 --- a/src/doc/unstable-book/src/language-features/unboxed-closures.md +++ b/src/doc/unstable-book/src/language-features/unboxed-closures.md @@ -12,7 +12,7 @@ The `unboxed_closures` feature allows you to write functions using the `"rust-ca required for implementing the [`Fn*`] family of traits. `"rust-call"` functions must have exactly one (non self) argument, a tuple representing the argument list. -[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[`Fn*`]: ../../std/ops/trait.Fn.html ```rust #![feature(unboxed_closures)] diff --git a/src/doc/unstable-book/src/library-features/default-free-fn.md b/src/doc/unstable-book/src/library-features/default-free-fn.md index d40a27ddd..bafc9ac4d 100644 --- a/src/doc/unstable-book/src/library-features/default-free-fn.md +++ b/src/doc/unstable-book/src/library-features/default-free-fn.md @@ -10,7 +10,7 @@ Adds a free `default()` function to the `std::default` module. This function just forwards to [`Default::default()`], but may remove repetition of the word "default" from the call site. -[`Default::default()`]: https://doc.rust-lang.org/nightly/std/default/trait.Default.html#tymethod.default +[`Default::default()`]: ../../std/default/trait.Default.html#tymethod.default Here is an example: diff --git a/src/doc/unstable-book/src/library-features/fn-traits.md b/src/doc/unstable-book/src/library-features/fn-traits.md index 29a8aecee..180184146 100644 --- a/src/doc/unstable-book/src/library-features/fn-traits.md +++ b/src/doc/unstable-book/src/library-features/fn-traits.md @@ -11,7 +11,7 @@ See Also: [`unboxed_closures`](../language-features/unboxed-closures.md) The `fn_traits` feature allows for implementation of the [`Fn*`] traits for creating custom closure-like types. -[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[`Fn*`]: ../../std/ops/trait.Fn.html ```rust #![feature(unboxed_closures)] |