Question: // option. This file may not be copied, modified, or distributed // except according to those terms. <ins> #[doc(keyword = "as")] // /// The type coercion keyword. /// /// `as` is most commonly used to turn primitive types into other primitive types, but it has other /// uses that include turning pointers into addresses, addresses into pointers, and pointers into /// other pointers. /// /// ```rust /// let thing1: u8 = 89.0 as u8; /// assert_eq!('B' as u32, 66); /// assert_eq!(thing1 as char, 'Y'); /// let thing2: f32 = thing1 as f32 + 10.5; /// assert_eq!(true as u8 + thing2 as u8, 100); /// ``` /// /// In general, any coercion that can be performed via writing out type hints can also be done /// using `as`, so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (Note: /// `let x = 123u32` would be best in that situation). The same is not true in the other direction, /// however, explicitly using `as` allows a few more coercions that aren't allowed implicitly, such /// as changing the type of a raw pointer or turning closures into raw pointers. /// /// For more information on what `as` is capable of, see the [Reference] /// /// [Reference]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions mod as_keyword { } #[doc(keyword = "const")] // /// The keyword for defining constants. /// /// Sometimes a certain value is used many times throughout a program, and it can become /// inconvenient to copy it over and over. What's more, it's not always possible or desirable to /// make it a variable that gets carried around to each function that needs it. In these cases, the /// `const` keyword provides a convenient alternative to code duplication. /// /// ```rust /// const THING: u32 = 0xABAD1DEA; /// /// let foo = 123 + THING; /// ``` /// /// Constants must be explicitly typed, unlike with `let` you can't ignore its type and let the /// compiler figure it out. Any constant value can be defined in a const, which in practice happens /// to be most things that would be reasonable to have a constant. For example, you can't have a /// File as a `const`. /// /// The only lifetime allowed in a constant is 'static, which is the lifetime that encompasses all /// others in a Rust program. For example, if you wanted to define a constant string, it would look /// like this: /// /// ```rust /// const WORDS: &'static str = "hello rust!"; /// ``` /// /// Thanks to static lifetime elision, you usually don't have to explicitly use 'static: /// /// ```rust /// const WORDS: &str = "hello convenience!"; /// ``` /// /// `const` items looks remarkably similar to [`static`] items, which introduces some confusion as /// to which one should be used at which times. To put it simply, constants are inlined wherever /// they're used, making using them identical to simply replacing the name of the const with its /// value. Static variables on the other hand point to a single location in memory, which all /// accesses share. This means that, unlike with constants, they can't have destructors, but it /// also means that (via unsafe code) they can be mutable, which is useful for the rare situations /// in which you can't avoid using global state. /// /// Constants, as with statics, should always be in SCREAMING_SNAKE_CASE. /// /// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const /// T` and `*mut T`. More about that can be read at the [pointer] primitive part of the Rust docs. /// /// For more detail on `const`, see the [Rust Book] or the [Reference] /// /// [`static`]: keyword.static.html /// [pointer]: primitive.pointer.html /// [Rust Book]: https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants /// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html mod const_keyword { } #[doc(keyword = "crate")] // /// The `crate` keyword. /// /// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are /// used to specify a dependency on a crate external to the one it's declared in. Crates are the /// fundamental compilation unit of Rust code, and can be seen as libraries or projects. More can /// be read about crates in the [Reference]. /// /// ```rust ignore /// extern crate rand; /// extern crate my_crate as thing; /// extern crate std; // implicitly added to the root of every Rust project /// ``` /// /// The `as` keyword can be used to change what the crate is referred to as in your project. If a /// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores. /// /// `crate` is also used as in conjunction with [`pub`] to signify that the item it's attached to /// is public only to other members of the same crate it's in. /// /// ```rust /// # #[allow(unused_imports)] /// pub(crate) use std::io::Error as IoError; /// pub(crate) enum CoolMarkerType { } /// pub struct PublicThing { ///     pub(crate) semi_secret_thing: bool, /// } /// ``` /// /// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html /// [`pub`]: keyword.pub.html mod crate_keyword { } #[doc(keyword = "enum")] // /// For defining enumerations. /// /// Enums in Rust are similar to those of other compiled languages like C, but have important /// differences that make them considerably more powerful. What Rust calls enums are more commonly /// known as Algebraic Data Types if you're coming from a functional programming background, but /// the important part is that data can go with the enum variants. /// /// ```rust /// # struct Coord; /// enum SimpleEnum { ///     FirstVariant, ///     SecondVariant, ///     ThirdVariant, /// } /// /// enum Location { ///     Unknown, ///     Anonymous, ///     Known(Coord), /// } /// /// enum ComplexEnum { ///     Nothing, ///     Something(u32), ///     LotsOfThings { ///         usual_struct_stuff: bool, ///         blah: String, ///     } /// } /// /// enum EmptyEnum { } /// ``` /// /// The first enum shown is the usual kind of enum you'd find in a C-style language. The second /// shows off a hypothetical example of something storing location data, with Coord being any other /// type that's needed, for example a struct. The third example demonstrates the kind of variant a /// variant can store, ranging from nothing, to a tuple, to an anonymous struct. /// /// Instantiating enum variants involves explicitly using the enum's name as its namespace, /// followed by one of its variants. `SimpleEnum::SecondVariant` would be an example from above. /// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data /// is added as the type describes, for example `Option::Some(123)`. The same follows with /// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff: /// true, blah: "hello!".to_string(), }`. Empty Enums are similar to () in that they cannot be /// instantiated at all, and are used mainly to mess with the type system in interesting ways. /// /// For more information, take a look at the [Rust Book] or the [Reference] /// /// [`Option`]: option/enum.Option.html /// [Rust Book]: https://doc.rust-lang.org/book/second-edition/ch06-01-defining-an-enum.html /// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html mod enum_keyword { } #[doc(keyword = "extern")] // /// For external connections in Rust code. /// /// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`] /// keyword to make your Rust code aware of other Rust crates in your project, i.e. `extern crate /// lazy_static;`. The other use is in foreign function interfaces (FFI). /// /// `extern` is used in two different contexts within FFI. The first is in the form of external /// blcoks, for declaring function interfaces that Rust code can call foreign code by. /// /// ```rust ignore /// #[link(name = "my_c_library")] /// extern "C" { ///     fn my_c_function(x: i32) -> bool; /// } /// ``` /// /// This code would attempt to link with libmy_c_library.so on unix-like systems and /// my_c_library.dll on Windows at runtime, and panic if it can't find something to link to. Rust /// code could then use `my_c_function` as if it were any other unsafe Rust function. Working with /// non-Rust languages and FFI is inherently unsafe, so wrappers are usually built around C APIs. /// /// The mirror use case of FFI is also done via the `extern` keyword: /// /// ```rust /// # #![allow(private_no_mangle_fns)] /// #[no_mangle] /// pub extern fn callable_from_c(x: i32) -> bool { ///     x % 3 == 0 /// } /// ``` /// /// If compiled as a dylib, the resulting .so could then be linked to from a C library, and the /// function could be used as if it was from any other library. /// /// For more information on FFI, check the [Rust book] or the [Reference]. /// /// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code /// [Reference]: https://doc.rust-lang.org/reference/items/external-blocks.html mod extern_keyword { } </ins> #[doc(keyword = "fn")] // <del> /// The `fn` keyword. </del> <ins> /// The keyword for defining functions. </ins> /// <del> /// The `fn` keyword is used to declare a function. </del> <ins> /// Functions are the primary way code is executed within Rust. Function blocks, usually just /// called functions, can be defined in a variety of different places and be assigned many /// different attributes and modifiers. </ins> /// <del> /// Example: </del> <ins> /// Standalone functions that just sit within a module not attached to anything else are common, /// but most functions will end up being inside [`impl`] blocks, either on another type itself, or /// as a trait impl for that type. </ins> /// /// ```rust <del> /// fn some_function() { ///     // code goes in here </del> <ins> /// fn standalone_function() { ///     // code /// } /// /// pub fn public_thing(argument: bool) -> String { ///     // code ///     # "".to_string() /// } /// /// struct Thing { ///     foo: i32, /// } /// /// impl Thing { ///     pub fn new() -> Self { ///         Self { ///             foo: 42, ///         } ///     } </ins> /// } /// ``` /// <del> /// For more information about functions, take a look at the [Rust Book][book]. </del> <ins> /// See docs on [`impl`] and [`self`] for relevant details on those. /// /// In addition to presenting fixed types in the form of `fn name(arg: type, ..) -> return_type`, /// functions can also declare a list of type parameters along with trait bounds that they fall /// into. /// /// ```rust /// fn generic_function<T: Clone>(x: T) -> (T, T, T) { ///     (x.clone(), x.clone(), x.clone()) /// } </ins> /// <del> /// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html </del> <ins> /// fn generic_where<T>(x: T) -> T ///     where T: std::ops::Add<Output=T> + Copy /// { ///     x + x + x /// } /// ``` /// /// Declaring trait bounds in the angle brackets is functionally identical to using a [`where`] /// clause, but `where` is preferred due to it being easier to understand at a glance. /// /// Along with being made public via [`pub`], `fn` can also have an [`extern`] added for use in /// FFI. /// /// For more information on the various types of functions and how they're used, consult the [Rust /// book] or the [Reference]. /// /// [`impl`]: keyword.impl.html /// [`self`]: keyword.self.html /// [`where`]: keyword.where.html /// [`pub`]: keyword.pub.html /// [`extern`]: keyword.extern.html /// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html /// [Reference]: https://doc.rust-lang.org/reference/items/functions.html </ins> mod fn_keyword { } <ins> #[doc(keyword = "for")] // /// The `for` keyword. /// /// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic uses such as /// `impl Trait for Type` (see [`impl`] for more info on that). for-in-loops, or to be more /// precise, iterator loops, are a simple syntactic sugar over an exceedingly common practice /// within Rust, which is to loop over an iterator until that iterator returns None (or [`break`] /// is called). /// /// ```rust /// for i in 0..5 { ///     println!("{}", i * 2); /// } /// /// for i in std::iter::repeat(5) { ///     println!("turns out {} never stops being 5", i); ///     break; // would loop forever otherwise /// } /// /// 'outer: for x in 5..50 { ///     for y in 0..10 { ///         if x == y { ///             break 'outer; ///         } ///     } /// } /// ``` /// /// As shown in the example above, `for` loops (along with all other loops) can be tagged, using /// similar syntax to lifetimes (only visually similar, entirely distinct in practice). Giving the /// same tag to `break` breaks the tagged loop, which is useful for inner loops. It is definitely /// not a goto. /// /// A `for` loop expands as shown: /// /// ```rust /// # fn code() { } /// # let iterator = 0..2; /// for loop_variable in iterator { ///     code() /// } /// ``` /// /// ```rust /// # fn code() { } /// # let iterator = 0..2; /// { ///     let mut _iter = std::iter::IntoIterator::into_iter(iterator); ///     loop { ///         match _iter.next() { ///             Some(loop_variable) => { ///                 code() ///             }, ///             None => break, ///         } ///     } /// } /// ``` /// /// More details on the functionality shown can be seen at the [`IntoIterator`] docs. /// /// For more information on for-loops, see the [Rust book] or the [Reference]. /// /// [`impl`]: keyword.impl.html /// [`break`]: keyword.break.html /// [`IntoIterator`]: iter/trait.IntoIterator.html /// [Rust book]: https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for /// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops mod for_keyword { } #[doc(keyword = "if")] // /// If statements and expressions. /// /// `if` is a familiar construct to most programmers, and is the main way you'll often do logic in /// your code. However, unlike in most languages, `if` blocks can also act as expressions. /// /// ```rust /// # let rude = true; /// if 1 == 2 { ///     println!("whoops, mathematics broke"); /// } else { ///     println!("everything's fine!"); /// } /// /// let greeting = if rude { ///     "sup nerd." /// } else { ///     "hello, friend!" /// }; /// /// if let Ok(x) = "123".parse::<i32>() { ///     println!("{} double that and you get {}!", greeting, x * 2); /// } /// ``` /// /// Shown above are the three typical forms an `if` block comes in. First is the usual kind of /// thing you'd see in many languages, with an optional `else` block. Second uses `if` as an /// expression, which is only possible if all branches return the same type. An `if` expression can /// be used everywhere you'd expect. The third kind of `if` block is an `if let` block, which /// behaves similarly to using a [`match`] expression: /// /// ```rust /// if let Some(x) = Some(123) { ///     // code ///     # let _ = x; /// } else { ///     // something else /// } /// /// match Some(123) { ///     Some(x) => { ///         // code ///         # let _ = x; ///     }, ///     _ => { ///         // something else ///     }, /// } /// ``` /// /// See [`let`] for more information on pattern bindings. /// /// Each kind of `if` expression can be mixed and matched as needed. /// /// ```rust /// if true == false { ///     println!("oh no"); /// } else if "something" == "other thing" { ///     println!("oh dear"); /// } else if let Some(200) = "blarg".parse::<i32>().ok() { ///     println!("uh oh"); /// } else { ///     println!("phew, nothing's broken"); /// } /// ``` /// /// The `if` keyword is used in one other place in Rust, namely as a part of pattern matching /// itself, allowing patterns such as `Some(x) if x > 200` to be used. /// /// For more information on `if` expressions, see the [Rust book] or the [Reference]. /// /// [`match`]: keyword.match.html /// [`let`]: keyword.let.html /// [Rust book]: https://doc.rust-lang.org/stable/book/2018-edition/ch03-05-control-flow.html#if-expressions /// [Reference]: https://doc.rust-lang.org/reference/expressions/if-expr.html mod if_keyword { } </ins> #[doc(keyword = "let")] // /// The `let` keyword.

Consider the following code (): It currently yields the following diagnostic messages: This line is what I object to: It has two problems: It uses the terminology when discussing building up an instance of the struct . It uses a tuple struct form in the example rewrite it provides; but our is a braced struct with named fields.
Is GitHub suffering from some kind of cache-consistency problem!? (I guess so: they're investigating service unavailability.) I apparently-successfully opened PR to fix this, but then it wasn't showing up in the and the pull/ URL was 404ing, so then I thought that it might not have actually gone through, so then I tried to resubmit, and then that failed with an "A pull request already exists" flash message, and then I wanted to try submitting under a different branch name, and/or rebased so as to have a different SHA (on the theory that maybe the problem had something to do with the fact that I was reusing the branch name from the my PR of last year in which the "variant of the expected type" message was introduced, even though it would be really surprising if a site as old and usually-stable as GitHub didn't already handle that case), but then the "Compare branches" pages aren't showing the open-pull-request form that they usually do. Typically I wouldn't even bother commenting about this kind of glitch (trusting that our friends at GitHub will sort it out any mere availability issue soon enough), but the fact that other PR pages are loading fine for me makes me wonder if there's some kind of bad state associated with in particular?!
Is GitHub suffering from some kind of cache-consistency problem!? (I guess so: they're investigating service unavailability.)


Question: // option. This file may not be copied, modified, or distributed // except according to those terms. <ins> #[doc(keyword = "as")] // /// The type coercion keyword. /// /// `as` is most commonly used to turn primitive types into other primitive types, but it has other /// uses that include turning pointers into addresses, addresses into pointers, and pointers into /// other pointers. /// /// ```rust /// let thing1: u8 = 89.0 as u8; /// assert_eq!('B' as u32, 66); /// assert_eq!(thing1 as char, 'Y'); /// let thing2: f32 = thing1 as f32 + 10.5; /// assert_eq!(true as u8 + thing2 as u8, 100); /// ``` /// /// In general, any coercion that can be performed via writing out type hints can also be done /// using `as`, so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (Note: /// `let x = 123u32` would be best in that situation). The same is not true in the other direction, /// however, explicitly using `as` allows a few more coercions that aren't allowed implicitly, such /// as changing the type of a raw pointer or turning closures into raw pointers. /// /// For more information on what `as` is capable of, see the [Reference] /// /// [Reference]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions mod as_keyword { } #[doc(keyword = "const")] // /// The keyword for defining constants. /// /// Sometimes a certain value is used many times throughout a program, and it can become /// inconvenient to copy it over and over. What's more, it's not always possible or desirable to /// make it a variable that gets carried around to each function that needs it. In these cases, the /// `const` keyword provides a convenient alternative to code duplication. /// /// ```rust /// const THING: u32 = 0xABAD1DEA; /// /// let foo = 123 + THING; /// ``` /// /// Constants must be explicitly typed, unlike with `let` you can't ignore its type and let the /// compiler figure it out. Any constant value can be defined in a const, which in practice happens /// to be most things that would be reasonable to have a constant. For example, you can't have a /// File as a `const`. /// /// The only lifetime allowed in a constant is 'static, which is the lifetime that encompasses all /// others in a Rust program. For example, if you wanted to define a constant string, it would look /// like this: /// /// ```rust /// const WORDS: &'static str = "hello rust!"; /// ``` /// /// Thanks to static lifetime elision, you usually don't have to explicitly use 'static: /// /// ```rust /// const WORDS: &str = "hello convenience!"; /// ``` /// /// `const` items looks remarkably similar to [`static`] items, which introduces some confusion as /// to which one should be used at which times. To put it simply, constants are inlined wherever /// they're used, making using them identical to simply replacing the name of the const with its /// value. Static variables on the other hand point to a single location in memory, which all /// accesses share. This means that, unlike with constants, they can't have destructors, but it /// also means that (via unsafe code) they can be mutable, which is useful for the rare situations /// in which you can't avoid using global state. /// /// Constants, as with statics, should always be in SCREAMING_SNAKE_CASE. /// /// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const /// T` and `*mut T`. More about that can be read at the [pointer] primitive part of the Rust docs. /// /// For more detail on `const`, see the [Rust Book] or the [Reference] /// /// [`static`]: keyword.static.html /// [pointer]: primitive.pointer.html /// [Rust Book]: https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants /// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html mod const_keyword { } #[doc(keyword = "crate")] // /// The `crate` keyword. /// /// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are /// used to specify a dependency on a crate external to the one it's declared in. Crates are the /// fundamental compilation unit of Rust code, and can be seen as libraries or projects. More can /// be read about crates in the [Reference]. /// /// ```rust ignore /// extern crate rand; /// extern crate my_crate as thing; /// extern crate std; // implicitly added to the root of every Rust project /// ``` /// /// The `as` keyword can be used to change what the crate is referred to as in your project. If a /// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores. /// /// `crate` is also used as in conjunction with [`pub`] to signify that the item it's attached to /// is public only to other members of the same crate it's in. /// /// ```rust /// # #[allow(unused_imports)] /// pub(crate) use std::io::Error as IoError; /// pub(crate) enum CoolMarkerType { } /// pub struct PublicThing { ///     pub(crate) semi_secret_thing: bool, /// } /// ``` /// /// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html /// [`pub`]: keyword.pub.html mod crate_keyword { } #[doc(keyword = "enum")] // /// For defining enumerations. /// /// Enums in Rust are similar to those of other compiled languages like C, but have important /// differences that make them considerably more powerful. What Rust calls enums are more commonly /// known as Algebraic Data Types if you're coming from a functional programming background, but /// the important part is that data can go with the enum variants. /// /// ```rust /// # struct Coord; /// enum SimpleEnum { ///     FirstVariant, ///     SecondVariant, ///     ThirdVariant, /// } /// /// enum Location { ///     Unknown, ///     Anonymous, ///     Known(Coord), /// } /// /// enum ComplexEnum { ///     Nothing, ///     Something(u32), ///     LotsOfThings { ///         usual_struct_stuff: bool, ///         blah: String, ///     } /// } /// /// enum EmptyEnum { } /// ``` /// /// The first enum shown is the usual kind of enum you'd find in a C-style language. The second /// shows off a hypothetical example of something storing location data, with Coord being any other /// type that's needed, for example a struct. The third example demonstrates the kind of variant a /// variant can store, ranging from nothing, to a tuple, to an anonymous struct. /// /// Instantiating enum variants involves explicitly using the enum's name as its namespace, /// followed by one of its variants. `SimpleEnum::SecondVariant` would be an example from above. /// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data /// is added as the type describes, for example `Option::Some(123)`. The same follows with /// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff: /// true, blah: "hello!".to_string(), }`. Empty Enums are similar to () in that they cannot be /// instantiated at all, and are used mainly to mess with the type system in interesting ways. /// /// For more information, take a look at the [Rust Book] or the [Reference] /// /// [`Option`]: option/enum.Option.html /// [Rust Book]: https://doc.rust-lang.org/book/second-edition/ch06-01-defining-an-enum.html /// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html mod enum_keyword { } #[doc(keyword = "extern")] // /// For external connections in Rust code. /// /// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`] /// keyword to make your Rust code aware of other Rust crates in your project, i.e. `extern crate /// lazy_static;`. The other use is in foreign function interfaces (FFI). /// /// `extern` is used in two different contexts within FFI. The first is in the form of external /// blcoks, for declaring function interfaces that Rust code can call foreign code by. /// /// ```rust ignore /// #[link(name = "my_c_library")] /// extern "C" { ///     fn my_c_function(x: i32) -> bool; /// } /// ``` /// /// This code would attempt to link with libmy_c_library.so on unix-like systems and /// my_c_library.dll on Windows at runtime, and panic if it can't find something to link to. Rust /// code could then use `my_c_function` as if it were any other unsafe Rust function. Working with /// non-Rust languages and FFI is inherently unsafe, so wrappers are usually built around C APIs. /// /// The mirror use case of FFI is also done via the `extern` keyword: /// /// ```rust /// # #![allow(private_no_mangle_fns)] /// #[no_mangle] /// pub extern fn callable_from_c(x: i32) -> bool { ///     x % 3 == 0 /// } /// ``` /// /// If compiled as a dylib, the resulting .so could then be linked to from a C library, and the /// function could be used as if it was from any other library. /// /// For more information on FFI, check the [Rust book] or the [Reference]. /// /// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code /// [Reference]: https://doc.rust-lang.org/reference/items/external-blocks.html mod extern_keyword { } </ins> #[doc(keyword = "fn")] // <del> /// The `fn` keyword. </del> <ins> /// The keyword for defining functions. </ins> /// <del> /// The `fn` keyword is used to declare a function. </del> <ins> /// Functions are the primary way code is executed within Rust. Function blocks, usually just /// called functions, can be defined in a variety of different places and be assigned many /// different attributes and modifiers. </ins> /// <del> /// Example: </del> <ins> /// Standalone functions that just sit within a module not attached to anything else are common, /// but most functions will end up being inside [`impl`] blocks, either on another type itself, or /// as a trait impl for that type. </ins> /// /// ```rust <del> /// fn some_function() { ///     // code goes in here </del> <ins> /// fn standalone_function() { ///     // code /// } /// /// pub fn public_thing(argument: bool) -> String { ///     // code ///     # "".to_string() /// } /// /// struct Thing { ///     foo: i32, /// } /// /// impl Thing { ///     pub fn new() -> Self { ///         Self { ///             foo: 42, ///         } ///     } </ins> /// } /// ``` /// <del> /// For more information about functions, take a look at the [Rust Book][book]. </del> <ins> /// See docs on [`impl`] and [`self`] for relevant details on those. /// /// In addition to presenting fixed types in the form of `fn name(arg: type, ..) -> return_type`, /// functions can also declare a list of type parameters along with trait bounds that they fall /// into. /// /// ```rust /// fn generic_function<T: Clone>(x: T) -> (T, T, T) { ///     (x.clone(), x.clone(), x.clone()) /// } </ins> /// <del> /// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html </del> <ins> /// fn generic_where<T>(x: T) -> T ///     where T: std::ops::Add<Output=T> + Copy /// { ///     x + x + x /// } /// ``` /// /// Declaring trait bounds in the angle brackets is functionally identical to using a [`where`] /// clause, but `where` is preferred due to it being easier to understand at a glance. /// /// Along with being made public via [`pub`], `fn` can also have an [`extern`] added for use in /// FFI. /// /// For more information on the various types of functions and how they're used, consult the [Rust /// book] or the [Reference]. /// /// [`impl`]: keyword.impl.html /// [`self`]: keyword.self.html /// [`where`]: keyword.where.html /// [`pub`]: keyword.pub.html /// [`extern`]: keyword.extern.html /// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html /// [Reference]: https://doc.rust-lang.org/reference/items/functions.html </ins> mod fn_keyword { } <ins> #[doc(keyword = "for")] // /// The `for` keyword. /// /// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic uses such as /// `impl Trait for Type` (see [`impl`] for more info on that). for-in-loops, or to be more /// precise, iterator loops, are a simple syntactic sugar over an exceedingly common practice /// within Rust, which is to loop over an iterator until that iterator returns None (or [`break`] /// is called). /// /// ```rust /// for i in 0..5 { ///     println!("{}", i * 2); /// } /// /// for i in std::iter::repeat(5) { ///     println!("turns out {} never stops being 5", i); ///     break; // would loop forever otherwise /// } /// /// 'outer: for x in 5..50 { ///     for y in 0..10 { ///         if x == y { ///             break 'outer; ///         } ///     } /// } /// ``` /// /// As shown in the example above, `for` loops (along with all other loops) can be tagged, using /// similar syntax to lifetimes (only visually similar, entirely distinct in practice). Giving the /// same tag to `break` breaks the tagged loop, which is useful for inner loops. It is definitely /// not a goto. /// /// A `for` loop expands as shown: /// /// ```rust /// # fn code() { } /// # let iterator = 0..2; /// for loop_variable in iterator { ///     code() /// } /// ``` /// /// ```rust /// # fn code() { } /// # let iterator = 0..2; /// { ///     let mut _iter = std::iter::IntoIterator::into_iter(iterator); ///     loop { ///         match _iter.next() { ///             Some(loop_variable) => { ///                 code() ///             }, ///             None => break, ///         } ///     } /// } /// ``` /// /// More details on the functionality shown can be seen at the [`IntoIterator`] docs. /// /// For more information on for-loops, see the [Rust book] or the [Reference]. /// /// [`impl`]: keyword.impl.html /// [`break`]: keyword.break.html /// [`IntoIterator`]: iter/trait.IntoIterator.html /// [Rust book]: https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for /// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops mod for_keyword { } #[doc(keyword = "if")] // /// If statements and expressions. /// /// `if` is a familiar construct to most programmers, and is the main way you'll often do logic in /// your code. However, unlike in most languages, `if` blocks can also act as expressions. /// /// ```rust /// # let rude = true; /// if 1 == 2 { ///     println!("whoops, mathematics broke"); /// } else { ///     println!("everything's fine!"); /// } /// /// let greeting = if rude { ///     "sup nerd." /// } else { ///     "hello, friend!" /// }; /// /// if let Ok(x) = "123".parse::<i32>() { ///     println!("{} double that and you get {}!", greeting, x * 2); /// } /// ``` /// /// Shown above are the three typical forms an `if` block comes in. First is the usual kind of /// thing you'd see in many languages, with an optional `else` block. Second uses `if` as an /// expression, which is only possible if all branches return the same type. An `if` expression can /// be used everywhere you'd expect. The third kind of `if` block is an `if let` block, which /// behaves similarly to using a [`match`] expression: /// /// ```rust /// if let Some(x) = Some(123) { ///     // code ///     # let _ = x; /// } else { ///     // something else /// } /// /// match Some(123) { ///     Some(x) => { ///         // code ///         # let _ = x; ///     }, ///     _ => { ///         // something else ///     }, /// } /// ``` /// /// See [`let`] for more information on pattern bindings. /// /// Each kind of `if` expression can be mixed and matched as needed. /// /// ```rust /// if true == false { ///     println!("oh no"); /// } else if "something" == "other thing" { ///     println!("oh dear"); /// } else if let Some(200) = "blarg".parse::<i32>().ok() { ///     println!("uh oh"); /// } else { ///     println!("phew, nothing's broken"); /// } /// ``` /// /// The `if` keyword is used in one other place in Rust, namely as a part of pattern matching /// itself, allowing patterns such as `Some(x) if x > 200` to be used. /// /// For more information on `if` expressions, see the [Rust book] or the [Reference]. /// /// [`match`]: keyword.match.html /// [`let`]: keyword.let.html /// [Rust book]: https://doc.rust-lang.org/stable/book/2018-edition/ch03-05-control-flow.html#if-expressions /// [Reference]: https://doc.rust-lang.org/reference/expressions/if-expr.html mod if_keyword { } </ins> #[doc(keyword = "let")] // /// The `let` keyword.

I apparently-successfully opened PR to fix this, but then it wasn't showing up in the and the pull/ URL was 404ing, so then I thought that it might not have actually gone through, so then I tried to resubmit, and then that failed with an "A pull request already exists" flash message, and then I wanted to try submitting under a different branch name, and/or rebased so as to have a different SHA (on the theory that maybe the problem had something to do with the fact that I was reusing the branch name from the my PR of last year in which the "variant of the expected type" message was introduced, even though it would be really surprising if a site as old and usually-stable as GitHub didn't already handle that case), but then the "Compare branches" pages aren't showing the open-pull-request form that they usually do. Typically I wouldn't even bother commenting about this kind of glitch (trusting that our friends at GitHub will sort it out any mere availability issue soon enough), but the fact that other PR pages are loading fine for me makes me wonder if there's some kind of bad state associated with in particular?!


Question: // option. This file may not be copied, modified, or distributed // except according to those terms. <ins> #[doc(keyword = "as")] // /// The type coercion keyword. /// /// `as` is most commonly used to turn primitive types into other primitive types, but it has other /// uses that include turning pointers into addresses, addresses into pointers, and pointers into /// other pointers. /// /// ```rust /// let thing1: u8 = 89.0 as u8; /// assert_eq!('B' as u32, 66); /// assert_eq!(thing1 as char, 'Y'); /// let thing2: f32 = thing1 as f32 + 10.5; /// assert_eq!(true as u8 + thing2 as u8, 100); /// ``` /// /// In general, any coercion that can be performed via writing out type hints can also be done /// using `as`, so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (Note: /// `let x = 123u32` would be best in that situation). The same is not true in the other direction, /// however, explicitly using `as` allows a few more coercions that aren't allowed implicitly, such /// as changing the type of a raw pointer or turning closures into raw pointers. /// /// For more information on what `as` is capable of, see the [Reference] /// /// [Reference]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions mod as_keyword { } #[doc(keyword = "const")] // /// The keyword for defining constants. /// /// Sometimes a certain value is used many times throughout a program, and it can become /// inconvenient to copy it over and over. What's more, it's not always possible or desirable to /// make it a variable that gets carried around to each function that needs it. In these cases, the /// `const` keyword provides a convenient alternative to code duplication. /// /// ```rust /// const THING: u32 = 0xABAD1DEA; /// /// let foo = 123 + THING; /// ``` /// /// Constants must be explicitly typed, unlike with `let` you can't ignore its type and let the /// compiler figure it out. Any constant value can be defined in a const, which in practice happens /// to be most things that would be reasonable to have a constant. For example, you can't have a /// File as a `const`. /// /// The only lifetime allowed in a constant is 'static, which is the lifetime that encompasses all /// others in a Rust program. For example, if you wanted to define a constant string, it would look /// like this: /// /// ```rust /// const WORDS: &'static str = "hello rust!"; /// ``` /// /// Thanks to static lifetime elision, you usually don't have to explicitly use 'static: /// /// ```rust /// const WORDS: &str = "hello convenience!"; /// ``` /// /// `const` items looks remarkably similar to [`static`] items, which introduces some confusion as /// to which one should be used at which times. To put it simply, constants are inlined wherever /// they're used, making using them identical to simply replacing the name of the const with its /// value. Static variables on the other hand point to a single location in memory, which all /// accesses share. This means that, unlike with constants, they can't have destructors, but it /// also means that (via unsafe code) they can be mutable, which is useful for the rare situations /// in which you can't avoid using global state. /// /// Constants, as with statics, should always be in SCREAMING_SNAKE_CASE. /// /// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const /// T` and `*mut T`. More about that can be read at the [pointer] primitive part of the Rust docs. /// /// For more detail on `const`, see the [Rust Book] or the [Reference] /// /// [`static`]: keyword.static.html /// [pointer]: primitive.pointer.html /// [Rust Book]: https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants /// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html mod const_keyword { } #[doc(keyword = "crate")] // /// The `crate` keyword. /// /// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are /// used to specify a dependency on a crate external to the one it's declared in. Crates are the /// fundamental compilation unit of Rust code, and can be seen as libraries or projects. More can /// be read about crates in the [Reference]. /// /// ```rust ignore /// extern crate rand; /// extern crate my_crate as thing; /// extern crate std; // implicitly added to the root of every Rust project /// ``` /// /// The `as` keyword can be used to change what the crate is referred to as in your project. If a /// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores. /// /// `crate` is also used as in conjunction with [`pub`] to signify that the item it's attached to /// is public only to other members of the same crate it's in. /// /// ```rust /// # #[allow(unused_imports)] /// pub(crate) use std::io::Error as IoError; /// pub(crate) enum CoolMarkerType { } /// pub struct PublicThing { ///     pub(crate) semi_secret_thing: bool, /// } /// ``` /// /// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html /// [`pub`]: keyword.pub.html mod crate_keyword { } #[doc(keyword = "enum")] // /// For defining enumerations. /// /// Enums in Rust are similar to those of other compiled languages like C, but have important /// differences that make them considerably more powerful. What Rust calls enums are more commonly /// known as Algebraic Data Types if you're coming from a functional programming background, but /// the important part is that data can go with the enum variants. /// /// ```rust /// # struct Coord; /// enum SimpleEnum { ///     FirstVariant, ///     SecondVariant, ///     ThirdVariant, /// } /// /// enum Location { ///     Unknown, ///     Anonymous, ///     Known(Coord), /// } /// /// enum ComplexEnum { ///     Nothing, ///     Something(u32), ///     LotsOfThings { ///         usual_struct_stuff: bool, ///         blah: String, ///     } /// } /// /// enum EmptyEnum { } /// ``` /// /// The first enum shown is the usual kind of enum you'd find in a C-style language. The second /// shows off a hypothetical example of something storing location data, with Coord being any other /// type that's needed, for example a struct. The third example demonstrates the kind of variant a /// variant can store, ranging from nothing, to a tuple, to an anonymous struct. /// /// Instantiating enum variants involves explicitly using the enum's name as its namespace, /// followed by one of its variants. `SimpleEnum::SecondVariant` would be an example from above. /// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data /// is added as the type describes, for example `Option::Some(123)`. The same follows with /// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff: /// true, blah: "hello!".to_string(), }`. Empty Enums are similar to () in that they cannot be /// instantiated at all, and are used mainly to mess with the type system in interesting ways. /// /// For more information, take a look at the [Rust Book] or the [Reference] /// /// [`Option`]: option/enum.Option.html /// [Rust Book]: https://doc.rust-lang.org/book/second-edition/ch06-01-defining-an-enum.html /// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html mod enum_keyword { } #[doc(keyword = "extern")] // /// For external connections in Rust code. /// /// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`] /// keyword to make your Rust code aware of other Rust crates in your project, i.e. `extern crate /// lazy_static;`. The other use is in foreign function interfaces (FFI). /// /// `extern` is used in two different contexts within FFI. The first is in the form of external /// blcoks, for declaring function interfaces that Rust code can call foreign code by. /// /// ```rust ignore /// #[link(name = "my_c_library")] /// extern "C" { ///     fn my_c_function(x: i32) -> bool; /// } /// ``` /// /// This code would attempt to link with libmy_c_library.so on unix-like systems and /// my_c_library.dll on Windows at runtime, and panic if it can't find something to link to. Rust /// code could then use `my_c_function` as if it were any other unsafe Rust function. Working with /// non-Rust languages and FFI is inherently unsafe, so wrappers are usually built around C APIs. /// /// The mirror use case of FFI is also done via the `extern` keyword: /// /// ```rust /// # #![allow(private_no_mangle_fns)] /// #[no_mangle] /// pub extern fn callable_from_c(x: i32) -> bool { ///     x % 3 == 0 /// } /// ``` /// /// If compiled as a dylib, the resulting .so could then be linked to from a C library, and the /// function could be used as if it was from any other library. /// /// For more information on FFI, check the [Rust book] or the [Reference]. /// /// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code /// [Reference]: https://doc.rust-lang.org/reference/items/external-blocks.html mod extern_keyword { } </ins> #[doc(keyword = "fn")] // <del> /// The `fn` keyword. </del> <ins> /// The keyword for defining functions. </ins> /// <del> /// The `fn` keyword is used to declare a function. </del> <ins> /// Functions are the primary way code is executed within Rust. Function blocks, usually just /// called functions, can be defined in a variety of different places and be assigned many /// different attributes and modifiers. </ins> /// <del> /// Example: </del> <ins> /// Standalone functions that just sit within a module not attached to anything else are common, /// but most functions will end up being inside [`impl`] blocks, either on another type itself, or /// as a trait impl for that type. </ins> /// /// ```rust <del> /// fn some_function() { ///     // code goes in here </del> <ins> /// fn standalone_function() { ///     // code /// } /// /// pub fn public_thing(argument: bool) -> String { ///     // code ///     # "".to_string() /// } /// /// struct Thing { ///     foo: i32, /// } /// /// impl Thing { ///     pub fn new() -> Self { ///         Self { ///             foo: 42, ///         } ///     } </ins> /// } /// ``` /// <del> /// For more information about functions, take a look at the [Rust Book][book]. </del> <ins> /// See docs on [`impl`] and [`self`] for relevant details on those. /// /// In addition to presenting fixed types in the form of `fn name(arg: type, ..) -> return_type`, /// functions can also declare a list of type parameters along with trait bounds that they fall /// into. /// /// ```rust /// fn generic_function<T: Clone>(x: T) -> (T, T, T) { ///     (x.clone(), x.clone(), x.clone()) /// } </ins> /// <del> /// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html </del> <ins> /// fn generic_where<T>(x: T) -> T ///     where T: std::ops::Add<Output=T> + Copy /// { ///     x + x + x /// } /// ``` /// /// Declaring trait bounds in the angle brackets is functionally identical to using a [`where`] /// clause, but `where` is preferred due to it being easier to understand at a glance. /// /// Along with being made public via [`pub`], `fn` can also have an [`extern`] added for use in /// FFI. /// /// For more information on the various types of functions and how they're used, consult the [Rust /// book] or the [Reference]. /// /// [`impl`]: keyword.impl.html /// [`self`]: keyword.self.html /// [`where`]: keyword.where.html /// [`pub`]: keyword.pub.html /// [`extern`]: keyword.extern.html /// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html /// [Reference]: https://doc.rust-lang.org/reference/items/functions.html </ins> mod fn_keyword { } <ins> #[doc(keyword = "for")] // /// The `for` keyword. /// /// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic uses such as /// `impl Trait for Type` (see [`impl`] for more info on that). for-in-loops, or to be more /// precise, iterator loops, are a simple syntactic sugar over an exceedingly common practice /// within Rust, which is to loop over an iterator until that iterator returns None (or [`break`] /// is called). /// /// ```rust /// for i in 0..5 { ///     println!("{}", i * 2); /// } /// /// for i in std::iter::repeat(5) { ///     println!("turns out {} never stops being 5", i); ///     break; // would loop forever otherwise /// } /// /// 'outer: for x in 5..50 { ///     for y in 0..10 { ///         if x == y { ///             break 'outer; ///         } ///     } /// } /// ``` /// /// As shown in the example above, `for` loops (along with all other loops) can be tagged, using /// similar syntax to lifetimes (only visually similar, entirely distinct in practice). Giving the /// same tag to `break` breaks the tagged loop, which is useful for inner loops. It is definitely /// not a goto. /// /// A `for` loop expands as shown: /// /// ```rust /// # fn code() { } /// # let iterator = 0..2; /// for loop_variable in iterator { ///     code() /// } /// ``` /// /// ```rust /// # fn code() { } /// # let iterator = 0..2; /// { ///     let mut _iter = std::iter::IntoIterator::into_iter(iterator); ///     loop { ///         match _iter.next() { ///             Some(loop_variable) => { ///                 code() ///             }, ///             None => break, ///         } ///     } /// } /// ``` /// /// More details on the functionality shown can be seen at the [`IntoIterator`] docs. /// /// For more information on for-loops, see the [Rust book] or the [Reference]. /// /// [`impl`]: keyword.impl.html /// [`break`]: keyword.break.html /// [`IntoIterator`]: iter/trait.IntoIterator.html /// [Rust book]: https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for /// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops mod for_keyword { } #[doc(keyword = "if")] // /// If statements and expressions. /// /// `if` is a familiar construct to most programmers, and is the main way you'll often do logic in /// your code. However, unlike in most languages, `if` blocks can also act as expressions. /// /// ```rust /// # let rude = true; /// if 1 == 2 { ///     println!("whoops, mathematics broke"); /// } else { ///     println!("everything's fine!"); /// } /// /// let greeting = if rude { ///     "sup nerd." /// } else { ///     "hello, friend!" /// }; /// /// if let Ok(x) = "123".parse::<i32>() { ///     println!("{} double that and you get {}!", greeting, x * 2); /// } /// ``` /// /// Shown above are the three typical forms an `if` block comes in. First is the usual kind of /// thing you'd see in many languages, with an optional `else` block. Second uses `if` as an /// expression, which is only possible if all branches return the same type. An `if` expression can /// be used everywhere you'd expect. The third kind of `if` block is an `if let` block, which /// behaves similarly to using a [`match`] expression: /// /// ```rust /// if let Some(x) = Some(123) { ///     // code ///     # let _ = x; /// } else { ///     // something else /// } /// /// match Some(123) { ///     Some(x) => { ///         // code ///         # let _ = x; ///     }, ///     _ => { ///         // something else ///     }, /// } /// ``` /// /// See [`let`] for more information on pattern bindings. /// /// Each kind of `if` expression can be mixed and matched as needed. /// /// ```rust /// if true == false { ///     println!("oh no"); /// } else if "something" == "other thing" { ///     println!("oh dear"); /// } else if let Some(200) = "blarg".parse::<i32>().ok() { ///     println!("uh oh"); /// } else { ///     println!("phew, nothing's broken"); /// } /// ``` /// /// The `if` keyword is used in one other place in Rust, namely as a part of pattern matching /// itself, allowing patterns such as `Some(x) if x > 200` to be used. /// /// For more information on `if` expressions, see the [Rust book] or the [Reference]. /// /// [`match`]: keyword.match.html /// [`let`]: keyword.let.html /// [Rust book]: https://doc.rust-lang.org/stable/book/2018-edition/ch03-05-control-flow.html#if-expressions /// [Reference]: https://doc.rust-lang.org/reference/expressions/if-expr.html mod if_keyword { } </ins> #[doc(keyword = "let")] // /// The `let` keyword.

This code snippet () results in the following lint output: The should contain the literal string , not the expanded macro that it repreesnts.
Ah, I think this is because we should be using (to get the code the user actually wrote) (to render the AST); I could PR this tonight.


Question: // option. This file may not be copied, modified, or distributed // except according to those terms. <ins> #[doc(keyword = "as")] // /// The type coercion keyword. /// /// `as` is most commonly used to turn primitive types into other primitive types, but it has other /// uses that include turning pointers into addresses, addresses into pointers, and pointers into /// other pointers. /// /// ```rust /// let thing1: u8 = 89.0 as u8; /// assert_eq!('B' as u32, 66); /// assert_eq!(thing1 as char, 'Y'); /// let thing2: f32 = thing1 as f32 + 10.5; /// assert_eq!(true as u8 + thing2 as u8, 100); /// ``` /// /// In general, any coercion that can be performed via writing out type hints can also be done /// using `as`, so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (Note: /// `let x = 123u32` would be best in that situation). The same is not true in the other direction, /// however, explicitly using `as` allows a few more coercions that aren't allowed implicitly, such /// as changing the type of a raw pointer or turning closures into raw pointers. /// /// For more information on what `as` is capable of, see the [Reference] /// /// [Reference]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions mod as_keyword { } #[doc(keyword = "const")] // /// The keyword for defining constants. /// /// Sometimes a certain value is used many times throughout a program, and it can become /// inconvenient to copy it over and over. What's more, it's not always possible or desirable to /// make it a variable that gets carried around to each function that needs it. In these cases, the /// `const` keyword provides a convenient alternative to code duplication. /// /// ```rust /// const THING: u32 = 0xABAD1DEA; /// /// let foo = 123 + THING; /// ``` /// /// Constants must be explicitly typed, unlike with `let` you can't ignore its type and let the /// compiler figure it out. Any constant value can be defined in a const, which in practice happens /// to be most things that would be reasonable to have a constant. For example, you can't have a /// File as a `const`. /// /// The only lifetime allowed in a constant is 'static, which is the lifetime that encompasses all /// others in a Rust program. For example, if you wanted to define a constant string, it would look /// like this: /// /// ```rust /// const WORDS: &'static str = "hello rust!"; /// ``` /// /// Thanks to static lifetime elision, you usually don't have to explicitly use 'static: /// /// ```rust /// const WORDS: &str = "hello convenience!"; /// ``` /// /// `const` items looks remarkably similar to [`static`] items, which introduces some confusion as /// to which one should be used at which times. To put it simply, constants are inlined wherever /// they're used, making using them identical to simply replacing the name of the const with its /// value. Static variables on the other hand point to a single location in memory, which all /// accesses share. This means that, unlike with constants, they can't have destructors, but it /// also means that (via unsafe code) they can be mutable, which is useful for the rare situations /// in which you can't avoid using global state. /// /// Constants, as with statics, should always be in SCREAMING_SNAKE_CASE. /// /// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const /// T` and `*mut T`. More about that can be read at the [pointer] primitive part of the Rust docs. /// /// For more detail on `const`, see the [Rust Book] or the [Reference] /// /// [`static`]: keyword.static.html /// [pointer]: primitive.pointer.html /// [Rust Book]: https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants /// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html mod const_keyword { } #[doc(keyword = "crate")] // /// The `crate` keyword. /// /// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are /// used to specify a dependency on a crate external to the one it's declared in. Crates are the /// fundamental compilation unit of Rust code, and can be seen as libraries or projects. More can /// be read about crates in the [Reference]. /// /// ```rust ignore /// extern crate rand; /// extern crate my_crate as thing; /// extern crate std; // implicitly added to the root of every Rust project /// ``` /// /// The `as` keyword can be used to change what the crate is referred to as in your project. If a /// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores. /// /// `crate` is also used as in conjunction with [`pub`] to signify that the item it's attached to /// is public only to other members of the same crate it's in. /// /// ```rust /// # #[allow(unused_imports)] /// pub(crate) use std::io::Error as IoError; /// pub(crate) enum CoolMarkerType { } /// pub struct PublicThing { ///     pub(crate) semi_secret_thing: bool, /// } /// ``` /// /// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html /// [`pub`]: keyword.pub.html mod crate_keyword { } #[doc(keyword = "enum")] // /// For defining enumerations. /// /// Enums in Rust are similar to those of other compiled languages like C, but have important /// differences that make them considerably more powerful. What Rust calls enums are more commonly /// known as Algebraic Data Types if you're coming from a functional programming background, but /// the important part is that data can go with the enum variants. /// /// ```rust /// # struct Coord; /// enum SimpleEnum { ///     FirstVariant, ///     SecondVariant, ///     ThirdVariant, /// } /// /// enum Location { ///     Unknown, ///     Anonymous, ///     Known(Coord), /// } /// /// enum ComplexEnum { ///     Nothing, ///     Something(u32), ///     LotsOfThings { ///         usual_struct_stuff: bool, ///         blah: String, ///     } /// } /// /// enum EmptyEnum { } /// ``` /// /// The first enum shown is the usual kind of enum you'd find in a C-style language. The second /// shows off a hypothetical example of something storing location data, with Coord being any other /// type that's needed, for example a struct. The third example demonstrates the kind of variant a /// variant can store, ranging from nothing, to a tuple, to an anonymous struct. /// /// Instantiating enum variants involves explicitly using the enum's name as its namespace, /// followed by one of its variants. `SimpleEnum::SecondVariant` would be an example from above. /// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data /// is added as the type describes, for example `Option::Some(123)`. The same follows with /// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff: /// true, blah: "hello!".to_string(), }`. Empty Enums are similar to () in that they cannot be /// instantiated at all, and are used mainly to mess with the type system in interesting ways. /// /// For more information, take a look at the [Rust Book] or the [Reference] /// /// [`Option`]: option/enum.Option.html /// [Rust Book]: https://doc.rust-lang.org/book/second-edition/ch06-01-defining-an-enum.html /// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html mod enum_keyword { } #[doc(keyword = "extern")] // /// For external connections in Rust code. /// /// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`] /// keyword to make your Rust code aware of other Rust crates in your project, i.e. `extern crate /// lazy_static;`. The other use is in foreign function interfaces (FFI). /// /// `extern` is used in two different contexts within FFI. The first is in the form of external /// blcoks, for declaring function interfaces that Rust code can call foreign code by. /// /// ```rust ignore /// #[link(name = "my_c_library")] /// extern "C" { ///     fn my_c_function(x: i32) -> bool; /// } /// ``` /// /// This code would attempt to link with libmy_c_library.so on unix-like systems and /// my_c_library.dll on Windows at runtime, and panic if it can't find something to link to. Rust /// code could then use `my_c_function` as if it were any other unsafe Rust function. Working with /// non-Rust languages and FFI is inherently unsafe, so wrappers are usually built around C APIs. /// /// The mirror use case of FFI is also done via the `extern` keyword: /// /// ```rust /// # #![allow(private_no_mangle_fns)] /// #[no_mangle] /// pub extern fn callable_from_c(x: i32) -> bool { ///     x % 3 == 0 /// } /// ``` /// /// If compiled as a dylib, the resulting .so could then be linked to from a C library, and the /// function could be used as if it was from any other library. /// /// For more information on FFI, check the [Rust book] or the [Reference]. /// /// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code /// [Reference]: https://doc.rust-lang.org/reference/items/external-blocks.html mod extern_keyword { } </ins> #[doc(keyword = "fn")] // <del> /// The `fn` keyword. </del> <ins> /// The keyword for defining functions. </ins> /// <del> /// The `fn` keyword is used to declare a function. </del> <ins> /// Functions are the primary way code is executed within Rust. Function blocks, usually just /// called functions, can be defined in a variety of different places and be assigned many /// different attributes and modifiers. </ins> /// <del> /// Example: </del> <ins> /// Standalone functions that just sit within a module not attached to anything else are common, /// but most functions will end up being inside [`impl`] blocks, either on another type itself, or /// as a trait impl for that type. </ins> /// /// ```rust <del> /// fn some_function() { ///     // code goes in here </del> <ins> /// fn standalone_function() { ///     // code /// } /// /// pub fn public_thing(argument: bool) -> String { ///     // code ///     # "".to_string() /// } /// /// struct Thing { ///     foo: i32, /// } /// /// impl Thing { ///     pub fn new() -> Self { ///         Self { ///             foo: 42, ///         } ///     } </ins> /// } /// ``` /// <del> /// For more information about functions, take a look at the [Rust Book][book]. </del> <ins> /// See docs on [`impl`] and [`self`] for relevant details on those. /// /// In addition to presenting fixed types in the form of `fn name(arg: type, ..) -> return_type`, /// functions can also declare a list of type parameters along with trait bounds that they fall /// into. /// /// ```rust /// fn generic_function<T: Clone>(x: T) -> (T, T, T) { ///     (x.clone(), x.clone(), x.clone()) /// } </ins> /// <del> /// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html </del> <ins> /// fn generic_where<T>(x: T) -> T ///     where T: std::ops::Add<Output=T> + Copy /// { ///     x + x + x /// } /// ``` /// /// Declaring trait bounds in the angle brackets is functionally identical to using a [`where`] /// clause, but `where` is preferred due to it being easier to understand at a glance. /// /// Along with being made public via [`pub`], `fn` can also have an [`extern`] added for use in /// FFI. /// /// For more information on the various types of functions and how they're used, consult the [Rust /// book] or the [Reference]. /// /// [`impl`]: keyword.impl.html /// [`self`]: keyword.self.html /// [`where`]: keyword.where.html /// [`pub`]: keyword.pub.html /// [`extern`]: keyword.extern.html /// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html /// [Reference]: https://doc.rust-lang.org/reference/items/functions.html </ins> mod fn_keyword { } <ins> #[doc(keyword = "for")] // /// The `for` keyword. /// /// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic uses such as /// `impl Trait for Type` (see [`impl`] for more info on that). for-in-loops, or to be more /// precise, iterator loops, are a simple syntactic sugar over an exceedingly common practice /// within Rust, which is to loop over an iterator until that iterator returns None (or [`break`] /// is called). /// /// ```rust /// for i in 0..5 { ///     println!("{}", i * 2); /// } /// /// for i in std::iter::repeat(5) { ///     println!("turns out {} never stops being 5", i); ///     break; // would loop forever otherwise /// } /// /// 'outer: for x in 5..50 { ///     for y in 0..10 { ///         if x == y { ///             break 'outer; ///         } ///     } /// } /// ``` /// /// As shown in the example above, `for` loops (along with all other loops) can be tagged, using /// similar syntax to lifetimes (only visually similar, entirely distinct in practice). Giving the /// same tag to `break` breaks the tagged loop, which is useful for inner loops. It is definitely /// not a goto. /// /// A `for` loop expands as shown: /// /// ```rust /// # fn code() { } /// # let iterator = 0..2; /// for loop_variable in iterator { ///     code() /// } /// ``` /// /// ```rust /// # fn code() { } /// # let iterator = 0..2; /// { ///     let mut _iter = std::iter::IntoIterator::into_iter(iterator); ///     loop { ///         match _iter.next() { ///             Some(loop_variable) => { ///                 code() ///             }, ///             None => break, ///         } ///     } /// } /// ``` /// /// More details on the functionality shown can be seen at the [`IntoIterator`] docs. /// /// For more information on for-loops, see the [Rust book] or the [Reference]. /// /// [`impl`]: keyword.impl.html /// [`break`]: keyword.break.html /// [`IntoIterator`]: iter/trait.IntoIterator.html /// [Rust book]: https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for /// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops mod for_keyword { } #[doc(keyword = "if")] // /// If statements and expressions. /// /// `if` is a familiar construct to most programmers, and is the main way you'll often do logic in /// your code. However, unlike in most languages, `if` blocks can also act as expressions. /// /// ```rust /// # let rude = true; /// if 1 == 2 { ///     println!("whoops, mathematics broke"); /// } else { ///     println!("everything's fine!"); /// } /// /// let greeting = if rude { ///     "sup nerd." /// } else { ///     "hello, friend!" /// }; /// /// if let Ok(x) = "123".parse::<i32>() { ///     println!("{} double that and you get {}!", greeting, x * 2); /// } /// ``` /// /// Shown above are the three typical forms an `if` block comes in. First is the usual kind of /// thing you'd see in many languages, with an optional `else` block. Second uses `if` as an /// expression, which is only possible if all branches return the same type. An `if` expression can /// be used everywhere you'd expect. The third kind of `if` block is an `if let` block, which /// behaves similarly to using a [`match`] expression: /// /// ```rust /// if let Some(x) = Some(123) { ///     // code ///     # let _ = x; /// } else { ///     // something else /// } /// /// match Some(123) { ///     Some(x) => { ///         // code ///         # let _ = x; ///     }, ///     _ => { ///         // something else ///     }, /// } /// ``` /// /// See [`let`] for more information on pattern bindings. /// /// Each kind of `if` expression can be mixed and matched as needed. /// /// ```rust /// if true == false { ///     println!("oh no"); /// } else if "something" == "other thing" { ///     println!("oh dear"); /// } else if let Some(200) = "blarg".parse::<i32>().ok() { ///     println!("uh oh"); /// } else { ///     println!("phew, nothing's broken"); /// } /// ``` /// /// The `if` keyword is used in one other place in Rust, namely as a part of pattern matching /// itself, allowing patterns such as `Some(x) if x > 200` to be used. /// /// For more information on `if` expressions, see the [Rust book] or the [Reference]. /// /// [`match`]: keyword.match.html /// [`let`]: keyword.let.html /// [Rust book]: https://doc.rust-lang.org/stable/book/2018-edition/ch03-05-control-flow.html#if-expressions /// [Reference]: https://doc.rust-lang.org/reference/expressions/if-expr.html mod if_keyword { } </ins> #[doc(keyword = "let")] // /// The `let` keyword.

ARC is beginning to infect more and more types, and they each must have a clone method, but there is no trait to implement.
related
Along with this, we should provide a default implementation of Clonable for all copyable types.
Closing this now that has been implemented. There are no doubt some types left that should have a implementation, but they can be dealt with on a case-by-case basis.


Question: <del> error: expected expression, found reserved keyword `try` --> $DIR/try-block-in-while.rs:6:11 </del> <ins> error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied --> $DIR/try-block-in-while.rs:6:15 </ins> | LL |     while try { false } {} <del> |           ^^^ expected expression </del> <ins> |               ^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool` | = note: required by `std::ops::Try::from_ok` </ins> error: aborting due to previous error <ins> For more information about this error, try `rustc --explain E0277`. </ins>

This produces a lint: But removing the parentheses produces an error. This bug was already mentioned in , but that issue is lost in feature-request purgatory since it asks for the version without parentheses to be allowed. I'm opening this issue to track the incorrect lint specifically. (Edit: Fixed the example.) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim Will wait for to get merged before this is fixed though.


Question: <del> error: expected expression, found reserved keyword `try` --> $DIR/try-block-in-while.rs:6:11 </del> <ins> error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied --> $DIR/try-block-in-while.rs:6:15 </ins> | LL |     while try { false } {} <del> |           ^^^ expected expression </del> <ins> |               ^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool` | = note: required by `std::ops::Try::from_ok` </ins> error: aborting due to previous error <ins> For more information about this error, try `rustc --explain E0277`. </ins>

The following code fails to compile (): The compiler error is: Adding parentheses or braces, it will compile fine: The same issue happens with other constructs such as:
cc
I believe the error is expected here, the same as with : Which also needs to be to compile. That said, the warning to remove the necessary parens is definitely wrong. EDIT: Hmm, I might be wrong, actually. The following compiles, which surprised me: as does this: So maybe the parser restriction is only for struct literals, not for keyword-introduced expressions.
Yeah I think is the better comparison here so it's probably a bug.
This is exactly what a thought. I didn't know that this:
For , hmmm... well, I can't come up with a truly devastating example, but eliminating the parentheses could hurt diagnostics.


Question: .iter() .enumerate() .filter(|x| x.1.hir_id == *hir_id) <del> .map(|(i, _)| init_tup.get(i).unwrap()) .next() </del> <ins> .find_map(|(i, _)| init_tup.get(i)) </ins> { self.note_type_is_not_clone_inner_expr(init) } else {

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Regression in
I think it's enough to change to be without .


Question: <ins> struct TestClient; impl TestClient { fn get_inner_ref(&self) -> &Vec<usize> { todo!() } } fn main() { let client = TestClient; let inner = client.get_inner_ref(); //~^ HELP consider changing this to be a mutable reference inner.clear(); //~^ ERROR cannot borrow `*inner` as mutable, as it is behind a `&` reference [E0596] } </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: In case it helps, when using the stable toolchain, the compiler does not panic but instead emits this error: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Bisected to . CC searched nightlies: from nightly-2021-10-01 to nightly-2021-11-25 regressed nightly: nightly-2021-11-23 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.1</summaryHost triple: aarch64-apple-darwin Reproduce with: </details label regression-from-stable-to-nightly
I can fix this quickly -- seems like just changing an to a since the can be out of bounds. claim
(only tangentially related) I also noticed a regression in error spans between stable and beta... stable: beta:
That was an intentional change, meant to highlight the fact that the attempted mutable borrow is occurring because of the method call. However, it seems to be confusing for a lot of people, so I'll look into improving it.
Ah thanks for letting me know. Maybe we can split the span up into the receiver and the method, and add a note on the latter like "due to this method which takes &mut self". Not sure if that much info bubbles down into borrowck. I'd be interested in making that change if you've got a lot on your plate and it's (relatively) easy to do.
See for discussion about this exact idea. It'd be nice, but likely hard to implement.
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-high


Question: <ins> // Copyright 2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. </ins>

Rustdoc defaults to only documented things that are public, i.e. things that the user of a library would care about. This is a good default, but rustdoc can also be useful to people working on large crates by documenting these crates themselves. In that case, it’s preferable to also include private types, fields, functions, and methods. was about this use case, and was closed with this solution: We just tried this on . It’s better than before, but has the unexpected side effect that every item (including non- and the implicit prelude) and every (including the implicit ) is documented under “Reexports”. It can get pretty noisy: ! They’re technically part of the crate, but don’t provide useful information. Could rustdoc split up the pass into one that strips private and , and one for everything else?


Question: let _: Wow<A.0>; //~^ ERROR expected one of //~| HELP expressions must be enclosed in braces to be used as const generic arguments <del> // FIXME(compiler-errors): This one is still unsatisfying, // and probably a case I could see someone typing by accident.. </del> <ins> let _: Wow<[]>; //~^ ERROR expected type //~| HELP expressions must be enclosed in braces to be used as const generic arguments </ins> let _: Wow<[12]>; <del> //~^ ERROR expected type, found //~| ERROR type provided when a constant was expected </del> <ins> //~^ ERROR expected type //~| ERROR invalid const generic expression //~| HELP expressions must be enclosed in braces to be used as const generic arguments let _: Wow<[0, 1, 3]>; //~^ ERROR expected type //~| HELP expressions must be enclosed in braces to be used as const generic arguments let _: Wow<[0xff; 8]>; //~^ ERROR expected type //~| ERROR invalid const generic expression //~| HELP expressions must be enclosed in braces to be used as const generic arguments let _: Wow<[1, 2]>; // Regression test for issue #81698. //~^ ERROR expected type //~| HELP expressions must be enclosed in braces to be used as const generic arguments let _: Wow<&0>; //~^ ERROR expected type //~| HELP expressions must be enclosed in braces to be used as const generic arguments let _: Wow<("", 0)>; //~^ ERROR expected type //~| HELP expressions must be enclosed in braces to be used as const generic arguments let _: Wow<(1 + 2) * 3>; //~^ ERROR expected type //~| HELP expressions must be enclosed in braces to be used as const generic arguments // FIXME(fmease): This one is pretty bad. let _: Wow<!0>; //~^ ERROR expected one of //~| HELP you might have meant to end the type parameters here </ins> }

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --This is a much abbreviated version of the code from my experiments with adding a shuffle API to the stdsimd repo, it probably needs further reduction but I wanted to file this before I forgot: I expected to see this happen: it works, provides a useful error, or even just ICEs. Instead, this happened: I got a request to input a type instead! And no, that doesn't work either if you put it in, because instead you get: : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The fix is Due to parsing ambiguities generic arguments currently need to be put into braces, unless they are really simple (like or ), is not simple enough.
Oh, cool! That does compile! I knew about that but wasn't sure if that was the problem because I thought that was just for expressions? I guess that's technically an array expression? That is none of the errors I was presented with, though, which makes this a diagnostics problem I suppose?
I believe diagnostic for const generic (example taken from ) needs to be improved too before release, at least I thought that can be used instead, if one didn't know about then they need to search it up.
Arrays as const parameters still have bad error messages. same with tuples
claim


Question: <ins> // revisions:rpass1 rpass2 struct A; #[cfg(rpass2)] impl From<A> for () { fn from(_: A) {} } fn main() {} </ins>

It have something to do with incremental build :( seems to point to random function sometimes even in file that was not edited for weeks. Issue started today. Deleting folder help for few compilations. I do not use latest compiler because some problems with crate upgrades and incompatibilities with async/await! so the issue is not caused by the compiler version, because I use same version for a while, but it is triggered by something in my code. Is there anything I can look for in my code that could cause these issues?
Remember what you've done between cleaning and ICEing. (maybe auto git commit every save or similar ^^). In my case it was just renaming a variable from to which causes an ICE.
when I think backward it first appeared when I add crate slotmap, and with that crate I was able to reproduce it even with 2 lines edit to their simplest example, so at that point I think it is caused by the crate and removed it and it was fine for a while, I chose to use CHashMap that solve some problems for me. I can not say after which change it reappear.
I want to know if I could use as key because I already have unique so I try to implement trait for struct containing only get error, so I tried to replace their key and still get the error, and when I commented out it compile, I tried few other combinations, but compiler panicked a lot, so I decided it is not the crate I want and removed it prom my project.
triage: I'm going to mark this as P-high, but it might be more of a "medium" bug. It's a bit hard to say. I think there are few bits of info that would be useful: First and foremost, a more concrete recipe for reproducing the problem, ideally with a standalone example Second, some idea if this is a regression -- did the problem only start recently?


Question: <ins> // revisions:rpass1 rpass2 struct A; #[cfg(rpass2)] impl From<A> for () { fn from(_: A) {} } fn main() {} </ins>

For the first question: I am on windows 10 Pro 1809, CPU 1950X, 64 GB RAM and steps to reproduce are simple for me: start IntelliJ IDEA new rust project to add replace withbuild add as mentioned above build ~50% chance it fail if the build worked just rename build failed 5 of 6 times I get that far without deleting folder For the second question yes it started recently when I tried this crate, but more importantly the issue persisted after I removed it, it is just much less common than every second build.
Sadly I cannot reproduce it. Let me try to summarize it: as dependency in (hope it crashes) not, use Am I correct? Please be as precice as possible and clarify "just rename ". Do you want me to change lower/upper case? Remove one character? Add one? Your nightly seems kind of outdated. Is it still possible for you if you use the latest nightly? (I tried both, no luck)
It seems that it has been fixed on latest nightly, but I'm now able to reproduce it 100% with nightly-2019-04-05 (). new project as dependency in build in front of build in front of again
I would suggest to remove the P-High and I-nomiated tag, because it is fixed on nightly. I'll add the E-needstest tag. I just have to reduce the above example without external dependencies. Lets see what I can do. modify labels: E-needstest
Thanks a lot for looking into this, can you confirm that the crash doesn't occur anymore with the latest nightly compiler?
After a lot of effort I switched toolchain to and it seems to work here (over 20 rebuilds without error)
please do not close this issue. I created a PR which will automatically close this when it has been merged. Please reopen it
This is likely caused by and fixed by
Can confirm that the bug has been fixed in (bisecting ftw)


Question: } /// Builds drops for pop_scope and exit_scope. <del> fn build_scope_drops<'tcx>(mut block: BasicBlock, </del> <ins> fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>, </ins> scope: &Scope<'tcx>, earlier_scopes: &[Scope<'tcx>], <del> cfg: &mut CFG<'tcx>) </del> <ins> mut block: BasicBlock) </ins> -> BlockAnd<()> { let mut iter = scope.drops.iter().rev().peekable(); while let Some(drop_data) = iter.next() {

This generates the following (broken) MIR: As you can see, is dropped but never written to (AFAIK this should be OK because of zeroing) but the boxes are never freed.
cc
EDIT: I wasn’t looking closely enough, it is indeed broken.
This is a problem on latest master ()


Question: DependencyType::TargetSelfContained, ); } <ins> let crt_path = builder.ensure(native::CrtBeginEnd { target }); </ins> for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { <del> let src = compiler_file(builder, builder.cc(target), target, obj); </del> <ins> let src = crt_path.join(obj); </ins> let target = libdir_self_contained.join(obj); builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained));

Upstream issue: The version of used in the (and possibly the one too?) standard library has a bug where it will sometimes walk off the end of the segment containing the section and segfault. I've struggled to reproduce this except in some proprietary code, but the backtrace looks like: There's a proposed fix in the linked LLVM issue, which can possibly be patched into libunwind before building the musl target if taking an updated libunwind isn't possible.
I ran into this as well.
There doesn't seem to be any movement on the LLVM issue since I raised it, not even an assignee. Do you know if this is normal behaviour for them? Or if I've mis-raised the issue?
Running into this as well at OneSignal
I can reproduce this on latest stable on an open source project: On the second run of the final command, the background process will segfault.
After much investigation, I think there's two bugs here, one that LLVM's unwinder will consider unreadable memory as part of the section, and one that the rust compiler creates invalid (unusual?) unwind information. The crash is specifically happening when trying to find unwind information for the frame above (not but the "c-runtime" main. Since the frames above the C entry point are provided by the runtime (musl in this case), they are contained in / which, in rust's musl-targeting stdlib have been provided. The provided object files have no unwind information in them: This in and of itself isn't a huge problem, the code stops trying to unwind when it can't find unwind information for the next frame (), so it should stop after which would be fine. so long as we can safely fail to find the unwind information. The issue is that libunwind's logic for searching for FDE (frame description entry) for the parent frame is pretty all-encompassing and runs in many phases, and one of these crashes (sometimes) if there searched for address is not present in the unwind information).


Question: DependencyType::TargetSelfContained, ); } <ins> let crt_path = builder.ensure(native::CrtBeginEnd { target }); </ins> for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { <del> let src = compiler_file(builder, builder.cc(target), target, obj); </del> <ins> let src = crt_path.join(obj); </ins> let target = libdir_self_contained.join(obj); builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained));

At a high level the process looks like () Look for a "compact unwinding table" Look for "DWARF unwind information" Look for ARM EHABI unwind info Look for dynamically created DWARF unwind entries For Rust x8664 musl binaries, the compiler has provided DWARF unwind information, so we fall into the second bullet (): No compact encoding hint, so the first section isn't interesting Search the section for an index for the frame - not present Check the local cache in case we've seen this frame before - we haven't Scan the whole of the section for the address of interest - CRASH! Digging further, we see that the logic for scanning the sector looks like (): Read a length field If it's 0 stop, we're done - rustc never seems to generate this "end-of-information" marker Skip over CIE entries For non-CIE entries work out if the address we're looking for is in the range of the entry, if so we've got our FDE Jump forward by the length of the CFI entry In each loop we check that the newly found CIE entry is in a reasonable place (between and ). If it's not, bail out for safety and fail the lookup. Unfortunately, as in the linked issue originally is incorrectly set too big (it's set to which is almost always wrong) so the unwind code will step right off the end of the segment and into one of: (LSDA) - This starts with a signature that is approximately , which is bigger than the error introduced by the miscalculation, so (after failing to parse the LSDA as a CFI entry) it jumps forward out of the range and bails out because the of the "reasonable location" check I mentioned above. The gap before (if the did not have a length that's a multiple of 32 and thus there's padding between the sections). In this case when it tries to read the next entry one of three things happens: The padding bytes happen to have a large value (when interpreted as a ) and we're in a similar position to the case where there's no padding, fail to parse the CFI entry, try to jump to the next one, realise we're jumping out of the allowed range and bail out for safety.


Question: DependencyType::TargetSelfContained, ); } <ins> let crt_path = builder.ensure(native::CrtBeginEnd { target }); </ins> for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { <del> let src = compiler_file(builder, builder.cc(target), target, obj); </del> <ins> let src = crt_path.join(obj); </ins> let target = libdir_self_contained.join(obj); builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained));

The padding bytes are medium sized when interpreted as a , in this case, after the failed parse, the unwinder jumps far enough to be off the end of the loaded segment, but not far enough to be past the so the sanity check passes and the unwinder attempts to read the next CFI entry, reads a 32-bit number from an invalid address and... :boom: The padding bytes are small when interpreted as a , and the unwinder jumps into a random part of the LSDA and we're back in a situation that's functionally similar to when we're reading the padding bytes and the same three options are still applicable in the next lookup. So, what's the bug(s) here? LLVM is miscalculating the section length (the original issue) Rustc (or the linker?) doesn't include the marker at the end of Either of these would fix this issue, probably both should be done?
Ah, there's another possible route for the crash: If the LOAD segement is really big, the signature at the start of the LSDA might not be big enough to jump past leading to an invalid read and a :boom:
I've ran into this issue as well. What's the status of this?
I've been looking at a proper fix for this and neither of the two paths I proposed above are yeilding simple results: LLVM miscalculating the section length: The simple fix I proposed in the upstream issue allows the unwinder to read arbitrary parts of the LOAD segment before bailing, which might have unexpected effects A more complex fix needs to calculate the section length at runtime, which is tricky as sections don't exist at runtime... Neither the nor section contains a length field so we're not simply told the length Maybe read the executable off disk (look in ) and parse the section table? Might not be readable to the current user. Might not even exist (not sure if this is possible, can you create a linux executable from an in-memory image?) Add terminator entry to the end of the section This relies on the static linker's behaviour, which is a shame as allows you to bring your own linker and both seem inconsistent about whether they add terminator entries, sometimes they do, sometimes they don't This feels like something that rustc can't fix locally or rely on externally Another option would be for LLVM to skip walking the section if the lookup in the fails.


Question: DependencyType::TargetSelfContained, ); } <ins> let crt_path = builder.ensure(native::CrtBeginEnd { target }); </ins> for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { <del> let src = compiler_file(builder, builder.cc(target), target, obj); </del> <ins> let src = crt_path.join(obj); </ins> let target = libdir_self_contained.join(obj); builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained));

It's unlikely to ever reveal anything new, and it seems that this section is just un-walkable with any kind of reliability.
Here are two tested workarounds, neither very pretty, but both work: to your Cargo config a build, extract the link script from the linker verbose output the lines: .ehframe : ONLYIFRO { KEEP ((.ehframe)) (.ehframe.) } ... .ehframe : ONLYIFRW { KEEP ((.ehframe)) (.ehframe.) } them to: .ehframe : ONLYIFRO { KEEP ((.ehframe)) (.ehframe.) LONG(0x0) } ... .ehframe : ONLYIFRW { KEEP ((.ehframe)) (.ehframe.) LONG(0x0) } ( is the CIE terminator) off this script somewhere in Cargo config (probably under the Musl target) an object containing just the terminator: 2, Add to your Cargo config (probably under the Musl target)
Hi! Is this still an issue? If so, is there perhaps a simpler way to reproduce this than the instructions linked above?
The setup that's needed is: A large LOAD segment (the one containing and ) Specifically the section needs to be deep into the segment How deep it has to be is roughly determined by the first of the section So something like the following should trigger the fault: This builds a huge section, which lives before the section so should lead to the crash. Hedging words because I can't reproduce the issue on my development machine (I run out of RAM and get OOM-killered).
Hmm, that doesn't seem to be sufficient (tested on the current stable and nightly). I get this output when building and running this on Arch Linux: I also get the same output when using to capture the backtrace.
I noticed the wrong ehSectionEnd calculation independently and filed
It looks like the gcc driver on Alpine adds the file to the link, which includes a terminator in . It seems that the rustc driver doesn't add something like this? (LLVM has a that has an .ehframe terminator, so maybe that's relevant to rustc.)


Question: DependencyType::TargetSelfContained, ); } <ins> let crt_path = builder.ensure(native::CrtBeginEnd { target }); </ins> for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { <del> let src = compiler_file(builder, builder.cc(target), target, obj); </del> <ins> let src = crt_path.join(obj); </ins> let target = libdir_self_contained.join(obj); builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained));

FWIW, it looks like LLVM's LLD linker automatically adds a terminator to the end of .ehframe, even if one isn't present in the linker inputs, so that could be a workaround: I think libunwind should stop scanning .ehframe when it finds unwind info from .ehframehdr (i.e. the GNUEH_FRAME segment).
Rustc's musl-targeting link includes: I don't exactly know where the files come from (they're shipped with the compiler toolchain, e.g. mine are in ) but looking at the musl codebase, there's no terminator in : (Intriguingly there's also no in the musl codebase, suggesting Rustc gets these objects from somewhere else?)_ I wouldn't expect to see a or since the rustc musl target doesn't include a C++ runtime and musl libc doesn't define either of these objects for the C runtime either.
It looks like musl's crt1 is a C file, not assembly. crt/{S,r,}crt1.c When crtbegin and crtend were to LLVM (), there was some discussion about which project is responsible for which aspects of the CRT begin/end files. Apparently the status quo on Linux is that: the compiler (e.g. libgcc) provides crtbegin/crtend the libc provides crti/crte (and maybe crt1, too?) That is the case on my gLinux (i.e. Debian) system: /usr/lib/x8664-linux-gnu/crt[1ie].o all come from the libc6-dev:amd64 package /usr/lib/gcc/x8664-linux-gnu/9/{crtbegin.o,crtend.o} come from libgcc-9-dev:amd64 The .ehframe terminator is usually in crtend, which is part of libgcc (not glibc or musl). LLVM's compiler-rt also provides crtbegin/crtend files. The gcc and clang drivers link a crtend object even for C programs. On Alpine, the gcc driver links a libgcc crtend object. It looks like rustc typically invokes the driver, but when it's targeting musl, it enters a mode where it provides the start files explicitly, and in this mode, it doesn't include crtbegin/crtend. For Alpine, I see , , , and .


Question: DependencyType::TargetSelfContained, ); } <ins> let crt_path = builder.ensure(native::CrtBeginEnd { target }); </ins> for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { <del> let src = compiler_file(builder, builder.cc(target), target, obj); </del> <ins> let src = crt_path.join(obj); </ins> let target = libdir_self_contained.join(obj); builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained));

For rustc/glibc, I don't see any of those flags, so the cc driver uses the default CRT begin/end/i/n/1 files. I see that rustc documents a lot of this at The unwinder needs the .ehframe terminator, because the .ehframehdr search table is optional, and because .ehframehdr has the start address of .ehframe, but not its size. ( / ). I don't think it's reasonable to open the ELF file indicated by dlpiname -- in principle, that duplicates the work done by the loader, and I can think of many specific things that wouldn't work. (e.g. the vdso, the executable w/glibc, Android's androiddlopen_ext and ability to map DSOs from zip files, unlinked files, etc).
Using self-contained mode is not generally recommended for serious work. If the compiler heuristics enable it by default, then it can be explicitly disabled with , then gcc will be used for linking without and will find all the necessary CRT objects by itself. Then it's important to make sure that gcc for the right target (musl in this case) is used by rustc.
If the compiler heuristics enable it by default Here's a FIXME for improving the heuristic for musl targets:
Thanks for that, very interesting. I think there are two separate use cases for musl-targeting builds: an environment where there's a full "native musl" toolchain (like on Alpine etc) where I think you're correct that we shouldn't use and should let the toolchain sort it out for us though I can't see an easy way to tell if a real toolchain is available a generic linux environment where the goal is fully static binaries (for easy of redistribution/embedding in thin container images/etc.)