diff options
Diffstat (limited to 'src/doc')
92 files changed, 1597 insertions, 1230 deletions
diff --git a/src/doc/book/COPYRIGHT b/src/doc/book/COPYRIGHT index dfe614df9..0fc3ea43f 100644 --- a/src/doc/book/COPYRIGHT +++ b/src/doc/book/COPYRIGHT @@ -1,290 +1,3 @@ -Short version for non-lawyers: - -The Rust Project is dual-licensed under Apache 2.0 and MIT -terms. - - -Longer version: - -The Rust Project is copyright 2010, The Rust Project -Developers. - -Licensed under the Apache License, Version 2.0 -<LICENSE-APACHE or -https://www.apache.org/licenses/LICENSE-2.0> or the MIT -license <LICENSE-MIT or https://opensource.org/licenses/MIT>, -at your option. All files in the project carrying such -notice may not be copied, modified, or distributed except -according to those terms. - - -The Rust Project includes packages written by third parties. -The following third party packages are included, and carry -their own copyright notices and license terms: - -* The src/rt/miniz.c file, carrying an implementation of - RFC1950/RFC1951 DEFLATE, by Rich Geldreich - <richgel99@gmail.com>. All uses of this file are - permitted by the embedded "unlicense" notice - (effectively: public domain with warranty disclaimer). - -* LLVM. Code for this package is found in src/llvm. - - Copyright (c) 2003-2013 University of Illinois at - Urbana-Champaign. All rights reserved. - - Developed by: - - LLVM Team - - University of Illinois at Urbana-Champaign - - https://llvm.org - - Permission is hereby granted, free of charge, to any - person obtaining a copy of this software and associated - documentation files (the "Software"), to deal with the - Software without restriction, including without - limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software - is furnished to do so, subject to the following - conditions: - - * Redistributions of source code must retain the - above copyright notice, this list of conditions - and the following disclaimers. - - * Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimers in the documentation - and/or other materials provided with the - distribution. - - * Neither the names of the LLVM Team, University of - Illinois at Urbana-Champaign, nor the names of its - contributors may be used to endorse or promote - products derived from this Software without - specific prior written permission. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE - FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT - OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS WITH THE SOFTWARE. - -* Additional libraries included in LLVM carry separate - BSD-compatible licenses. See src/llvm/LICENSE.txt for - details. - -* compiler-rt, in src/compiler-rt is dual licensed under - LLVM's license and MIT: - - Copyright (c) 2009-2014 by the contributors listed in - CREDITS.TXT - - All rights reserved. - - Developed by: - - LLVM Team - - University of Illinois at Urbana-Champaign - - https://llvm.org - - Permission is hereby granted, free of charge, to any - person obtaining a copy of this software and associated - documentation files (the "Software"), to deal with the - Software without restriction, including without - limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software - is furnished to do so, subject to the following - conditions: - - * Redistributions of source code must retain the - above copyright notice, this list of conditions - and the following disclaimers. - - * Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimers in the documentation - and/or other materials provided with the - distribution. - - * Neither the names of the LLVM Team, University of - Illinois at Urbana-Champaign, nor the names of its - contributors may be used to endorse or promote - products derived from this Software without - specific prior written permission. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE - FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT - OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS WITH THE SOFTWARE. - - ======================================================== - - Copyright (c) 2009-2014 by the contributors listed in - CREDITS.TXT - - Permission is hereby granted, free of charge, to any - person obtaining a copy of this software and associated - documentation files (the "Software"), to deal in the - Software without restriction, including without - limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software - is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice - shall be included in all copies or substantial portions - of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - -* Portions of the FFI code for interacting with the native ABI - is derived from the Clay programming language, which carries - the following license. - - Copyright (C) 2008-2010 Tachyon Technologies. - All rights reserved. - - Redistribution and use in source and binary forms, with - or without modification, are permitted provided that the - following conditions are met: - - 1. Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - - 2. Redistributions in binary form must reproduce the - above copyright notice, this list of conditions and - the following disclaimer in the documentation and/or - other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - OF SUCH DAMAGE. - -* libbacktrace, under src/libbacktrace: - - Copyright (C) 2012-2014 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Google. - - Redistribution and use in source and binary forms, with - or without modification, are permitted provided that the - following conditions are met: - - (1) Redistributions of source code must retain the - above copyright notice, this list of conditions and - the following disclaimer. - - (2) Redistributions in binary form must reproduce - the above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the - distribution. - - (3) The name of the author may not be used to - endorse or promote products derived from this - software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - OF SUCH DAMAGE. */ - -* jemalloc, under src/jemalloc: - - Copyright (C) 2002-2014 Jason Evans - <jasone@canonware.com>. All rights reserved. - Copyright (C) 2007-2012 Mozilla Foundation. - All rights reserved. - Copyright (C) 2009-2014 Facebook, Inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - 1. Redistributions of source code must retain the above copyright notice(s), - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice(s), - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - OF SUCH DAMAGE. - -* Additional copyright may be retained by contributors other - than Mozilla, the Rust Project Developers, or the parties - enumerated in this file. Such copyright can be determined - on a case-by-case basis by examining the author of each - portion of a file in the revision-control commit records - of the project, or by consulting representative comments - claiming copyright ownership for a file. - - For example, the text: - - "Copyright (c) 2011 Google Inc." - - appears in some files, and these files thereby denote - that their author and copyright-holder is Google Inc. - - In all such cases, the absence of explicit licensing text - indicates that the contributor chose to license their work - for distribution under identical terms to those Mozilla - has chosen for the collective work, enumerated at the top - of this file. The only difference is the retention of - copyright itself, held by the contributor. +This repository is licensed under the Apache License, Version 2.0 +<LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT +license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option. diff --git a/src/doc/book/src/ch15-06-reference-cycles.md b/src/doc/book/src/ch15-06-reference-cycles.md index bef289202..beb2bc216 100644 --- a/src/doc/book/src/ch15-06-reference-cycles.md +++ b/src/doc/book/src/ch15-06-reference-cycles.md @@ -84,7 +84,7 @@ If you uncomment the last `println!` and run the program, Rust will try to print this cycle with `a` pointing to `b` pointing to `a` and so forth until it overflows the stack. -Compared to a real-world program, the consequences creating a reference cycle +Compared to a real-world program, the consequences of creating a reference cycle in this example aren’t very dire: right after we create the reference cycle, the program ends. However, if a more complex program allocated lots of memory in a cycle and held onto it for a long time, the program would use more memory diff --git a/src/doc/footer.inc b/src/doc/footer.inc index 77e151235..504fe5115 100644 --- a/src/doc/footer.inc +++ b/src/doc/footer.inc @@ -1,3 +1,4 @@ +<!-- REUSE-IgnoreStart --> <footer><p> Copyright © 2011 The Rust Project Developers. Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> @@ -5,3 +6,4 @@ or the <a href="https://opensource.org/licenses/MIT">MIT license</a>, at your op </p><p> This file may not be copied, modified, or distributed except according to those terms. </p></footer> +<!-- REUSE-IgnoreEnd --> diff --git a/src/doc/nomicon/src/ffi.md b/src/doc/nomicon/src/ffi.md index 684e7125b..55be225de 100644 --- a/src/doc/nomicon/src/ffi.md +++ b/src/doc/nomicon/src/ffi.md @@ -258,7 +258,7 @@ pub extern "C" fn hello_from_rust() { # fn main() {} ``` -The `extern "C"` makes this function adhere to the C calling convention, as discussed above in "[Foreign Calling Conventions]". +The `extern "C"` makes this function adhere to the C calling convention, as discussed below in "[Foreign Calling Conventions]". The `no_mangle` attribute turns off Rust's name mangling, so that it has a well defined symbol to link to. Then, to compile Rust code as a shared library that can be called from C, add the following to your `Cargo.toml`: diff --git a/src/doc/nomicon/src/subtyping.md b/src/doc/nomicon/src/subtyping.md index cc48a5970..79b29beb0 100644 --- a/src/doc/nomicon/src/subtyping.md +++ b/src/doc/nomicon/src/subtyping.md @@ -335,7 +335,7 @@ we inherited invariance as soon as we put our reference inside an `&mut T`. As it turns out, the argument for why it's ok for Box (and Vec, Hashmap, etc.) to be covariant is pretty similar to the argument for why it's ok for -lifetimes to be covariant: as soon as you try to stuff them in something like a +references to be covariant: as soon as you try to stuff them in something like a mutable reference, they inherit invariance and you're prevented from doing anything bad. diff --git a/src/doc/reference/src/attributes/codegen.md b/src/doc/reference/src/attributes/codegen.md index 69ad341d1..ab59cd8e7 100644 --- a/src/doc/reference/src/attributes/codegen.md +++ b/src/doc/reference/src/attributes/codegen.md @@ -88,9 +88,11 @@ Feature | Implicitly Enables | Description `avx2` | `avx` | [AVX2] — Advanced Vector Extensions 2 `bmi1` | | [BMI1] — Bit Manipulation Instruction Sets `bmi2` | | [BMI2] — Bit Manipulation Instruction Sets 2 +`cmpxchg16b`| | [`cmpxchg16b`] - Compares and exchange 16 bytes (128 bits) of data atomically `fma` | `avx` | [FMA3] — Three-operand fused multiply-add `fxsr` | | [`fxsave`] and [`fxrstor`] — Save and restore x87 FPU, MMX Technology, and SSE State `lzcnt` | | [`lzcnt`] — Leading zeros count +`movbe` | | [`movbe`] - Move data after swapping bytes `pclmulqdq` | `sse2` | [`pclmulqdq`] — Packed carry-less multiplication quadword `popcnt` | | [`popcnt`] — Count of bits set to 1 `rdrand` | | [`rdrand`] — Read random number @@ -115,10 +117,12 @@ Feature | Implicitly Enables | Description [AVX2]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#AVX2 [BMI1]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets [BMI2]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#BMI2 +[`cmpxchg16b`]: https://www.felixcloutier.com/x86/cmpxchg8b:cmpxchg16b [FMA3]: https://en.wikipedia.org/wiki/FMA_instruction_set [`fxsave`]: https://www.felixcloutier.com/x86/fxsave [`fxrstor`]: https://www.felixcloutier.com/x86/fxrstor [`lzcnt`]: https://www.felixcloutier.com/x86/lzcnt +[`movbe`]: https://www.felixcloutier.com/x86/movbe [`pclmulqdq`]: https://www.felixcloutier.com/x86/pclmulqdq [`popcnt`]: https://www.felixcloutier.com/x86/popcnt [`rdrand`]: https://en.wikipedia.org/wiki/RdRand diff --git a/src/doc/reference/src/attributes/diagnostics.md b/src/doc/reference/src/attributes/diagnostics.md index 45f9cc440..506e2848b 100644 --- a/src/doc/reference/src/attributes/diagnostics.md +++ b/src/doc/reference/src/attributes/diagnostics.md @@ -49,7 +49,7 @@ check on and off: ```rust #[warn(missing_docs)] -pub mod m2{ +pub mod m2 { #[allow(missing_docs)] pub mod nested { // Missing documentation is ignored here diff --git a/src/doc/reference/src/expressions/loop-expr.md b/src/doc/reference/src/expressions/loop-expr.md index 204207ee0..c8b93ea39 100644 --- a/src/doc/reference/src/expressions/loop-expr.md +++ b/src/doc/reference/src/expressions/loop-expr.md @@ -249,8 +249,27 @@ A `break` expression is only permitted in the body of a loop, and has one of the > [_BlockExpression_] Labelled block expressions are exactly like block expressions, except that they allow using `break` expressions within the block. -Unlike other loops, `break` expressions within a label expression *must* have a label (i.e. the label is not optional). -Unlike other loops, labelled block expressions *must* begin with a label. +Unlike loops, `break` expressions within a labelled block expression *must* have a label (i.e. the label is not optional). +Similarly, labelled block expressions *must* begin with a label. + +```rust +# fn do_thing() {} +# fn condition_not_met() -> bool { true } +# fn do_next_thing() {} +# fn do_last_thing() {} +let result = 'block: { + do_thing(); + if condition_not_met() { + break 'block 1; + } + do_next_thing(); + if condition_not_met() { + break 'block 2; + } + do_last_thing(); + 3 +}; +``` ## `continue` expressions diff --git a/src/doc/reference/src/expressions/struct-expr.md b/src/doc/reference/src/expressions/struct-expr.md index 8caeff200..8d9154789 100644 --- a/src/doc/reference/src/expressions/struct-expr.md +++ b/src/doc/reference/src/expressions/struct-expr.md @@ -73,7 +73,7 @@ drop(y_ref); ``` Struct expressions with curly braces can't be used directly in a [loop] or [if] expression's head, or in the [scrutinee] of an [if let] or [match] expression. -However, struct expressions can be in used in these situations if they are within another expression, for example inside [parentheses]. +However, struct expressions can be used in these situations if they are within another expression, for example inside [parentheses]. The field names can be decimal integer values to specify indices for constructing tuple structs. This can be used with base structs to fill out the remaining indices not specified: diff --git a/src/doc/reference/src/inline-assembly.md b/src/doc/reference/src/inline-assembly.md index 996b157da..a12f495ff 100644 --- a/src/doc/reference/src/inline-assembly.md +++ b/src/doc/reference/src/inline-assembly.md @@ -43,16 +43,15 @@ format_string := STRING_LITERAL / RAW_STRING_LITERAL dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout" reg_spec := <register class> / "\"" <explicit register> "\"" operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_" -reg_operand := dir_spec "(" reg_spec ")" operand_expr -operand := reg_operand +reg_operand := [ident "="] dir_spec "(" reg_spec ")" operand_expr clobber_abi := "clobber_abi(" <abi> *("," <abi>) [","] ")" option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw" options := "options(" option *("," option) [","] ")" -asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) *("," clobber_abi) *("," options) [","] ")" -global_asm := "global_asm!(" format_string *("," format_string) *("," [ident "="] operand) *("," options) [","] ")" +operand := reg_operand / clobber_abi / options +asm := "asm!(" format_string *("," format_string) *("," operand) [","] ")" +global_asm := "global_asm!(" format_string *("," format_string) *("," operand) [","] ")" ``` - ## Scope Inline assembly can be used in one of two ways. @@ -74,8 +73,7 @@ An `asm!` invocation may have one or more template string arguments; an `asm!` w The expected usage is for each template string argument to correspond to a line of assembly code. All template string arguments must appear before any other arguments. -As with format strings, named arguments must appear after positional arguments. -Explicit [register operands](#register-operands) must appear at the end of the operand list, after named arguments if any. +As with format strings, positional arguments must appear before named arguments and explicit [register operands](#register-operands). Explicit register operands cannot be used by placeholders in the template string. All other named and positional operands must appear at least once in the template string, otherwise a compiler error is generated. @@ -486,6 +484,29 @@ To avoid undefined behavior, these rules must be followed when using function-sc > **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call. +### Correctness and Validity + +In addition to all of the previous rules, the string argument to `asm!` must ultimately become— +after all other arguments are evaluated, formatting is performed, and operands are translated— +assembly that is both syntactically correct and semantically valid for the target architecture. +The formatting rules allow the compiler to generate assembly with correct syntax. +Rules concerning operands permit valid translation of Rust operands into and out of `asm!`. +Adherence to these rules is necessary, but not sufficient, for the final expanded assembly to be +both correct and valid. For instance: + +- arguments may be placed in positions which are syntactically incorrect after formatting +- an instruction may be correctly written, but given architecturally invalid operands +- an architecturally unspecified instruction may be assembled into unspecified code +- a set of instructions, each correct and valid, may cause undefined behavior if placed in immediate succession + +As a result, these rules are _non-exhaustive_. The compiler is not required to check the +correctness and validity of the initial string nor the final assembly that is generated. +The assembler may check for correctness and validity but is not required to do so. +When using `asm!`, a typographical error may be sufficient to make a program unsound, +and the rules for assembly may include thousands of pages of architectural reference manuals. +Programmers should exercise appropriate care, as invoking this `unsafe` capability comes with +assuming the responsibility of not violating rules of both the compiler or the architecture. + ### Directives Support Inline assembly supports a subset of the directives supported by both GNU AS and LLVM's internal assembler, given as follows. @@ -499,12 +520,9 @@ The following directives are guaranteed to be supported by the assembler: - `.4byte` - `.8byte` - `.align` +- `.alt_entry` - `.ascii` - `.asciz` -- `.alt_entry` -- `.balign` -- `.balignl` -- `.balignw` - `.balign` - `.balignl` - `.balignw` @@ -520,17 +538,17 @@ The following directives are guaranteed to be supported by the assembler: - `.eqv` - `.fill` - `.float` -- `.globl` - `.global` -- `.lcomm` +- `.globl` - `.inst` +- `.lcomm` - `.long` - `.octa` - `.option` -- `.private_extern` - `.p2align` -- `.pushsection` - `.popsection` +- `.private_extern` +- `.pushsection` - `.quad` - `.scl` - `.section` diff --git a/src/doc/reference/src/items/constant-items.md b/src/doc/reference/src/items/constant-items.md index bf315932f..85d3e015d 100644 --- a/src/doc/reference/src/items/constant-items.md +++ b/src/doc/reference/src/items/constant-items.md @@ -89,6 +89,22 @@ m!(const _: () = ();); // const _: () = (); ``` +## Evaluation + +[Free][free] constants are always [evaluated][const_eval] at compile-time to surface +panics. This happens even within an unused function: + +```rust,compile_fail +// Compile-time panic +const PANIC: () = std::unimplemented!(); + +fn unused_generic_function<T>() { + // A failing compile-time assertion + const _: () = assert!(usize::BITS == 0); +} +``` + +[const_eval]: ../const_eval.md [associated constant]: ../items/associated-items.md#associated-constants [constant value]: ../const_eval.md#constant-expressions [free]: ../glossary.md#free-item diff --git a/src/doc/reference/src/items/unions.md b/src/doc/reference/src/items/unions.md index 325b22717..3c6c83d50 100644 --- a/src/doc/reference/src/items/unions.md +++ b/src/doc/reference/src/items/unions.md @@ -55,13 +55,13 @@ let f = unsafe { u.f1 }; ## Reading and writing union fields Unions have no notion of an "active field". Instead, every union access just -interprets the storage at the type of the field used for the access. Reading a +interprets the storage as the type of the field used for the access. Reading a union field reads the bits of the union at the field's type. Fields might have a non-zero offset (except when [the C representation] is used); in that case the bits starting at the offset of the fields are read. It is the programmer's responsibility to make sure that the data is valid at the field's type. Failing to do so results in [undefined behavior]. For example, reading the value `3` -through of a field of the [boolean type] is undefined behavior. Effectively, +from a field of the [boolean type] is undefined behavior. Effectively, writing to and then reading from a union with [the C representation] is analogous to a [`transmute`] from the type used for writing to the type used for reading. diff --git a/src/doc/reference/src/names/namespaces.md b/src/doc/reference/src/names/namespaces.md index 14811697c..bb4409b73 100644 --- a/src/doc/reference/src/names/namespaces.md +++ b/src/doc/reference/src/names/namespaces.md @@ -52,6 +52,7 @@ The following is a list of namespaces, with their corresponding entities: * [Generic lifetime parameters] * Label Namespace * [Loop labels] + * [Block labels] An example of how overlapping names in different namespaces can be used unambiguously: @@ -132,6 +133,7 @@ It is still an error for a [`use` import] to shadow another macro, regardless of [Attribute macros]: ../procedural-macros.md#attribute-macros [attributes]: ../attributes.md [bang-style macros]: ../macros.md +[Block labels]: ../expressions/loop-expr.md#labelled-block-expressions [boolean]: ../types/boolean.md [Built-in attributes]: ../attributes.md#built-in-attributes-index [closure parameters]: ../expressions/closure-expr.md diff --git a/src/doc/rust-by-example/src/crates/lib.md b/src/doc/rust-by-example/src/crates/lib.md index 44593f3bb..729ccb890 100644 --- a/src/doc/rust-by-example/src/crates/lib.md +++ b/src/doc/rust-by-example/src/crates/lib.md @@ -2,6 +2,8 @@ Let's create a library, and then see how to link it to another crate. +In `rary.rs`: + ```rust,ignore pub fn public_function() { println!("called rary's `public_function()`"); diff --git a/src/doc/rust-by-example/src/flow_control/match/guard.md b/src/doc/rust-by-example/src/flow_control/match/guard.md index 63008a743..af81f64c9 100644 --- a/src/doc/rust-by-example/src/flow_control/match/guard.md +++ b/src/doc/rust-by-example/src/flow_control/match/guard.md @@ -3,6 +3,7 @@ A `match` *guard* can be added to filter the arm. ```rust,editable +#[allow(dead_code)] enum Temperature { Celsius(i32), Fahrenheit(i32), diff --git a/src/doc/rust-by-example/src/hello/print.md b/src/doc/rust-by-example/src/hello/print.md index 55f6ed520..d578337ad 100644 --- a/src/doc/rust-by-example/src/hello/print.md +++ b/src/doc/rust-by-example/src/hello/print.md @@ -39,7 +39,6 @@ fn main() { println!("Base 16 (hexadecimal): {:x}", 69420); // 10f2c println!("Base 16 (hexadecimal): {:X}", 69420); // 10F2C - // You can right-justify text with a specified width. This will // output " 1". (Four white spaces and a "1", for a total width of 5.) println!("{number:>5}", number=1); @@ -51,7 +50,6 @@ fn main() { // You can use named arguments in the format specifier by appending a `$`. println!("{number:0>width$}", number=1, width=5); - // Rust even checks to make sure the correct number of arguments are used. println!("My name is {0}, {1} {0}", "Bond"); // FIXME ^ Add the missing argument: "James" diff --git a/src/doc/rust-by-example/src/hello/print/fmt.md b/src/doc/rust-by-example/src/hello/print/fmt.md index 5332b4903..c3c78f6b1 100644 --- a/src/doc/rust-by-example/src/hello/print/fmt.md +++ b/src/doc/rust-by-example/src/hello/print/fmt.md @@ -49,17 +49,17 @@ fn main() { City { name: "Dublin", lat: 53.347778, lon: -6.259722 }, City { name: "Oslo", lat: 59.95, lon: 10.75 }, City { name: "Vancouver", lat: 49.25, lon: -123.1 }, - ].iter() { - println!("{}", *city); + ] { + println!("{}", city); } for color in [ Color { red: 128, green: 255, blue: 90 }, Color { red: 0, green: 3, blue: 254 }, Color { red: 0, green: 0, blue: 0 }, - ].iter() { + ] { // Switch this to use {} once you've added an implementation // for fmt::Display. - println!("{:?}", *color); + println!("{:?}", color); } } ``` diff --git a/src/doc/rust-by-example/src/macros.md b/src/doc/rust-by-example/src/macros.md index 3f12fcc41..f01cf8dc7 100644 --- a/src/doc/rust-by-example/src/macros.md +++ b/src/doc/rust-by-example/src/macros.md @@ -16,12 +16,12 @@ macro_rules! say_hello { // `()` indicates that the macro takes no argument. () => { // The macro will expand into the contents of this block. - println!("Hello!"); + println!("Hello!") }; } fn main() { - // This call will expand into `println!("Hello");` + // This call will expand into `println!("Hello")` say_hello!() } ``` diff --git a/src/doc/rust-by-example/src/primitives/array.md b/src/doc/rust-by-example/src/primitives/array.md index 3811bb6d7..9cec24d69 100644 --- a/src/doc/rust-by-example/src/primitives/array.md +++ b/src/doc/rust-by-example/src/primitives/array.md @@ -63,7 +63,7 @@ fn main() { } } - // Out of bound indexing causes runtime error. + // Out of bound indexing causes compile time error. //println!("{}", xs[5]); } ``` diff --git a/src/doc/rust-by-example/src/scope/lifetime.md b/src/doc/rust-by-example/src/scope/lifetime.md index 01c4bf405..68b42d380 100644 --- a/src/doc/rust-by-example/src/scope/lifetime.md +++ b/src/doc/rust-by-example/src/scope/lifetime.md @@ -1,6 +1,6 @@ # Lifetimes -A *lifetime* is a construct the compiler (or more specifically, its *borrow +A *lifetime* is a construct of the compiler (or more specifically, its *borrow checker*) uses to ensure all borrows are valid. Specifically, a variable's lifetime begins when it is created and ends when it is destroyed. While lifetimes and scopes are often referred to together, they are not the same. diff --git a/src/doc/rust-by-example/src/scope/raii.md b/src/doc/rust-by-example/src/scope/raii.md index 7b6bca618..6d94b0713 100644 --- a/src/doc/rust-by-example/src/scope/raii.md +++ b/src/doc/rust-by-example/src/scope/raii.md @@ -41,6 +41,8 @@ fn main() { Of course, we can double check for memory errors using [`valgrind`][valgrind]: +<!-- REUSE-IgnoreStart --> +<!-- Prevent REUSE from parsing the copyright statement in the sample code --> ```shell $ rustc raii.rs && valgrind ./raii ==26873== Memcheck, a memory error detector @@ -58,6 +60,7 @@ $ rustc raii.rs && valgrind ./raii ==26873== For counts of detected and suppressed errors, rerun with: -v ==26873== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) ``` +<!-- REUSE-IgnoreEnd --> No leaks here! diff --git a/src/doc/rust-by-example/src/std/panic.md b/src/doc/rust-by-example/src/std/panic.md index b22000494..d08d1f4e2 100644 --- a/src/doc/rust-by-example/src/std/panic.md +++ b/src/doc/rust-by-example/src/std/panic.md @@ -34,6 +34,8 @@ fn main() { Let's check that `panic!` doesn't leak memory. +<!-- REUSE-IgnoreStart --> +<!-- Prevent REUSE from parsing the copyright statement in the sample code --> ```shell $ rustc panic.rs && valgrind ./panic ==4401== Memcheck, a memory error detector @@ -52,3 +54,4 @@ thread '<main>' panicked at 'division by zero', panic.rs:5 ==4401== For counts of detected and suppressed errors, rerun with: -v ==4401== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ``` +<!-- REUSE-IgnoreEnd --> diff --git a/src/doc/rust-by-example/src/std_misc/file/read_lines.md b/src/doc/rust-by-example/src/std_misc/file/read_lines.md index 641eb972a..216b0181c 100644 --- a/src/doc/rust-by-example/src/std_misc/file/read_lines.md +++ b/src/doc/rust-by-example/src/std_misc/file/read_lines.md @@ -1,44 +1,51 @@ # `read_lines` -## Beginner friendly method -This method is NOT efficient. It's here for beginners -who can't understand the efficient method yet. +## A naive approach -```rust,no_run -use std::fs::File; -use std::io::{ self, BufRead, BufReader }; +This might be a reasonable first attempt for a beginner's first +implementation for reading lines from a file. -fn read_lines(filename: String) -> io::Lines<BufReader<File>> { - // Open the file in read-only mode. - let file = File::open(filename).unwrap(); - // Read the file line by line, and return an iterator of the lines of the file. - return io::BufReader::new(file).lines(); -} +```rust,norun +use std::fs::read_to_string; -fn main() { - // Stores the iterator of lines of the file in lines variable. - let lines = read_lines("./hosts".to_string()); - // Iterate over the lines of the file, and in this case print them. - for line in lines { - println!("{}", line.unwrap()); +fn read_lines(filename: &str) -> Vec<String> { + let mut result = Vec::new(); + + for line in read_to_string(filename).unwrap().lines() { + result.push(line.to_string()) } + + result } ``` -Running this program simply prints the lines individually. -```shell -$ echo -e "127.0.0.1\n192.168.0.1\n" > hosts -$ rustc read_lines.rs && ./read_lines -127.0.0.1 -192.168.0.1 +Since the method `lines()` returns an iterator over the lines in the file, +we can also perform a map inline and collect the results, yielding a more +concise and fluent expression. + +```rust,norun +use std::fs::read_to_string; + +fn read_lines(filename: &str) -> Vec<String> { + read_to_string(filename) + .unwrap() // panic on possible file-reading errors + .lines() // split the string into an iterator of string slices + .map(String::from) // make each slice into a string + .collect() // gather them together into a vector +} ``` -## Efficient method -The method `lines()` returns an iterator over the lines -of a file. +Note that in both examples above, we must convert the `&str` reference +returned from `lines()` to the owned type `String`, using `.to_string()` +and `String::from` respectively. -`File::open` expects a generic, `AsRef<Path>`. That's what -`read_lines()` expects as input. +## A more efficient approach + +Here we pass ownership of the open `File` to a `BufReader` struct. `BufReader` uses an internal +buffer to reduce intermediate allocations. + +We also update `read_lines` to return an iterator instead of allocating new +`String` objects in memory for each line. ```rust,no_run use std::fs::File; @@ -46,8 +53,8 @@ use std::io::{self, BufRead}; use std::path::Path; fn main() { - // File hosts must exist in current path before this produces output - if let Ok(lines) = read_lines("./hosts") { + // File hosts.txt must exist in the current path + if let Ok(lines) = read_lines("./hosts.txt") { // Consumes the iterator, returns an (Optional) String for line in lines { if let Ok(ip) = line { @@ -68,11 +75,15 @@ where P: AsRef<Path>, { Running this program simply prints the lines individually. ```shell -$ echo -e "127.0.0.1\n192.168.0.1\n" > hosts +$ echo -e "127.0.0.1\n192.168.0.1\n" > hosts.txt $ rustc read_lines.rs && ./read_lines 127.0.0.1 192.168.0.1 ``` -This process is more efficient than creating a `String` in memory -especially working with larger files.
\ No newline at end of file +(Note that since `File::open` expects a generic `AsRef<Path>` as argument, we define our +generic `read_lines()` method with the same generic constraint, using the `where` keyword.) + +This process is more efficient than creating a `String` in memory with all of the file's +contents. This can especially cause performance issues when working with larger files. + diff --git a/src/doc/rust-by-example/src/unsafe/asm.md b/src/doc/rust-by-example/src/unsafe/asm.md index 7ad6e0c5e..1a3fab904 100644 --- a/src/doc/rust-by-example/src/unsafe/asm.md +++ b/src/doc/rust-by-example/src/unsafe/asm.md @@ -18,11 +18,13 @@ Inline assembly is currently supported on the following architectures: Let us start with the simplest possible example: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; unsafe { asm!("nop"); } +# } ``` This will insert a NOP (no operation) instruction into the assembly generated by the compiler. @@ -36,6 +38,7 @@ Now inserting an instruction that does nothing is rather boring. Let us do somet actually acts on data: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; let x: u64; @@ -43,6 +46,7 @@ unsafe { asm!("mov {}, 5", out(reg) x); } assert_eq!(x, 5); +# } ``` This will write the value `5` into the `u64` variable `x`. @@ -61,6 +65,7 @@ the template and will read the variable from there after the inline assembly fin Let us see another example that also uses an input: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; let i: u64 = 3; @@ -74,6 +79,7 @@ unsafe { ); } assert_eq!(o, 8); +# } ``` This will add `5` to the input in variable `i` and write the result to variable `o`. @@ -97,6 +103,7 @@ readability, and allows reordering instructions without changing the argument or We can further refine the above example to avoid the `mov` instruction: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; let mut x: u64 = 3; @@ -104,6 +111,7 @@ unsafe { asm!("add {0}, 5", inout(reg) x); } assert_eq!(x, 8); +# } ``` We can see that `inout` is used to specify an argument that is both input and output. @@ -112,6 +120,7 @@ This is different from specifying an input and output separately in that it is g It is also possible to specify different variables for the input and output parts of an `inout` operand: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; let x: u64 = 3; @@ -120,6 +129,7 @@ unsafe { asm!("add {0}, 5", inout(reg) x => y); } assert_eq!(y, 8); +# } ``` ## Late output operands @@ -135,6 +145,7 @@ There is also a `inlateout` variant of this specifier. Here is an example where `inlateout` *cannot* be used in `release` mode or other optimized cases: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; let mut a: u64 = 4; @@ -150,6 +161,7 @@ unsafe { ); } assert_eq!(a, 12); +# } ``` The above could work well in unoptimized cases (`Debug` mode), but if you want optimized performance (`release` mode or other optimized cases), it could not work. @@ -158,6 +170,7 @@ That is because in optimized cases, the compiler is free to allocate the same re However the following example can use `inlateout` since the output is only modified after all input registers have been read: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; let mut a: u64 = 4; @@ -166,6 +179,7 @@ unsafe { asm!("add {0}, {1}", inlateout(reg) a, in(reg) b); } assert_eq!(a, 8); +# } ``` As you can see, this assembly fragment will still work correctly if `a` and `b` are assigned to the same register. @@ -177,12 +191,14 @@ Therefore, Rust inline assembly provides some more specific constraint specifier While `reg` is generally available on any architecture, explicit registers are highly architecture specific. E.g. for x86 the general purpose registers `eax`, `ebx`, `ecx`, `edx`, `ebp`, `esi`, and `edi` among others can be addressed by their name. ```rust,no_run +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; let cmd = 0xd1; unsafe { asm!("out 0x64, eax", in("eax") cmd); } +# } ``` In this example we call the `out` instruction to output the content of the `cmd` variable to port `0x64`. Since the `out` instruction only accepts `eax` (and its sub registers) as operand we had to use the `eax` constraint specifier. @@ -192,6 +208,7 @@ In this example we call the `out` instruction to output the content of the `cmd` Consider this example which uses the x86 `mul` instruction: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; fn mul(a: u64, b: u64) -> u128 { @@ -211,6 +228,7 @@ fn mul(a: u64, b: u64) -> u128 { ((hi as u128) << 64) + lo as u128 } +# } ``` This uses the `mul` instruction to multiply two 64-bit inputs with a 128-bit result. @@ -229,6 +247,7 @@ We need to tell the compiler about this since it may need to save and restore th ```rust use std::arch::asm; +# #[cfg(target_arch = "x86_64")] fn main() { // three entries of four bytes each let mut name_buf = [0_u8; 12]; @@ -262,6 +281,9 @@ fn main() { let name = core::str::from_utf8(&name_buf).unwrap(); println!("CPU Manufacturer ID: {}", name); } + +# #[cfg(not(target_arch = "x86_64"))] +# fn main() {} ``` In the example above we use the `cpuid` instruction to read the CPU manufacturer ID. @@ -269,13 +291,14 @@ This instruction writes to `eax` with the maximum supported `cpuid` argument and Even though `eax` is never read we still need to tell the compiler that the register has been modified so that the compiler can save any values that were in these registers before the asm. This is done by declaring it as an output but with `_` instead of a variable name, which indicates that the output value is to be discarded. -This code also works around the limitation that `ebx` is a reserved register by LLVM. That means that LLVM assumes that it has full control over the register and it must be restored to its original state before exiting the asm block, so it cannot be used as an input or output **except** if the compiler uses it to fulfill a general register class (e.g. `in(reg)`). This makes `reg` operands dangerous when using reserved registers as we could unknowingly corrupt out input or output because they share the same register. +This code also works around the limitation that `ebx` is a reserved register by LLVM. That means that LLVM assumes that it has full control over the register and it must be restored to its original state before exiting the asm block, so it cannot be used as an input or output **except** if the compiler uses it to fulfill a general register class (e.g. `in(reg)`). This makes `reg` operands dangerous when using reserved registers as we could unknowingly corrupt our input or output because they share the same register. -To work around this we use `rdi` to store the pointer to the output array, save `ebx` via `push`, read from `ebx` inside the asm block into the array and then restoring `ebx` to its original state via `pop`. The `push` and `pop` use the full 64-bit `rbx` version of the register to ensure that the entire register is saved. On 32 bit targets the code would instead use `ebx` in the `push`/`pop`. +To work around this we use `rdi` to store the pointer to the output array, save `ebx` via `push`, read from `ebx` inside the asm block into the array and then restore `ebx` to its original state via `pop`. The `push` and `pop` use the full 64-bit `rbx` version of the register to ensure that the entire register is saved. On 32 bit targets the code would instead use `ebx` in the `push`/`pop`. This can also be used with a general register class to obtain a scratch register for use inside the asm code: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; // Multiply x by 6 using shifts and adds @@ -291,6 +314,7 @@ unsafe { ); } assert_eq!(x, 4 * 6); +# } ``` ## Symbol operands and ABI clobbers @@ -300,6 +324,7 @@ By default, `asm!` assumes that any register not specified as an output will hav [`clobber_abi`]: ../../reference/inline-assembly.html#abi-clobbers ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; extern "C" fn foo(arg: i32) -> i32 { @@ -325,6 +350,7 @@ fn call_foo(arg: i32) -> i32 { result } } +# } ``` ## Register template modifiers @@ -336,6 +362,7 @@ By default the compiler will always choose the name that refers to the full regi This default can be overridden by using modifiers on the template string operands, just like you would with format strings: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; let mut x: u16 = 0xab; @@ -345,6 +372,7 @@ unsafe { } assert_eq!(x, 0xabab); +# } ``` In this example, we use the `reg_abcd` register class to restrict the register allocator to the 4 legacy x86 registers (`ax`, `bx`, `cx`, `dx`) of which the first two bytes can be addressed independently. @@ -361,6 +389,7 @@ You have to manually use the memory address syntax specified by the target archi For example, on x86/x86_64 using Intel assembly syntax, you should wrap inputs/outputs in `[]` to indicate they are memory operands: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; fn load_fpu_control_word(control: u16) { @@ -368,6 +397,7 @@ fn load_fpu_control_word(control: u16) { asm!("fldcw [{}]", in(reg) &control, options(nostack)); } } +# } ``` ## Labels @@ -383,6 +413,7 @@ As a consequence, you should only use GNU assembler **numeric** [local labels] i Moreover, on x86 when using the default Intel syntax, due to [an LLVM bug], you shouldn't use labels exclusively made of `0` and `1` digits, e.g. `0`, `11` or `101010`, as they may end up being interpreted as binary values. Using `options(att_syntax)` will avoid any ambiguity, but that affects the syntax of the _entire_ `asm!` block. (See [Options](#options), below, for more on `options`.) ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; let mut a = 0; @@ -400,6 +431,7 @@ unsafe { ); } assert_eq!(a, 5); +# } ``` This will decrement the `{0}` register value from 10 to 3, then add 2 and store it in `a`. @@ -419,6 +451,7 @@ By default, an inline assembly block is treated the same way as an external FFI Let's take our previous example of an `add` instruction: ```rust +# #[cfg(target_arch = "x86_64")] { use std::arch::asm; let mut a: u64 = 4; @@ -431,6 +464,7 @@ unsafe { ); } assert_eq!(a, 8); +# } ``` Options can be provided as an optional final argument to the `asm!` macro. We specified three options here: diff --git a/src/doc/rust-by-example/src/variable_bindings/mut.md b/src/doc/rust-by-example/src/variable_bindings/mut.md index 0925132f2..c75f034ec 100644 --- a/src/doc/rust-by-example/src/variable_bindings/mut.md +++ b/src/doc/rust-by-example/src/variable_bindings/mut.md @@ -15,9 +15,8 @@ fn main() { println!("After mutation: {}", mutable_binding); - // Error! + // Error! Cannot assign a new value to an immutable variable _immutable_binding += 1; - // FIXME ^ Comment out this line } ``` diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml index 2346698d4..bb0493bf7 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml @@ -46,7 +46,7 @@ jobs: if: github.event_name != 'push' run: | shopt -s globstar - MAX_LINE_LENGTH=100 bash ci/check_line_lengths.sh src/**/*.md + MAX_LINE_LENGTH=100 bash ci/lengthcheck.sh src/**/*.md - name: Install latest nightly Rust toolchain if: steps.mdbook-cache.outputs.cache-hit != 'true' diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index e501c9161..fdf6c5050 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -49,10 +49,10 @@ To build a local static HTML site, install [`mdbook`](https://github.com/rust-la and execute the following command in the root of the repository: ``` -> mdbook build +> mdbook build --open ``` -The build files are found in the `book` directory. +The build files are found in the `book/html` directory. ### Link Validations @@ -67,20 +67,20 @@ including the `<!-- toc -->` marker at the place where you want the TOC. ### Pre-commit script We also test that line lengths are less than 100 columns. To test this locally, -you can run `ci/check_line_lengths.sh`. +you can run `ci/lengthcheck.sh`. You can also set this to run automatically. On Linux: ```bash -ln -s ../../ci/check_line_lengths.sh .git/hooks/pre-commit +ln -s ../../ci/lengthcheck.sh .git/hooks/pre-commit ``` On Windows: ```powershell -New-Item -Path .git/hooks/pre-commit -ItemType HardLink -Value <absolute_path/to/check_line_lengths.sh> +New-Item -Path .git/hooks/pre-commit -ItemType HardLink -Value $(Resolve-Path ci/lengthcheck.sh) ``` ## How to fix toolstate failures diff --git a/src/doc/rustc-dev-guide/book.toml b/src/doc/rustc-dev-guide/book.toml index a5d794b50..203bfd61e 100644 --- a/src/doc/rustc-dev-guide/book.toml +++ b/src/doc/rustc-dev-guide/book.toml @@ -43,10 +43,8 @@ exclude = [ cache-timeout = 86400 warning-policy = "error" -[output.linkcheck.http-headers] -'github\.com' = ["Authorization: Bearer $GITHUB_TOKEN"] - [output.html.redirect] "/compiletest.html" = "tests/compiletest.html" -"/diagnostics/sessiondiagnostic.html" = "diagnostics/diagnostic-structs.html" +"/diagnostics/sessiondiagnostic.html" = "diagnostic-structs.html" +"/diagnostics/diagnostic-codes.html" = "error-codes.html" "/miri.html" = "const-eval/interpret.html" diff --git a/src/doc/rustc-dev-guide/ci/check_line_lengths.sh b/src/doc/rustc-dev-guide/ci/lengthcheck.sh index 31cda5c65..76d677be7 100755 --- a/src/doc/rustc-dev-guide/ci/check_line_lengths.sh +++ b/src/doc/rustc-dev-guide/ci/lengthcheck.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +# Check files for lines that are too long. + if [ "$1" == "--help" ]; then echo 'Usage:' "[MAX_LINE_LENGTH=n] $0 [file ...]" exit 1 @@ -10,8 +12,7 @@ if [ "$MAX_LINE_LENGTH" == "" ]; then fi if [ "$1" == "" ]; then - shopt -s globstar - files=( src/**/*.md ) + files=( src/*.md src/*/*.md src/*/*/*.md ) else files=( "$@" ) fi @@ -22,7 +23,6 @@ echo "Offending files and lines:" (( bad_lines = 0 )) (( inside_block = 0 )) for file in "${files[@]}"; do - echo "$file" (( line_no = 0 )) while IFS="" read -r line || [[ -n "$line" ]] ; do (( line_no++ )) @@ -34,7 +34,7 @@ for file in "${files[@]}"; do && ! [[ "$line" =~ " | "|"-|-"|"://"|"]:"|\[\^[^\ ]+\]: ]] \ && (( "${#line}" > $MAX_LINE_LENGTH )) ; then (( bad_lines++ )) - echo -e "\t$line_no : $line" + echo -e "\t$file:$line_no : $line" fi done < "$file" done diff --git a/src/doc/rustc-dev-guide/ci/linkcheck.sh b/src/doc/rustc-dev-guide/ci/linkcheck.sh index 5d49d1337..133e22239 100755 --- a/src/doc/rustc-dev-guide/ci/linkcheck.sh +++ b/src/doc/rustc-dev-guide/ci/linkcheck.sh @@ -3,12 +3,16 @@ set -e set -o pipefail +set_github_token() { + jq '.config.output.linkcheck."http-headers"."github\\.com" = ["Authorization: Bearer $GITHUB_TOKEN"]' +} + # https://docs.github.com/en/actions/reference/environment-variables if [ "$GITHUB_EVENT_NAME" = "schedule" ] ; then # running in scheduled job FLAGS="" + USE_TOKEN=1 echo "Doing full link check." - set -x elif [ "$GITHUB_EVENT_NAME" = "pull_request" ] ; then # running in PR CI build if [ -z "$BASE_SHA" ]; then echo "error: unexpected state: BASE_SHA must be non-empty in CI" @@ -17,9 +21,9 @@ elif [ "$GITHUB_EVENT_NAME" = "pull_request" ] ; then # running in PR CI build CHANGED_FILES=$(git diff --name-only $BASE_SHA... | tr '\n' ' ') FLAGS="--no-cache -f $CHANGED_FILES" + USE_TOKEN=1 echo "Checking files changed since $BASE_SHA: $CHANGED_FILES" - set -x else # running locally COMMIT_RANGE=master... CHANGED_FILES=$(git diff --name-only $COMMIT_RANGE | tr '\n' ' ') @@ -28,4 +32,10 @@ else # running locally echo "Checking files changed in $COMMIT_RANGE: $CHANGED_FILES" fi -exec mdbook-linkcheck $FLAGS +echo "exec mdbook-linkcheck $FLAGS" +if [ "$USE_TOKEN" = 1 ]; then + config=$(set_github_token) + exec mdbook-linkcheck $FLAGS <<<"$config" +else + exec mdbook-linkcheck $FLAGS +fi diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs index 9708ab01d..70e77fd5b 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs @@ -42,9 +42,10 @@ fn main() { "# .into(), }, - output_dir: None, // Option<PathBuf> - output_file: None, // Option<PathBuf> - file_loader: None, // Option<Box<dyn FileLoader + Send + Sync>> + output_dir: None, // Option<PathBuf> + output_file: None, // Option<PathBuf> + file_loader: None, // Option<Box<dyn FileLoader + Send + Sync>> + locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES, lint_caps: FxHashMap::default(), // FxHashMap<lint::LintId, lint::Level> // This is a callback from the driver that is called when [`ParseSess`] is created. parse_sess_created: None, //Option<Box<dyn FnOnce(&mut ParseSess) + Send>> diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs index 5bc2312a2..888674aaf 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs @@ -66,6 +66,7 @@ fn main() { output_dir: None, output_file: None, file_loader: None, + locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES, lint_caps: rustc_hash::FxHashMap::default(), parse_sess_created: None, register_lints: None, diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs index 53f8df81a..df0e0385d 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs @@ -44,6 +44,7 @@ fn main() { output_dir: None, output_file: None, file_loader: None, + locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES, lint_caps: rustc_hash::FxHashMap::default(), parse_sess_created: None, register_lints: None, diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index adc397fd8..b01cb6797 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -1,8 +1,7 @@ # Summary -[About this guide](./about-this-guide.md) - [Getting Started](./getting-started.md) +[About this guide](./about-this-guide.md) --- @@ -35,17 +34,19 @@ # Contributing to Rust -- [Introduction](./contributing.md) +- [Contribution Procedures](./contributing.md) - [About the compiler team](./compiler-team.md) - [Using Git](./git.md) - [Mastering @rustbot](./rustbot.md) - [Walkthrough: a typical contribution](./walkthrough.md) -- [Bug Fix Procedure](./bug-fix-procedure.md) +- [Procedures for Breaking Changes](./bug-fix-procedure.md) - [Implementing new features](./implementing_new_features.md) - [Stability attributes](./stability.md) - [Stabilizing Features](./stabilization_guide.md) - [Feature Gates](./feature-gates.md) - [Coding conventions](./conventions.md) +- [Using external repositories](./external-repos.md) +- [Fuzzing](./fuzzing.md) - [Notification groups](notification-groups/about.md) - [ARM](notification-groups/arm.md) - [Cleanup Crew](notification-groups/cleanup-crew.md) @@ -146,7 +147,7 @@ - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md) - [Translation](./diagnostics/translation.md) - [`LintStore`](./diagnostics/lintstore.md) - - [Diagnostic codes](./diagnostics/diagnostic-codes.md) + - [Error codes](./diagnostics/error-codes.md) - [Diagnostic items](./diagnostics/diagnostic-items.md) - [`ErrorGuaranteed`](./diagnostics/error-guaranteed.md) diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md index 71407854e..944ebf5a8 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -58,14 +58,51 @@ please see the corresponding [subsection on writing documentation in this guide] You might also find the following sites useful: -- [rustc API docs] -- rustdoc documentation for the compiler +- This guide contains information about how various parts of the + compiler work and how to contribute to the compiler. +- [rustc API docs] -- rustdoc documentation for the compiler, devtools, and internal tools - [Forge] -- contains documentation about Rust infrastructure, team procedures, and more - [compiler-team] -- the home-base for the Rust compiler team, with description of the team procedures, active working groups, and the team calendar. - [std-dev-guide] -- a similar guide for developing the standard library. +- [The t-compiler zulip][z] +- [The Forge](https://forge.rust-lang.org/) has more documentation about various procedures. +- `#contribute` and `#wg-rustup` on [Discord](https://discord.gg/rust-lang). +- The [Rust Internals forum][rif], a place to ask questions and + discuss Rust's internals +- The [Rust reference][rr], even though it doesn't specifically talk about + Rust's internals, is a great resource nonetheless +- Although out of date, [Tom Lee's great blog article][tlgba] is very helpful +- [rustaceans.org][ro] is helpful, but mostly dedicated to IRC +- The [Rust Compiler Testing Docs][rctd] +- For [@bors], [this cheat sheet][cheatsheet] is helpful +- Google is always helpful when programming. + You can [search all Rust documentation][gsearchdocs] (the standard library, + the compiler, the books, the references, and the guides) to quickly find + information about the language and compiler. +- You can also use Rustdoc's built-in search feature to find documentation on + types and functions within the crates you're looking at. You can also search + by type signature! For example, searching for `* -> vec` should find all + functions that return a `Vec<T>`. + _Hint:_ Find more tips and keyboard shortcuts by typing `?` on any Rustdoc + page! + +[rustc dev guide]: about-this-guide.md +[gsearchdocs]: https://www.google.com/search?q=site:doc.rust-lang.org+your+query+here +[stddocs]: https://doc.rust-lang.org/std +[rif]: http://internals.rust-lang.org +[rr]: https://doc.rust-lang.org/book/README.html +[rustforge]: https://forge.rust-lang.org/ +[tlgba]: https://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/ +[ro]: https://www.rustaceans.org/ +[rctd]: tests/intro.md +[cheatsheet]: https://bors.rust-lang.org/ +[Miri]: https://github.com/rust-lang/miri +[@bors]: https://github.com/bors [GitHub repository]: https://github.com/rust-lang/rustc-dev-guide/ -[rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ +[rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle [Forge]: https://forge.rust-lang.org/ [compiler-team]: https://github.com/rust-lang/compiler-team/ [std-dev-guide]: https://std-dev-guide.rust-lang.org/ +[z]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler diff --git a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md index 5e005c965..b92a40b8b 100644 --- a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md +++ b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md @@ -103,9 +103,8 @@ The hash includes a variety of elements: * Hashes of the HIR nodes. * All of the upstream crate hashes. * All of the source filenames. -* Hashes of certain command-line flags (like `-C metadata` via the [Crate - Disambiguator](#crate-disambiguator), and all CLI options marked with - `[TRACKED]`). +* Hashes of certain command-line flags (like `-C metadata` via the [Stable + Crate Id](#stable-crate-id), and all CLI options marked with `[TRACKED]`). See [`compute_hir_hash`] for where the hash is actually computed. diff --git a/src/doc/rustc-dev-guide/src/backend/monomorph.md b/src/doc/rustc-dev-guide/src/backend/monomorph.md index cbc56acfc..7726daf4f 100644 --- a/src/doc/rustc-dev-guide/src/backend/monomorph.md +++ b/src/doc/rustc-dev-guide/src/backend/monomorph.md @@ -99,7 +99,7 @@ are relatively rare in functions, but closures inherit the generic parameters of their parent function and it is common for closures to not use those inherited parameters. Without polymorphization, a copy of these closures would be created for each copy of the parent function. By -creating fewer copies, less LLVM IR is generated and needs processed. +creating fewer copies, less LLVM IR is generated; therefore less needs to be processed. `unused_generic_params` returns a `FiniteBitSet<u64>` where a bit is set if the generic parameter of the corresponding index is unused. Any parameters diff --git a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md index 2f5e24716..e69ce48f9 100644 --- a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md +++ b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md @@ -1,4 +1,4 @@ -# Rustc Bug Fix Procedure +# Procedures for Breaking Changes <!-- toc --> @@ -169,6 +169,13 @@ there were no errors before. #### Crater and crates.io +[Crater] is a bot that will compile all crates.io crates and many +public github repos with the compiler with your changes. A report will then be +generated with crates that ceased to compile with or began to compile with your +changes. Crater runs can take a few days to complete. + +[Crater]: ./tests/crater.md + We should always do a crater run to assess impact. It is polite and considerate to at least notify the authors of affected crates the breaking change. If we can submit PRs to fix the problem, so much the better. diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping.md b/src/doc/rustc-dev-guide/src/building/bootstrapping.md index fe34cb500..d53896f81 100644 --- a/src/doc/rustc-dev-guide/src/building/bootstrapping.md +++ b/src/doc/rustc-dev-guide/src/building/bootstrapping.md @@ -22,6 +22,13 @@ Note that this documentation mostly covers user-facing information. See ## Stages of bootstrapping +### Overview + +- Stage 0: the pre-compiled compiler +- Stage 1: from current code, by an earlier compiler +- Stage 2: the truly current compiler +- Stage 3: the same-result test + Compiling `rustc` is done in stages. Here's a diagram, adapted from Joshua Nelson's [talk on bootstrapping][rustconf22-talk] at RustConf 2022, with detailed explanations below. @@ -51,7 +58,7 @@ graph TD classDef with-s1c fill: lightgreen; ``` -### Stage 0 +### Stage 0: the pre-compiled compiler The stage0 compiler is usually the current _beta_ `rustc` compiler and its associated dynamic libraries, @@ -65,11 +72,11 @@ a compiler (with its set of dependencies) and its 'target' or 'object' libraries (`std` and `rustc`). Both are staged, but in a staggered manner. -### Stage 1 +### Stage 1: from current code, by an earlier compiler The rustc source code is then compiled with the stage0 compiler to produce the stage1 compiler. -### Stage 2 +### Stage 2: the truly current compiler We then rebuild our stage1 compiler with itself to produce the stage2 compiler. @@ -92,7 +99,7 @@ For development, you usually only want the `stage1` compiler, which you can build with `./x.py build library`. See [Building the compiler](./how-to-build-and-run.html#building-the-compiler). -### Stage 3 +### Stage 3: the same-result test Stage 3 is optional. To sanity check our new compiler, we can build the libraries with the stage2 compiler. The result ought @@ -249,6 +256,10 @@ So the stage2 compiler has to recompile `std` for the target. ### Why does only libstd use `cfg(bootstrap)`? +NOTE: for docs on `cfg(bootstrap)` itself, see [Complications of Bootstrapping][complications]. + +[complications]: #complications-of-bootstrapping + The `rustc` generated by the stage0 compiler is linked to the freshly-built `std`, which means that for the most part only `std` needs to be cfg-gated, so that `rustc` can use features added to std immediately after their addition, @@ -258,7 +269,7 @@ Note this is different from any other Rust program: stage1 `rustc` is built by the _beta_ compiler, but using the _master_ version of libstd! The only time `rustc` uses `cfg(bootstrap)` is when it adds internal lints -that use diagnostic items. This happens very rarely. +that use diagnostic items, or when it uses unstable library features that were recently changed. ### What is a 'sysroot'? diff --git a/src/doc/rustc-dev-guide/src/building/compiler-documenting.md b/src/doc/rustc-dev-guide/src/building/compiler-documenting.md index 965e004c9..4e72bf994 100644 --- a/src/doc/rustc-dev-guide/src/building/compiler-documenting.md +++ b/src/doc/rustc-dev-guide/src/building/compiler-documenting.md @@ -31,6 +31,8 @@ like the standard library (std) or the compiler (rustc). ./x.py doc compiler library ``` + See [the nightly docs index page](https://doc.rust-lang.org/nightly/) for a full list of books. + - Document internal rustc items Compiler documentation is not built by default. diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index 6651b3691..59893bdc1 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -1,5 +1,7 @@ # How to build and run the compiler +<!-- toc --> + The compiler is built using a tool called `x.py`. You will need to have Python installed to run it. @@ -22,6 +24,29 @@ git clone https://github.com/rust-lang/rust.git cd rust ``` +### Shallow clone the repository + +Due to the size of the repository, cloning on a slower internet connection can take a long time. +To sidestep this, you can use the `--depth N` option with the `git clone` command. +This instructs `git` to perform a "shallow clone", cloning the repository but truncating it to +the last `N` commits. + +Passing `--depth 1` tells `git` to clone the repository but truncate the history to the latest +commit that is on the `master` branch, which is usually fine for browsing the source code or +building the compiler. + +```bash +git clone --depth 1 https://github.com/rust-lang/rust.git +cd rust +``` + +> **NOTE**: A shallow clone limits which `git` commands can be run. +> If you intend to work on and contribute to the compiler, it is +> generally recommended to fully clone the repository [as shown above](#get-the-source-code). +> +> For example, `git bisect` and `git blame` require access to the commit history, +> so they don't work if the repository was cloned with `--depth 1`. + ## What is `x.py`? `x.py` is the build tool for the `rust` repository. It can build docs, run tests, and compile the @@ -45,14 +70,41 @@ You can install it with `cargo install --path src/tools/x`. To start, run `./x.py setup`. This will do some initialization and create a `config.toml` for you with reasonable defaults. -Alternatively, you can write `config.toml` by hand. See `config.toml.example` for all the available +Alternatively, you can write `config.toml` by hand. See `config.example.toml` for all the available settings and explanations of them. See `src/bootstrap/defaults` for common settings to change. If you have already built `rustc` and you change settings related to LLVM, then you may have to execute `rm -rf build` for subsequent configuration changes to take effect. Note that `./x.py clean` will not cause a rebuild of LLVM. -## Building the compiler +## Common `x.py` commands + +Here are the basic invocations of the `x.py` commands most commonly used when +working on `rustc`, `std`, `rustdoc`, and other tools. + +| Command | When to use it | +| --- | --- | +| `./x.py check` | Quick check to see if most things compile; [rust-analyzer can run this automatically for you][rust-analyzer] | +| `./x.py build` | Builds `rustc`, `std`, and `rustdoc` | +| `./x.py test` | Runs all tests | +| `./x.py fmt` | Formats all code | + +As written, these commands are reasonable starting points. However, there are +additional options and arguments for each of them that are worth learning for +serious development work. In particular, `./x.py build` and `./x.py test` +provide many ways to compile or test a subset of the code, which can save a lot +of time. + +Also, note that `x.py` supports all kinds of path suffixes for `compiler`, `library`, +and `src/tools` directories. So, you can simply run `x.py test tidy` instead of +`x.py test src/tools/tidy`. Or, `x.py build std` instead of `x.py build library/std`. + +[rust-analyzer]: ./building/suggested.html#configuring-rust-analyzer-for-rustc + +See the chapters on [building](./building/how-to-build-and-run.md), +[testing](./tests/intro.md), and [rustdoc](./rustdoc.md) for more details. + +### Building the compiler Note that building will require a relatively large amount of storage space. You may want to have upwards of 10 or 15 gigabytes available to build the compiler. @@ -98,7 +150,7 @@ build. The **full** `rustc` build (what you get with `./x.py build You almost never need to do this. -## Build specific components +### Build specific components If you are working on the standard library, you probably don't need to build the compiler unless you are planning to use a recently added nightly feature. @@ -188,7 +240,7 @@ Note that building for some targets requires having external dependencies instal (e.g. building musl targets requires a local copy of musl). Any target-specific configuration (e.g. the path to a local copy of musl) will need to be provided by your `config.toml`. -Please see `config.toml.example` for information on target-specific configuration keys. +Please see `config.example.toml` for information on target-specific configuration keys. For examples of the complete configuration necessary to build a target, please visit [the rustc book](https://doc.rust-lang.org/rustc/platform-support.html), diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md index f999a9472..629445be6 100644 --- a/src/doc/rustc-dev-guide/src/building/new-target.md +++ b/src/doc/rustc-dev-guide/src/building/new-target.md @@ -4,6 +4,8 @@ These are a set of steps to add support for a new target. There are numerous end states and paths to get there, so not all sections may be relevant to your desired goal. +<!-- toc --> + ## Specifying a new LLVM For very new targets, you may need to use a different fork of LLVM diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index 2e2592094..3049d87db 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -3,6 +3,8 @@ The full bootstrapping process takes quite a while. Here are some suggestions to make your life easier. +<!-- toc --> + ## Installing a pre-push hook CI will automatically fail your build if it doesn't pass `tidy`, our @@ -24,20 +26,20 @@ You can also install the hook as a step of running `./x.py setup`! `rust-analyzer` can help you check and format your code whenever you save a file. By default, `rust-analyzer` runs the `cargo check` and `rustfmt` commands, but you can override these commands to use more adapted versions -of these tools when hacking on `rustc`. For example, `x.py setup` will prompt +of these tools when hacking on `rustc`. For example, `x.py setup vscode` will prompt you to create a `.vscode/settings.json` file which will configure Visual Studio code. This will ask `rust-analyzer` to use `./x.py check` to check the sources, and the stage 0 rustfmt to format them. -The recommended `rust-analyzer` settings live at [`src/etc/vscode_settings.json`]. +The recommended `rust-analyzer` settings live at [`src/etc/rust_analyzer_settings.json`]. If you have enough free disk space and you would like to be able to run `x.py` commands while rust-analyzer runs in the background, you can also add `--build-dir build-rust-analyzer` to the `overrideCommand` to avoid x.py locking. If you're running `coc.nvim`, you can use `:CocLocalConfig` to create a -`.vim/coc-settings.json` and copy the settings from [`src/etc/vscode_settings.json`]. +`.vim/coc-settings.json` and copy the settings from [`src/etc/rust_analyzer_settings.json`]. -[`src/etc/vscode_settings.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/vscode_settings.json +[`src/etc/rust_analyzer_settings.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_settings.json If running `./x.py check` on save is inconvenient, in VS Code you can use a [Build Task] instead: @@ -259,8 +261,8 @@ If you're using nix, you can use the following nix-shell to work on Rust: # This file contains a development shell for working on rustc. let - # Build configuration for rust-lang/rust. Based on `config.toml.example` from - # `1bd30ce2aac40c7698aa4a1b9520aa649ff2d1c5`. + # Build configuration for rust-lang/rust. Based on `config.example.toml` (then called + # `config.toml.example`) from `1bd30ce2aac40c7698aa4a1b9520aa649ff2d1c5` config = pkgs.writeText "rustc-config" '' profile = "compiler" # you may want to choose a different profile, like `library` or `tools` changelog-seen = 2 @@ -289,7 +291,7 @@ let # Files that are ignored by ripgrep when searching. ignoreFile = pkgs.writeText "rustc-rgignore" '' configure - config.toml.example + config.example.toml x.py LICENSE-MIT LICENSE-APACHE diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md index 6052ea58a..65c3cadbb 100644 --- a/src/doc/rustc-dev-guide/src/compiler-debugging.md +++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md @@ -42,7 +42,7 @@ otherwise you need to disable new symbol-mangling-version in `config.toml`. new-symbol-mangling = false ``` -> See the comments in `config.toml.example` for more info. +> See the comments in `config.example.toml` for more info. You will need to rebuild the compiler after changing any configuration option. @@ -269,7 +269,7 @@ on *why* it was changed. See [this tutorial][bisect-tutorial] on how to use it. [bisect]: https://github.com/rust-lang/cargo-bisect-rustc -[bisect-tutorial]: https://github.com/rust-lang/cargo-bisect-rustc/blob/master/TUTORIAL.md +[bisect-tutorial]: https://rust-lang.github.io/cargo-bisect-rustc/tutorial.html ## Downloading Artifacts from Rust's CI diff --git a/src/doc/rustc-dev-guide/src/const-eval/interpret.md b/src/doc/rustc-dev-guide/src/const-eval/interpret.md index ee044505e..fbf781b96 100644 --- a/src/doc/rustc-dev-guide/src/const-eval/interpret.md +++ b/src/doc/rustc-dev-guide/src/const-eval/interpret.md @@ -82,7 +82,7 @@ The next statement asserts that said boolean is `0`. In case the assertion fails, its error message is used for reporting a compile-time error. Since it does not fail, `Operand::Immediate(Immediate::Scalar(Scalar::Raw { -data: 4054, .. }))` is stored in the virtual memory was allocated before the +data: 4054, .. }))` is stored in the virtual memory it was allocated before the evaluation. `_0` always refers to that location directly. After the evaluation is done, the return value is converted from [`Operand`] to diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 383660fc1..d6037c7f1 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -1,32 +1,7 @@ -# Contributing to Rust - -Thank you for your interest in contributing to Rust! There are many ways to -contribute, and we appreciate all of them. +# Contribution Procedures <!-- toc --> -If you have questions, please make a post on [internals.rust-lang.org][internals] or -hop on the [Rust Discord server][rust-discord] or [Rust Zulip server][rust-zulip]. - -As a reminder, all contributors are expected to follow our [Code of Conduct][coc]. - -If this is your first time contributing, the [Getting Started] and -[walkthrough] chapters can give you a good example of how a typical -contribution would go. - -[internals]: https://internals.rust-lang.org -[rust-discord]: http://discord.gg/rust-lang -[rust-zulip]: https://rust-lang.zulipchat.com -[coc]: https://www.rust-lang.org/conduct.html -[walkthrough]: ./walkthrough.md -[Getting Started]: ./getting-started.md - -## Feature Requests - -Feature requests need to go through a process to be approved by the relevant -teams. Usually this requires a Final Comment Period (FCP) or even a Request for -Comments (RFC). See [Getting Started] for more information about these processes. - ## Bug Reports While bugs are unfortunate, they're a reality in software. We can't fix what we @@ -58,6 +33,80 @@ Opening an issue is as easy as following [this link](https://github.com/rust-lang/rust/issues/new/choose) and filling out the fields in the appropriate provided template. +## Bug Fixes or "Normal" code changes + +For most PRs, no special procedures are needed. You can just [open a PR][prs], and it +will be reviewed, approved, and merged. This includes most bug fixes, +refactorings, and other user-invisible changes. The next few sections talk +about exceptions to this rule. + +Also, note that it is perfectly acceptable to open WIP PRs or GitHub [Draft +PRs][draft]. Some people prefer to do this so they can get feedback along the +way or share their code with a collaborator. Others do this so they can utilize +the CI to build and test their PR (e.g. if you are developing on a laptop). + +[prs]: #pull-requests +[draft]: https://github.blog/2019-02-14-introducing-draft-pull-requests/ + +## New Features + +Rust has strong backwards-compatibility guarantees. Thus, new features can't +just be implemented directly in stable Rust. Instead, we have 3 release +channels: stable, beta, and nightly. + +- **Stable**: this is the latest stable release for general usage. +- **Beta**: this is the next release (will be stable within 6 weeks). +- **Nightly**: follows the `master` branch of the repo. This is the only + channel where unstable, incomplete, or experimental features are usable with + feature gates. + +See [this chapter on implementing new features](./implementing_new_features.md) for more +information. + +### Breaking Changes + +Breaking changes have a [dedicated section][breaking-changes] in the dev-guide. + +[breaking-changes]: ./bug-fix-procedure.md + +### Major Changes + +The compiler team has a special process for large changes, whether or not they +cause breakage. This process is called a Major Change Proposal (MCP). MCP is a +relatively lightweight mechanism for getting feedback on large changes to the +compiler (as opposed to a full RFC or a design meeting with the team). + +Example of things that might require MCPs include major refactorings, changes +to important types, or important changes to how the compiler does something, or +smaller user-facing changes. + +**When in doubt, ask on [zulip][z]. It would be a shame to put a lot of work +into a PR that ends up not getting merged!** [See this document][mcpinfo] for +more info on MCPs. + +[mcpinfo]: https://forge.rust-lang.org/compiler/mcp.html +[z]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler + +### Performance + +Compiler performance is important. We have put a lot of effort over the last +few years into [gradually improving it][perfdash]. + +[perfdash]: https://perf.rust-lang.org/dashboard.html + +If you suspect that your change may cause a performance regression (or +improvement), you can request a "perf run" (your reviewer may also request one +before approving). This is yet another bot that will compile a collection of +benchmarks on a compiler with your changes. The numbers are reported +[here][perf], and you can see a comparison of your changes against the latest +master. + +For an introduction to the performance of Rust code in general +which would also be useful in rustc development, see [The Rust Performance Book]. + +[perf]: https://perf.rust-lang.org +[The Rust Performance Book]: https://nnethercote.github.io/perf-book/ + ## Pull Requests Pull requests (or PRs for short) are the primary mechanism we use to change Rust. @@ -96,6 +145,42 @@ For a full list of possible `groupname` check the `adhoc_groups` section at the or the list of teams in the [rust-lang teams database](https://github.com/rust-lang/team/tree/master/teams). +### Waiting for reviews + +> NOTE +> +> Pull request reviewers are often working at capacity, +> and many of them are contributing on a volunteer basis. +> In order to minimize review delays, +> pull request authors and assigned reviewers should ensure that the review label +> (`S-waiting-on-review` and `S-waiting-on-author`) stays updated, +> invoking these commands when appropriate: +> +> - `@rustbot author`: +> the review is finished, +> and PR author should check the comments and take action accordingly. +> +> - `@rustbot review`: +> the author is ready for a review, +> and this PR will be queued again in the reviewer's queue. + +Please note that the reviewers are humans, who for the most part work on `rustc` +in their free time. This means that they can take some time to respond and review +your PR. It also means that reviewers can miss some PRs that are assigned to them. + +To try to move PRs forward, the Triage WG regularly goes through all PRs that +are waiting for review and haven't been discussed for at least 2 weeks. If you +don't get a review within 2 weeks, feel free to ask the Triage WG on +Zulip ([#t-release/triage]). They have knowledge of when to ping, who might be +on vacation, etc. + +The reviewer may request some changes using the GitHub code review interface. +They may also request special procedures (such as a [crater] run; [see +below][break]) for some PRs. + +[r?]: https://github.com/rust-lang/rust/pull/78133#issuecomment-712692371 +[#t-release/triage]: https://rust-lang.zulipchat.com/#narrow/stream/242269-t-release.2Ftriage +[break]: #breaking-changes ### CI In addition to being reviewed by a human, pull requests are automatically tested @@ -104,6 +189,8 @@ a pull request, CI builds the compiler and tests it against the [compiler test suite][rctd], and also performs other tests such as checking that your pull request is in compliance with Rust's style guidelines. +[rctd]: tests/intro.md + Running continuous integration tests allows PR authors to catch mistakes early without going through a first review cycle, and also helps reviewers stay aware of the status of a particular pull request. @@ -135,6 +222,8 @@ Changes that are rolled up are tested and merged alongside other PRs, to speed the process up. Typically only small changes that are expected not to conflict with one another are marked as "always roll up". +Be patient; this can take a while and the queue can sometimes be long. PRs are never merged by hand. + [@rustbot]: https://github.com/rustbot [@bors]: https://github.com/bors [merge-queue]: https://bors.rust-lang.org/queue/rust @@ -179,161 +268,19 @@ the issue in question. [labeling]: ./rustbot.md#issue-relabeling [closing-keywords]: https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue -### External Dependencies (subtree) - -As a developer to this repository, you don't have to treat the following external projects -differently from other crates that are directly in this repo: - -* [Clippy](https://github.com/rust-lang/rust-clippy) -* [Miri] -* [rustfmt](https://github.com/rust-lang/rustfmt) -* [rust-analyzer](https://github.com/rust-lang/rust-analyzer) - -In contrast to `submodule` dependencies -(see below for those), the `subtree` dependencies are just regular files and directories which can -be updated in tree. However, if possible, enhancements, bug fixes, etc. specific -to these tools should be filed against the tools directly in their respective -upstream repositories. The exception is that when rustc changes are required to -implement a new tool feature or test, that should happen in one collective rustc PR. - -#### Synchronizing a subtree - -Periodically the changes made to subtree based dependencies need to be synchronized between this -repository and the upstream tool repositories. - -Subtree synchronizations are typically handled by the respective tool maintainers. Other users -are welcome to submit synchronization PRs, however, in order to do so you will need to modify -your local git installation and follow a very precise set of instructions. -These instructions are documented, along with several useful tips and tricks, in the -[syncing subtree changes][clippy-sync-docs] section in Clippy's Contributing guide. -The instructions are applicable for use with any subtree based tool, just be sure to -use the correct corresponding subtree directory and remote repository. - -The synchronization process goes in two directions: `subtree push` and `subtree pull`. - -A `subtree push` takes all the changes that happened to the copy in this repo and creates commits -on the remote repo that match the local changes. Every local -commit that touched the subtree causes a commit on the remote repo, but -is modified to move the files from the specified directory to the tool repo root. - -A `subtree pull` takes all changes since the last `subtree pull` -from the tool repo and adds these commits to the rustc repo along with a merge commit that moves -the tool changes into the specified directory in the Rust repository. - -It is recommended that you always do a push first and get that merged to the tool master branch. -Then, when you do a pull, the merge works without conflicts. -While it's definitely possible to resolve conflicts during a pull, you may have to redo the conflict -resolution if your PR doesn't get merged fast enough and there are new conflicts. Do not try to -rebase the result of a `git subtree pull`, rebasing merge commits is a bad idea in general. - -You always need to specify the `-P` prefix to the subtree directory and the corresponding remote -repository. If you specify the wrong directory or repository -you'll get very fun merges that try to push the wrong directory to the wrong remote repository. -Luckily you can just abort this without any consequences by throwing away either the pulled commits -in rustc or the pushed branch on the remote and try again. It is usually fairly obvious -that this is happening because you suddenly get thousands of commits that want to be synchronized. - -[clippy-sync-docs]: https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html - -#### Creating a new subtree dependency - -If you want to create a new subtree dependency from an existing repository, call (from this -repository's root directory!) - -``` -git subtree add -P src/tools/clippy https://github.com/rust-lang/rust-clippy.git master -``` - -This will create a new commit, which you may not rebase under any circumstances! Delete the commit -and redo the operation if you need to rebase. - -Now you're done, the `src/tools/clippy` directory behaves as if Clippy were -part of the rustc monorepo, so no one but you (or others that synchronize -subtrees) actually needs to use `git subtree`. - - -### External Dependencies (submodules) - -Building Rust will also use external git repositories tracked using [git -submodules]. The complete list may be found in the [`.gitmodules`] file. Some -of these projects are required (like `stdarch` for the standard library) and -some of them are optional (like [Miri]). - -Usage of submodules is discussed more in the [Using Git -chapter](git.md#git-submodules). - -Some of the submodules are allowed to be in a "broken" state where they -either don't build or their tests don't pass, e.g. the documentation books -like [The Rust Reference]. Maintainers of these projects will be notified -when the project is in a broken state, and they should fix them as soon -as possible. The current status is tracked on the [toolstate website]. -More information may be found on the Forge [Toolstate chapter]. - -Breakage is not allowed in the beta and stable channels, and must be addressed -before the PR is merged. They are also not allowed to be broken on master in -the week leading up to the beta cut. - -[git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules -[`.gitmodules`]: https://github.com/rust-lang/rust/blob/master/.gitmodules -[The Rust Reference]: https://github.com/rust-lang/reference/ -[toolstate website]: https://rust-lang-nursery.github.io/rust-toolstate/ -[Toolstate chapter]: https://forge.rust-lang.org/infra/toolstate.html - -#### Breaking Tools Built With The Compiler - -Rust's build system builds a number of tools that make use of the internals of -the compiler and that are hosted in a separate repository, and included in Rust -via git submodules (such as [Miri]). If these tools break because of your -changes, you may run into a sort of "chicken and egg" problem. These tools rely -on the latest compiler to be built so you can't update them (in their own -repositories) to reflect your changes to the compiler until those changes are -merged into the compiler. At the same time, you can't get your changes merged -into the compiler because the rust-lang/rust build won't pass until those tools -build and pass their tests. - -Luckily, a feature was -[added to Rust's build](https://github.com/rust-lang/rust/issues/45861) to make -all of this easy to handle. The idea is that we allow these tools to be -"broken", so that the rust-lang/rust build passes without trying to build them, -then land the change in the compiler, and go update the tools that you -broke. Some tools will require waiting for a nightly release before this can -happen, while others use the builds uploaded after each bors merge and thus can -be updated immediately (check the tool's documentation for details). Once you're -done and the tools are working again, you go back in the compiler and update the -tools so they can be distributed again. - -This should avoid a bunch of synchronization dances and is also much easier on contributors as -there's no need to block on tools changes going upstream. - -Here are those same steps in detail: - -1. (optional) First, if it doesn't exist already, create a `config.toml` by copying - `config.toml.example` in the root directory of the Rust repository. - Set `submodules = false` in the `[build]` section. This will prevent `x.py` - from resetting to the original branch after you make your changes. If you - need to [update any submodules to their latest versions](#updating-submodules), - see the section of this file about that for more information. -2. (optional) Run `./x.py test src/tools/cargo` (substituting the submodule - that broke for `cargo`). Fix any errors in the submodule (and possibly others). -3. (optional) Make commits for your changes and send them to upstream repositories as a PR. -4. (optional) Maintainers of these submodules will **not** merge the PR. The PR can't be - merged because CI will be broken. You'll want to write a message on the PR referencing - your change, and how the PR should be merged once your change makes it into a nightly. -5. Wait for your PR to merge. -6. Wait for a nightly. -7. (optional) Help land your PR on the upstream repository now that your changes are in nightly. -8. (optional) Send a PR to rust-lang/rust updating the submodule. +## External Dependencies +This section has moved to ["Using External Repositories"](./external-repos.md). ## Writing Documentation Documentation improvements are very welcome. The source of `doc.rust-lang.org` is located in [`src/doc`] in the tree, and standard API documentation is generated -from the source code itself (e.g. [`lib.rs`]). Documentation pull requests function -in the same way as other pull requests. +from the source code itself (e.g. [`library/std/src/lib.rs`][std-root]). Documentation pull requests +function in the same way as other pull requests. [`src/doc`]: https://github.com/rust-lang/rust/tree/master/src/doc -[`lib.rs`]: https://github.com/rust-lang/rust/blob/master/library/std/src/lib.rs#L1 +[std-root]: https://github.com/rust-lang/rust/blob/master/library/std/src/lib.rs#L1 To find documentation-related issues, sort by the [A-docs label][adocs]. @@ -343,14 +290,11 @@ You can find documentation style guidelines in [RFC 1574][rfc1574]. [rfc1574]: https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text -In many cases, you don't need a full `./x.py doc --stage 2`, which will build -the entire stage 2 compiler and compile the various books published on -[doc.rust-lang.org][docs]. When updating documentation for the standard library, -first try `./x.py doc library`. If that fails, or if you need to -see the output from the latest version of `rustdoc`, add `--stage 1`. -Results should appear in `build/host/doc`. - -[docs]: https://doc.rust-lang.org +To build the standard library documentation, use `x doc --stage 0 library --open`. +To build the documentation for a book (e.g. the unstable book), use `x doc src/doc/unstable-book.` +Results should appear in `build/host/doc`, as well as automatically open in your default browser. +See [Building Documentation](./building/compiler-documenting.md#building-documentation) for more +information. You can also use `rustdoc` directly to check small fixes. For example, `rustdoc src/doc/reference.md` will render reference to `doc/reference.html`. @@ -366,7 +310,7 @@ There are issues for beginners and advanced compiler devs alike! Just a few things to keep in mind: - Please limit line length to 100 characters. This is enforced by CI, and you can run the checks - locally with `ci/check_line_lengths.sh`. + locally with `ci/lengthcheck.sh`. - When contributing text to the guide, please contextualize the information with some time period and/or a reason so that the reader knows how much to trust or mistrust the information. @@ -431,122 +375,99 @@ updated sort][lru] is good for finding issues like this. [Thanks to `@rustbot`][rustbot], anyone can help triage issues by adding appropriate labels to issues that haven't been triaged yet: -* Yellow, **A**-prefixed labels state which **area** of the project an issue - relates to. - -* Magenta, **B**-prefixed labels identify bugs which are **blockers**. - -* Dark blue, **beta-** labels track changes which need to be backported into - the beta branches. - -* Light purple, **C**-prefixed labels represent the **category** of an issue. - -* Green, **E**-prefixed labels explain the level of **experience** necessary - to fix the issue. - -* The dark blue **final-comment-period** label marks bugs that are using the - RFC signoff functionality of [rfcbot] and are currently in the final - comment period. - -* Red, **I**-prefixed labels indicate the **importance** of the issue. The - [I-nominated][inom] label indicates that an issue has been nominated for - discussion at the next meeting of the team tagged using a - **T**-prefixed label. Similarly, the [I-prioritize][ipri] indicates - that an issue has been requested to be prioritized by the appropriate - team. - -* The purple **metabug** label marks lists of bugs collected by other - categories. - -* Purple gray, **O**-prefixed labels are the **operating system** or platform - that this issue is specific to. - -* Orange, **P**-prefixed labels indicate a bug's **priority**. These labels - can be assigned by anyone that understand the issue and is able to - prioritize it, and replace the [I-prioritize][ipri] label. - -* The gray **proposed-final-comment-period** label marks bugs that are using - the RFC signoff functionality of [rfcbot] and are currently awaiting - signoff of all team members in order to enter the final comment period. - -* Pink, **regression**-prefixed labels track regressions from stable to the - release channels. - -* The light orange **relnotes** label marks issues that should be documented in - the release notes of the next release. - -* Gray, **S**-prefixed labels are used for tracking the **status** of pull - requests. - -* Blue, **T**-prefixed bugs denote which **team** the issue belongs to. - -If you're looking for somewhere to start, check out the [E-easy][eeasy] tag. - -[rustbot]: ./rustbot.md -[inom]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AI-nominated -[ipri]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AI-prioritize -[eeasy]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy [lru]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc -[rfcbot]: https://github.com/anp/rfcbot-rs/ - -## Out-of-tree Contributions - -There are a number of other ways to contribute to Rust that don't deal with -rust-lang/rust: - -* Answer questions in the _Get Help!_ channels on the [Rust Discord - server][rust-discord], on [users.rust-lang.org][users], or on - [StackOverflow][so]. -* Participate in the [RFC process](https://github.com/rust-lang/rfcs). -* Find a [requested community library][community-library], build it, and publish - it to [Crates.io](http://crates.io). Easier said than done, but very, very - valuable! +[rustbot]: ./rustbot.md -[rust-discord]: https://discord.gg/rust-lang -[users]: https://users.rust-lang.org/ -[so]: http://stackoverflow.com/questions/tagged/rust -[community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library +<style> +.label-color { + border-radius:0.5em; +} +table td:nth-child(2) { + white-space: nowrap; +} + +</style> + +| Labels | Color | Description | +|--------|-------|-------------| +| [A-] | <span class="label-color" style="background-color:#f7e101;"> </span> Yellow | The **area** of the project an issue relates to. | +| [B-] | <span class="label-color" style="background-color:#d304cb;"> </span> Magenta | Issues which are **blockers**. | +| [beta-] | <span class="label-color" style="background-color:#1e76d9;"> </span> Dark Blue | Tracks changes which need to be [backported to beta][beta-backport] | +| [C-] | <span class="label-color" style="background-color:#f5f1fd;"> </span> Light Purple | The **category** of an issue. | +| [D-] | <span class="label-color" style="background-color:#c9f7a3;"> </span> Mossy Green | Issues for **diagnostics**. | +| [E-] | <span class="label-color" style="background-color:#02e10c;"> </span> Green | The **experience** level necessary to fix an issue. | +| [F-] | <span class="label-color" style="background-color:#f9c0cc;"> </span> Peach | Issues for **nightly features**. | +| [I-] | <span class="label-color" style="background-color:#e10c02;"> </span> Red | The **importance** of the issue. | +| [I-\*-nominated] | <span class="label-color" style="background-color:#e10c02;"> </span> Red | The issue has been nominated for discussion at the next meeting of the corresponding team. | +| [I-prioritize] | <span class="label-color" style="background-color:#e10c02;"> </span> Red | The issue has been nominated for prioritization by the team tagged with a **T**-prefixed label. | +| [metabug] | <span class="label-color" style="background-color:#5319e7;"> </span> Purple | Bugs that collect other bugs. | +| [O-] | <span class="label-color" style="background-color:#6e6ec0;"> </span> Purple Grey | The **operating system** or platform that the issue is specific to. | +| [P-] | <span class="label-color" style="background-color:#eb6420;"> </span> Orange | The issue **priority**. These labels can be assigned by anyone that understand the issue and is able to prioritize it, and remove the [I-prioritize] label. | +| [regression-] | <span class="label-color" style="background-color:#e4008a;"> </span> Pink | Tracks regressions from a stable release. | +| [relnotes] | <span class="label-color" style="background-color:#fad8c7;"> </span> Light Orange | Changes that should be documented in the release notes of the next release. | +| [S-] | <span class="label-color" style="background-color:#d3dddd;"> </span> Gray | Tracks the **status** of pull requests. | +| [S-tracking-] | <span class="label-color" style="background-color:#4682b4;"> </span> Steel Blue | Tracks the **status** of [tracking issues]. | +| [stable-] | <span class="label-color" style="background-color:#00229c;"> </span> Dark Blue | Tracks changes which need to be [backported to stable][stable-backport] in anticipation of a point release. | +| [T-] | <span class="label-color" style="background-color:#bfd4f2;"> </span> Blue | Denotes which **team** the issue belongs to. | +| [WG-] | <span class="label-color" style="background-color:#c2e0c6;"> </span> Green | Denotes which **working group** the issue belongs to. | + + +[A-]: https://github.com/rust-lang/rust/labels?q=A +[B-]: https://github.com/rust-lang/rust/labels?q=B +[C-]: https://github.com/rust-lang/rust/labels?q=C +[D-]: https://github.com/rust-lang/rust/labels?q=D +[E-]: https://github.com/rust-lang/rust/labels?q=E +[F-]: https://github.com/rust-lang/rust/labels?q=F +[I-]: https://github.com/rust-lang/rust/labels?q=I +[O-]: https://github.com/rust-lang/rust/labels?q=O +[P-]: https://github.com/rust-lang/rust/labels?q=P +[S-]: https://github.com/rust-lang/rust/labels?q=S +[T-]: https://github.com/rust-lang/rust/labels?q=T +[WG-]: https://github.com/rust-lang/rust/labels?q=WG +[stable-]: https://github.com/rust-lang/rust/labels?q=stable +[beta-]: https://github.com/rust-lang/rust/labels?q=beta +[I-\*-nominated]: https://github.com/rust-lang/rust/labels?q=nominated +[I-prioritize]: https://github.com/rust-lang/rust/labels/I-prioritize +[tracking issues]: https://github.com/rust-lang/rust/labels/C-tracking-issue +[beta-backport]: https://forge.rust-lang.org/release/backporting.html#beta-backporting-in-rust-langrust +[stable-backport]: https://forge.rust-lang.org/release/backporting.html#stable-backporting-in-rust-langrust +[metabug]: https://github.com/rust-lang/rust/labels/metabug +[regression-]: https://github.com/rust-lang/rust/labels?q=regression +[relnotes]: https://github.com/rust-lang/rust/labels/relnotes +[S-tracking-]: https://github.com/rust-lang/rust/labels?q=s-tracking + +### Rfcbot labels + +[rfcbot] uses its own labels for tracking the process of coordinating +asynchronous decisions, such as approving or rejecting a change. +This is used for [RFCs], issues, and pull requests. + +| Labels | Color | Description | +|--------|-------|-------------| +| [proposed-final-comment-period] | <span class="label-color" style="background-color:#ededed;"> </span> Gray | Currently awaiting signoff of all team members in order to enter the final comment period. | +| [disposition-merge] | <span class="label-color" style="background-color:#008800;"> </span> Green | Indicates the intent is to merge the change. | +| [disposition-close] | <span class="label-color" style="background-color:#dd0000;"> </span> Red | Indicates the intent is to not accept the change and close it. | +| [disposition-postpone] | <span class="label-color" style="background-color:#ededed;"> </span> Gray | Indicates the intent is to not accept the change at this time and postpone it to a later date. | +| [final-comment-period] | <span class="label-color" style="background-color:#1e76d9;"> </span> Blue | Currently soliciting final comments before merging or closing. | +| [finished-final-comment-period] | <span class="label-color" style="background-color:#f9e189;"> </span> Light Yellow | The final comment period has concluded, and the issue will be merged or closed. | +| [postponed] | <span class="label-color" style="background-color:#fbca04;"> </span> Yellow | The issue has been postponed. | +| [closed] | <span class="label-color" style="background-color:#dd0000;"> </span> Red | The issue has been rejected. | +| [to-announce] | <span class="label-color" style="background-color:#ededed;"> </span> Gray | Issues that have finished their final-comment-period and should be publicly announced. Note: the rust-lang/rust repository uses this label differently, to announce issues at the triage meetings. | + +[disposition-merge]: https://github.com/rust-lang/rust/labels/disposition-merge +[disposition-close]: https://github.com/rust-lang/rust/labels/disposition-close +[disposition-postpone]: https://github.com/rust-lang/rust/labels/disposition-postpone +[proposed-final-comment-period]: https://github.com/rust-lang/rust/labels/proposed-final-comment-period +[final-comment-period]: https://github.com/rust-lang/rust/labels/final-comment-period +[finished-final-comment-period]: https://github.com/rust-lang/rust/labels/finished-final-comment-period +[postponed]: https://github.com/rust-lang/rfcs/labels/postponed +[closed]: https://github.com/rust-lang/rfcs/labels/closed +[to-announce]: https://github.com/rust-lang/rfcs/labels/to-announce +[rfcbot]: https://github.com/anp/rfcbot-rs/ +[RFCs]: https://github.com/rust-lang/rfcs ## Helpful Links and Information -For people new to Rust, and just starting to contribute, or even for -more seasoned developers, some useful places to look for information -are: - -* This guide contains information about how various parts of the - compiler work and how to contribute to the compiler -* [Rust Forge][rustforge] contains additional documentation, including - write-ups of how to achieve common tasks -* The [Rust Internals forum][rif], a place to ask questions and - discuss Rust's internals -* The [generated documentation for Rust's compiler][gdfrustc] -* The [Rust reference][rr], even though it doesn't specifically talk about - Rust's internals, is a great resource nonetheless -* Although out of date, [Tom Lee's great blog article][tlgba] is very helpful -* [rustaceans.org][ro] is helpful, but mostly dedicated to IRC -* The [Rust Compiler Testing Docs][rctd] -* For [@bors], [this cheat sheet][cheatsheet] is helpful -* Google is always helpful when programming. - You can [search all Rust documentation][gsearchdocs] (the standard library, - the compiler, the books, the references, and the guides) to quickly find - information about the language and compiler. -* You can also use Rustdoc's built-in search feature to find documentation on - types and functions within the crates you're looking at. You can also search - by type signature! For example, searching for `* -> vec` should find all - functions that return a `Vec<T>`. - _Hint:_ Find more tips and keyboard shortcuts by typing `?` on any Rustdoc - page! -* Don't be afraid to ask! The Rust community is friendly and helpful. - -[rustc dev guide]: about-this-guide.md -[gdfrustc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ -[gsearchdocs]: https://www.google.com/search?q=site:doc.rust-lang.org+your+query+here -[stddocs]: https://doc.rust-lang.org/std -[rif]: http://internals.rust-lang.org -[rr]: https://doc.rust-lang.org/book/README.html -[rustforge]: https://forge.rust-lang.org/ -[tlgba]: https://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/ -[ro]: https://www.rustaceans.org/ -[rctd]: tests/intro.md -[cheatsheet]: https://bors.rust-lang.org/ -[Miri]: https://github.com/rust-lang/miri +This section has moved to the ["About this guide"][more-links] chapter. + +[more-links]: ./about-this-guide.md#other-places-to-find-information diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index 4dd0a2da9..521aeb4a5 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -29,7 +29,10 @@ pass the <!-- date-check: nov 2022 --> `--edition=2021` argument yourself when c <a name="copyright"></a> +<!-- REUSE-IgnoreStart --> +<!-- Prevent REUSE from interpreting the heading as a copyright notice --> ### Copyright notice +<!-- REUSE-IgnoreEnd --> In the past, files began with a copyright and license notice. Please **omit** this notice for new files licensed under the standard terms (dual diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index d32de068e..daaffba7b 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/src/diagnostics.md @@ -69,17 +69,12 @@ surrounded with backticks: error: the identifier `foo.bar` is invalid ``` -### Error explanations +### Error codes and explanations -Some errors include long form descriptions. They may be viewed with the -`--explain` flag, or via the [error index]. Each explanation comes with an -example of how to trigger it and advice on how to fix it. - -Please read [RFC 1567] for details on how to format and write long error -codes. - -The descriptions are written in Markdown, and all of them are linked in the -[`rustc_error_codes`] crate. +Most errors have an associated error code. Error codes are linked to long-form +explanations which contains an example of how to trigger the error and in-depth +details about the error. They may be viewed with the `--explain` flag, or via +the [error index]. As a general rule, give an error a code (with an associated explanation) if the explanation would give more information than the error itself. A lot of the time @@ -89,12 +84,15 @@ triggers to include useful information for all cases in the error, in which case it's a good idea to add an explanation.[^estebank] As always, if you are not sure, just ask your reviewer! +If you decide to add a new error with an associated error code, please read +[this section][error-codes] for a guide and important details about the +process. + [^estebank]: This rule of thumb was suggested by **@estebank** [here][estebank-comment]. -[`rustc_error_codes`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_error_codes/error_codes/index.html [error index]: https://doc.rust-lang.org/error-index.html -[RFC 1567]: https://github.com/rust-lang/rfcs/blob/master/text/1567-long-error-codes-explanation-normalization.md [estebank-comment]: https://github.com/rust-lang/rustc-dev-guide/pull/967#issuecomment-733218283 +[error-codes]: ./diagnostics/error-codes.md ### Lints versus fixed diagnostics diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-codes.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-codes.md deleted file mode 100644 index 3618b43cd..000000000 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-codes.md +++ /dev/null @@ -1,79 +0,0 @@ -# Diagnostic codes -We generally try to assign each error message a unique code like `E0123`. These -codes are defined in the compiler in the `diagnostics.rs` files found in each -crate, which basically consist of macros. The codes come in two varieties: those -that have an extended write-up, and those that do not. Whenever possible, if you -are making a new code, you should write an extended write-up. - -### Allocating a fresh code - -Error codes are stored in `compiler/rustc_error_codes`. - -To create a new error, you first need to find the next available -code. You can find it with `tidy`: - -``` -./x.py test tidy -``` - -This will invoke the tidy script, which generally checks that your code obeys -our coding conventions. One of those jobs is to check that diagnostic codes are -indeed unique. Once it is finished with that, tidy will print out the lowest -unused code: - -``` -... -tidy check (x86_64-apple-darwin) -* 470 error codes -* highest error code: E0591 -... -``` - -Here we see the highest error code in use is `E0591`, so we _probably_ want -`E0592`. To be sure, run `rg E0592` and check, you should see no references. - -Ideally, you will write an extended description for your error, -which will go in `rustc_error_codes/src/error_codes/E0592.md`. -To register the error, open `rustc_error_codes/src/error_codes.rs` and add the -code (in its proper numerical order) into` register_diagnostics!` macro, like -this: - -```rust -register_diagnostics! { - ... - E0592: include_str!("./error_codes/E0592.md"), -} -``` - -But you can also add it without an extended description: - -```rust -register_diagnostics! { - ... - E0592, // put a description here -} -``` - -To actually issue the error, you can use the `struct_span_err!` macro: - -```rust -struct_span_err!(self.tcx.sess, // some path to the session here - span, // whatever span in the source you want - E0592, // your new error code - fluent::example::an_error_message) - .emit() // actually issue the error -``` - -If you want to add notes or other snippets, you can invoke methods before you -call `.emit()`: - -```rust -struct_span_err!(...) - .span_label(another_span, fluent::example::example_label) - .span_note(another_span, fluent::example::separate_note) - .emit_() -``` - -For an example of a PR adding an error code, see [#76143]. - -[#76143]: https://github.com/rust-lang/rust/pull/76143 diff --git a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md new file mode 100644 index 000000000..2dbdb53fe --- /dev/null +++ b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md @@ -0,0 +1,95 @@ +# Error codes +We generally try to assign each error message a unique code like `E0123`. These +codes are defined in the compiler in the `diagnostics.rs` files found in each +crate, which basically consist of macros. All error codes have an associated +explanation: new error codes must include them. Note that not all _historical_ +(no longer emitted) error codes have explanations. + +## Error explanations + +The explanations are written in Markdown (see the [CommonMark Spec] for +specifics around syntax), and all of them are linked in the [`rustc_error_codes`] +crate. Please read [RFC 1567] for details on how to format and write long error +codes. As of <!-- date-check --> February 2023, there is an +effort[^new-explanations] to replace this largely outdated RFC with a new more +flexible standard. + +Error explanations should expand on the error message and provide details about +_why_ the error occurs. It is not helpful for users to copy-paste a quick fix; +explanations should help users understand why their code cannot be accepted by +the compiler. Rust prides itself on helpful error messages and long-form +explanations are no exception. However, before error explanations are +overhauled[^new-explanations] it is a bit open as to how exactly they should be +written, as always: ask your reviewer or ask around on the Rust Discord or Zulip. + +[^new-explanations]: See the draft RFC [here][new-explanations-rfc]. + +[`rustc_error_codes`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_error_codes/error_codes/index.html +[CommonMark Spec]: https://spec.commonmark.org/current/ +[RFC 1567]: https://github.com/rust-lang/rfcs/blob/master/text/1567-long-error-codes-explanation-normalization.md +[new-explanations-rfc]: https://github.com/rust-lang/rfcs/pull/3370 + +## Allocating a fresh code + +Error codes are stored in `compiler/rustc_error_codes`. + +To create a new error, you first need to find the next available +code. You can find it with `tidy`: + +``` +./x.py test tidy +``` + +This will invoke the tidy script, which generally checks that your code obeys +our coding conventions. Some of these jobs check error codes and ensure that +there aren't duplicates, etc (the tidy check is defined in +`src/tools/tidy/src/error_codes.rs`). Once it is finished with that, tidy will +print out the highest used error code: + +``` +... +tidy check +Found 505 error codes +Highest error code: `E0591` +... +``` + +Here we see the highest error code in use is `E0591`, so we _probably_ want +`E0592`. To be sure, run `rg E0592` and check, you should see no references. + +You will have to write an extended description for your error, +which will go in `rustc_error_codes/src/error_codes/E0592.md`. +To register the error, open `rustc_error_codes/src/error_codes.rs` and add the +code (in its proper numerical order) into` register_diagnostics!` macro, like +this: + +```rust +register_diagnostics! { + ... + E0592: include_str!("./error_codes/E0592.md"), +} +``` + +To actually issue the error, you can use the `struct_span_err!` macro: + +```rust +struct_span_err!(self.tcx.sess, // some path to the session here + span, // whatever span in the source you want + E0592, // your new error code + fluent::example::an_error_message) + .emit() // actually issue the error +``` + +If you want to add notes or other snippets, you can invoke methods before you +call `.emit()`: + +```rust +struct_span_err!(...) + .span_label(another_span, fluent::example::example_label) + .span_note(another_span, fluent::example::separate_note) + .emit() +``` + +For an example of a PR adding an error code, see [#76143]. + +[#76143]: https://github.com/rust-lang/rust/pull/76143 diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md new file mode 100644 index 000000000..533f7eb5e --- /dev/null +++ b/src/doc/rustc-dev-guide/src/external-repos.md @@ -0,0 +1,113 @@ +# Using External Repositories + +The `rust-lang/rust` git repository depends on several other repos in the `rust-lang` organization. +There are three main ways we use dependencies: +1. As a Cargo dependency through crates.io (e.g. `rustc-rayon`) +2. As a git subtree (e.g. `clippy`) +3. As a git submodule (e.g. `cargo`) + +As a general rule, use crates.io for libraries that could be useful for others in the ecosystem; use +subtrees for tools that depend on compiler internals and need to be updated if there are breaking +changes; and use submodules for tools that are independent of the compiler. + +## External Dependencies (subtree) + +As a developer to this repository, you don't have to treat the following external projects +differently from other crates that are directly in this repo: + +* [Clippy](https://github.com/rust-lang/rust-clippy) +* [Miri] +* [rustfmt](https://github.com/rust-lang/rustfmt) +* [rust-analyzer](https://github.com/rust-lang/rust-analyzer) + +[Miri]: https://github.com/rust-lang/miri + +In contrast to `submodule` dependencies +(see below for those), the `subtree` dependencies are just regular files and directories which can +be updated in tree. However, if possible, enhancements, bug fixes, etc. specific +to these tools should be filed against the tools directly in their respective +upstream repositories. The exception is that when rustc changes are required to +implement a new tool feature or test, that should happen in one collective rustc PR. + +### Synchronizing a subtree + +Periodically the changes made to subtree based dependencies need to be synchronized between this +repository and the upstream tool repositories. + +Subtree synchronizations are typically handled by the respective tool maintainers. Other users +are welcome to submit synchronization PRs, however, in order to do so you will need to modify +your local git installation and follow a very precise set of instructions. +These instructions are documented, along with several useful tips and tricks, in the +[syncing subtree changes][clippy-sync-docs] section in Clippy's Contributing guide. +The instructions are applicable for use with any subtree based tool, just be sure to +use the correct corresponding subtree directory and remote repository. + +The synchronization process goes in two directions: `subtree push` and `subtree pull`. + +A `subtree push` takes all the changes that happened to the copy in this repo and creates commits +on the remote repo that match the local changes. Every local +commit that touched the subtree causes a commit on the remote repo, but +is modified to move the files from the specified directory to the tool repo root. + +A `subtree pull` takes all changes since the last `subtree pull` +from the tool repo and adds these commits to the rustc repo along with a merge commit that moves +the tool changes into the specified directory in the Rust repository. + +It is recommended that you always do a push first and get that merged to the tool master branch. +Then, when you do a pull, the merge works without conflicts. +While it's definitely possible to resolve conflicts during a pull, you may have to redo the conflict +resolution if your PR doesn't get merged fast enough and there are new conflicts. Do not try to +rebase the result of a `git subtree pull`, rebasing merge commits is a bad idea in general. + +You always need to specify the `-P` prefix to the subtree directory and the corresponding remote +repository. If you specify the wrong directory or repository +you'll get very fun merges that try to push the wrong directory to the wrong remote repository. +Luckily you can just abort this without any consequences by throwing away either the pulled commits +in rustc or the pushed branch on the remote and try again. It is usually fairly obvious +that this is happening because you suddenly get thousands of commits that want to be synchronized. + +[clippy-sync-docs]: https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html + +### Creating a new subtree dependency + +If you want to create a new subtree dependency from an existing repository, call (from this +repository's root directory!) + +``` +git subtree add -P src/tools/clippy https://github.com/rust-lang/rust-clippy.git master +``` + +This will create a new commit, which you may not rebase under any circumstances! Delete the commit +and redo the operation if you need to rebase. + +Now you're done, the `src/tools/clippy` directory behaves as if Clippy were +part of the rustc monorepo, so no one but you (or others that synchronize +subtrees) actually needs to use `git subtree`. + + +## External Dependencies (submodules) + +Building Rust will also use external git repositories tracked using [git +submodules]. The complete list may be found in the [`.gitmodules`] file. Some +of these projects are required (like `stdarch` for the standard library) and +some of them are optional (like `src/doc/book`). + +Usage of submodules is discussed more in the [Using Git chapter](git.md#git-submodules). + +Some of the submodules are allowed to be in a "broken" state where they +either don't build or their tests don't pass, e.g. the documentation books +like [The Rust Reference]. Maintainers of these projects will be notified +when the project is in a broken state, and they should fix them as soon +as possible. The current status is tracked on the [toolstate website]. +More information may be found on the Forge [Toolstate chapter]. +In practice, it is very rare for documentation to have broken toolstate. + +Breakage is not allowed in the beta and stable channels, and must be addressed +before the PR is merged. They are also not allowed to be broken on master in +the week leading up to the beta cut. + +[git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules +[`.gitmodules`]: https://github.com/rust-lang/rust/blob/master/.gitmodules +[The Rust Reference]: https://github.com/rust-lang/reference/ +[toolstate website]: https://rust-lang-nursery.github.io/rust-toolstate/ +[Toolstate chapter]: https://forge.rust-lang.org/infra/toolstate.html diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md new file mode 100644 index 000000000..3fb1add01 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -0,0 +1,149 @@ +# Fuzzing + +<!-- date-check: Mar 2023 --> + +For the purposes of this guide, *fuzzing* is any testing methodology that +involves compiling a wide variety of programs in an attempt to uncover bugs in +rustc. Fuzzing is often used to find internal compiler errors (ICEs). Fuzzing +can be beneficial, because it can find bugs before users run into them and +provide small, self-contained programs that make the bug easier to track down. +However, some common mistakes can reduce the helpfulness of fuzzing and end up +making contributors' lives harder. To maximize your positive impact on the Rust +project, please read this guide before reporting fuzzer-generated bugs! + +## Guidelines + +### In a nutshell + +*Please do:* + +- Ensure the bug is still present on the latest nightly rustc +- Include a reasonably minimal, standalone example along with any bug report +- Include all of the information requested in the bug report template +- Search for existing reports with the same message and query stack +- Format the test case with `rustfmt`, if it maintains the bug +- Indicate that the bug was found by fuzzing + +*Please don't:* + +- Don't report lots of bugs that use internal features, including but not + limited to `custom_mir`, `lang_items`, `no_core`, and `rustc_attrs`. +- Don't seed your fuzzer with inputs that are known to crash rustc (details + below). + +### Discussion + +If you're not sure whether or not an ICE is a duplicate of one that's already +been reported, please go ahead and report it and link to issues you think might +be related. In general, ICEs on the same line but with different *query stacks* +are usually distinct bugs. For example, [#109020][#109202] and [#109129][#109129] +had similar error messages: + +``` +error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead +``` +``` +error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <() as Project>::Assoc, maybe try to call `try_normalize_erasing_regions` instead +``` +but different query stacks: +``` +query stack during panic: +#0 [fn_abi_of_instance] computing call ABI of `<[closure@src/main.rs:36:25: 36:28] as core::ops::function::FnOnce<(Emplacable<()>,)>>::call_once - shim(vtable)` +end of query stack +``` +``` +query stack during panic: +#0 [check_mod_attrs] checking attributes in top-level module +#1 [analysis] running analysis passes on this crate +end of query stack +``` + +[#109020]: https://github.com/rust-lang/rust/issues/109020 +[#109129]: https://github.com/rust-lang/rust/issues/109129 + +## Building a corpus + +When building a corpus, be sure to avoid collecting tests that are already +known to crash rustc. A fuzzer that is seeded with such tests is more likely to +generate bugs with the same root cause, wasting everyone's time. The simplest +way to avoid this is to loop over each file in the corpus, see if it causes an +ICE, and remove it if so. + +To build a corpus, you may want to use: + +- The rustc/rust-analyzer/clippy test suites (or even source code) --- though avoid + tests that are already known to cause failures, which often begin with comments + like `// failure-status: 101` or `// known-bug: #NNN`. +- The already-fixed ICEs in [Glacier][glacier] --- though avoid the unfixed + ones in `ices/`! + +## Extra credit + +Here are a few things you can do to help the Rust project after filing an ICE. + +- [Bisect][bisect] the bug to figure out when it was introduced +- Fix "distractions": problems with the test case that don't contribute to + triggering the ICE, such as syntax errors or borrow-checking errors +- Minimize the test case (see below) +- Add the minimal test case to [Glacier][glacier] + +[bisect]: https://rust-lang.github.io/cargo-bisect-rustc/ + +## Minimization + +It is helpful to carefully *minimize* the fuzzer-generated input. When +minimizing, be careful to preserve the original error, and avoid introducing +distracting problems such as syntax, type-checking, or borrow-checking errors. + +There are some tools that can help with minimization. If you're not sure how +to avoid introducing syntax, type-, and borrow-checking errors while using +these tools, post both the complete and minimized test cases. Generally, +*syntax-aware* tools give the best results in the least amount of time. +[`treereduce-rust`][treereduce] and [picireny][picireny] are syntax-aware. +`halfempty` is not, but is generally a high-quality tool. + +[halfempty]: https://github.com/googleprojectzero/halfempty +[picireny]: https://github.com/renatahodovan/picireny +[treereduce]: https://github.com/langston-barrett/treereduce + +## Effective fuzzing + +When fuzzing rustc, you may want to avoid generating machine code, since this +is mostly done by LLVM. Try `--emit=mir` instead. + +A variety of compiler flags can uncover different issues. `-Zmir-opt-level=4` +will turn on MIR optimization passes that are not run by default, potentially +uncovering interesting bugs. `-Zvalidate-mir` can help uncover such bugs. + +If you're fuzzing a compiler you built, you may want to build it with `-C +target-cpu=native` or even PGO/BOLT to squeeze out a few more executions per +second. Of course, it's best to try multiple build configurations and see +what actually results in superior throughput. + +You may want to build rustc from source with debug assertions to find +additional bugs, though this is a trade-off: it can slow down fuzzing by +requiring extra work for every execution. To enable debug assertions, add this +to `config.toml` when compiling rustc: + +```toml +[rust] +debug-assertions = true +``` + +ICEs that require debug assertions to reproduce should be tagged +[`requires-debug-assertions`][requires-debug-assertions]. + +[requires-debug-assertions]: https://github.com/rust-lang/rust/labels/requires-debug-assertions + +## Existing projects + +- [fuzz-rustc][fuzz-rustc] demonstrates how to fuzz rustc with libfuzzer +- [icemaker][icemaker] runs rustc and other tools on a large number of source + files with a variety of flags to catch ICEs +- [tree-splicer][tree-splicer] generates new source files by combining existing + ones while maintaining correct syntax + +[glacier]: https://github.com/rust-lang/glacier +[fuzz-rustc]: https://github.com/dwrensha/fuzz-rustc +[icemaker]: https://github.com/matthiaskrgr/icemaker/ +[tree-splicer]: https://github.com/langston-barrett/tree-splicer/
\ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/generics.md b/src/doc/rustc-dev-guide/src/generics.md index 0173bee8f..7512b3b47 100644 --- a/src/doc/rustc-dev-guide/src/generics.md +++ b/src/doc/rustc-dev-guide/src/generics.md @@ -6,7 +6,7 @@ inference, type checking, and trait solving. Conceptually, during these routines that one type is equal to another type and want to swap one out for the other and then swap that out for another type and so on until we eventually get some concrete types (or an error). -In rustc this is done using the `SubstsRef` that we mentioned above (“substs” = “substitutions”). +In rustc this is done using [SubstsRef] (“substs” = “substitutions”). Conceptually, you can think of `SubstsRef` as a list of types that are to be substituted for the generic type parameters of the ADT. @@ -18,6 +18,7 @@ is conceptually like a `&'tcx [GenericArgKind<'tcx>]` slice (but it is actually [list]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.List.html [`GenericArg`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/subst/struct.GenericArg.html [`GenericArgKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/subst/enum.GenericArgKind.html +[SubstsRef]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/subst/type.SubstsRef.html So why do we use this `List` type instead of making it really a slice? It has the length "inline", so `&List` is only 32 bits. As a consequence, it cannot be "subsliced" (that only works if the @@ -126,7 +127,7 @@ You may have a couple of followup questions… **`subst`** How do we actually do the substitutions? There is a function for that too! You use [`subst`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/subst/struct.EarlyBinder.html#method.subst) to -replace a `SubstRef` with another list of types. +replace a `SubstsRef` with another list of types. [Here is an example of actually using `subst` in the compiler][substex]. The exact details are not too important, but in this piece of code, we happen to be converting from the `rustc_hir::Ty` to diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index bc294d1b3..d5c948994 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -1,13 +1,37 @@ # Getting Started +Thank you for your interest in contributing to Rust! There are many ways to +contribute, and we appreciate all of them. + <!-- toc --> +If this is your first time contributing, the [walkthrough] chapter can give you a good example of +how a typical contribution would go. + This documentation is _not_ intended to be comprehensive; it is meant to be a quick guide for the most useful things. For more information, [see this chapter on how to build and run the compiler](./building/how-to-build-and-run.md). +[internals]: https://internals.rust-lang.org +[rust-discord]: http://discord.gg/rust-lang +[rust-zulip]: https://rust-lang.zulipchat.com +[coc]: https://www.rust-lang.org/conduct.html +[walkthrough]: ./walkthrough.md +[Getting Started]: ./getting-started.md + ## Asking Questions +If you have questions, please make a post on the [Rust Zulip server][rust-zulip] or +[internals.rust-lang.org][internals]. If you are contributing to Rustup, be aware they are not on +Zulip - you can ask questions in `#wg-rustup` [on Discord][rust-discord]. +See the [list of teams and working groups][governance] and [the Community page][community] on the +official website for more resources. + +[governance]: https://www.rust-lang.org/governance +[community]: https://www.rust-lang.org/community + +As a reminder, all contributors are expected to follow our [Code of Conduct][coc]. + The compiler team (or `t-compiler`) usually hangs out in Zulip [in this "stream"][z]; it will be easiest to get questions answered there. @@ -30,6 +54,12 @@ compiler, [consult this "experts map"][map]. It's not perfectly complete, though, so please also feel free to ask questions even if you can't figure out who to ping. +Another way to find experts for a given part of the compiler is to see who has made recent commits. +For example, to find people who have recently worked on name resolution since the 1.68.2 release, +you could run `git shortlog -n 1.68.2.. compiler/rustc_resolve/`. Ignore any commits starting with +"Rollup merge" or commits by `@bors` (see [CI contribution prodcedures](./contributing.md#ci) for +more information about these commits). + [map]: https://github.com/rust-lang/compiler-team/blob/master/content/experts/map.toml ### Etiquette @@ -42,91 +72,61 @@ Just pinging someone without providing any context can be a bit annoying and just create noise, so we ask that you be mindful of the fact that the `t-compiler` folks get a lot of pings in a day. -## Cloning and Building - -### System Requirements - -Internet access is required. - -The most notable software requirement is that you will need Python 2 or 3, but -there are various others. - -The following hardware is recommended. -* 30GB+ of free disk space. -* 8GB+ RAM -* 2+ cores - -More powerful machines will lead to much faster builds. There are various -strategies to work around lesser hardware in the following chapters. - -See [this chapter][prereqs] for more details about software and hardware prerequisites. - -[prereqs]: ./building/prerequisites.md +## What should I work on? -### Cloning +The Rust project is quite large and it can be difficult to know which parts of the project need +help, or are a good starting place for beginners. Here are some suggested starting places. -You can just do a normal git clone: +### Easy or mentored issues -```sh -git clone https://github.com/rust-lang/rust.git -cd rust -``` +If you're looking for somewhere to start, check out the following [issue +search][help-wanted-search]. See the [Triage] for an explanation of these labels. You can also try +filtering the search to areas you're interested in. For example: -### `x.py` Intro +- `repo:rust-lang/rust-clippy` will only show clippy issues +- `label:T-compiler` will only show issues related to the compiler +- `label:A-diagnostics` will only show diagnostic issues -`rustc` is a [bootstrapping] compiler, which makes it more complex than a -typical Rust program. As a result, you cannot use Cargo to build it. Instead -you must use the special tool `x.py`. It is used for the things Cargo is -normally used for: building, testing, creating releases, formatting, etc. +Not all important or beginner work has issue labels. +See below for how to find work that isn't labelled. -[bootstrapping]: ./building/bootstrapping.md +[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CE-help-wanted%2CE-mentor +[Triage]: ./contributing.md#issue-triage -### Configuring the compiler +### Recurring work -In the top level of the repo: +Some work is too large to be done by a single person. In this case, it's common to have "Tracking +issues" to co-ordinate the work between contributors. Here are some example tracking issues where +it's easy to pick up work without a large time commitment: -```sh -$ ./x.py setup -``` +- [Rustdoc Askama Migration](https://github.com/rust-lang/rust/issues/108868) +- [Diagnostic Translation](https://github.com/rust-lang/rust/issues/100717) +- [Move UI tests to subdirectories](https://github.com/rust-lang/rust/issues/73494) -This will do some initialization and walk you through an interactive setup to -create `config.toml`, the primary configuration file. +If you find more recurring work, please feel free to add it here! -See [this chapter][config] for more info about configuration. +### Clippy issues -[config]: ./building/how-to-build-and-run.md#create-a-configtoml +The [Clippy] project has spent a long time making its contribution process as friendly to newcomers +as possible. Consider working on it first to get familiar with the process and the compiler +internals. -### Common `x.py` commands +See [the Clippy contribution guide][clippy-contributing] for instructions on getting started. -Here are the basic invocations of the `x.py` commands most commonly used when -working on `rustc`, `std`, `rustdoc`, and other tools. +[Clippy]: https://doc.rust-lang.org/clippy/ +[clippy-contributing]: https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md -| Command | When to use it | -| --- | --- | -| `./x.py check` | Quick check to see if most things compile; [rust-analyzer can run this automatically for you][rust-analyzer] | -| `./x.py build` | Builds `rustc`, `std`, and `rustdoc` | -| `./x.py test` | Runs all tests | -| `./x.py fmt` | Formats all code | +### Diagnostic issues -As written, these commands are reasonable starting points. However, there are -additional options and arguments for each of them that are worth learning for -serious development work. In particular, `./x.py build` and `./x.py test` -provide many ways to compile or test a subset of the code, which can save a lot -of time. +Many diagnostic issues are self-contained and don't need detailed background knowledge of the +compiler. You can see a list of diagnostic issues [here][diagnostic-issues]. -Also, note that `x.py` supports all kinds of path suffixes for `compiler`, `library`, -and `src/tools` directories. So, you can simply run `x.py test tidy` instead of -`x.py test src/tools/tidy`. Or, `x.py build std` instead of `x.py build library/std`. - -[rust-analyzer]: ./building/suggested.html#configuring-rust-analyzer-for-rustc - -See the chapters on [building](./building/how-to-build-and-run.md), -[testing](./tests/intro.md), and [rustdoc](./rustdoc.md) for more details. +[diagnostic-issues]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AA-diagnostics+no%3Aassignee ### Contributing code to other Rust projects There are a bunch of other projects that you can contribute to outside of the -`rust-lang/rust` repo, including `clippy`, `miri`, `chalk`, and many others. +`rust-lang/rust` repo, including `cargo`, `miri`, `rustup`, and many others. These repos might have their own contributing guidelines and procedures. Many of them are owned by working groups (e.g. `chalk` is largely owned by @@ -146,173 +146,37 @@ incredibly helpful: - [Writing documentation][wd]: if you are feeling a bit more intrepid, you could try to read a part of the code and write doc comments for it. This will help you to learn some part of the compiler while also producing a useful artifact! +- [Triaging issues][triage]: categorizing, replicating, and minimizing issues is very helpful to the Rust maintainers. - [Working groups][wg]: there are a bunch of working groups on a wide variety of rust-related things. +- Answer questions in the _Get Help!_ channels on the [Rust Discord + server][rust-discord], on [users.rust-lang.org][users], or on + [StackOverflow][so]. +- Participate in the [RFC process](https://github.com/rust-lang/rfcs). +- Find a [requested community library][community-library], build it, and publish + it to [Crates.io](http://crates.io). Easier said than done, but very, very + valuable! + +[rust-discord]: https://discord.gg/rust-lang +[users]: https://users.rust-lang.org/ +[so]: http://stackoverflow.com/questions/tagged/rust +[community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library [iceb]: ./notification-groups/cleanup-crew.md [wd]: ./contributing.md#writing-documentation [wg]: https://rust-lang.github.io/compiler-team/working-groups/ +[triage]: ./contributing.md#issue-triage -## Contributor Procedures - -There are some official procedures to know about. This is a tour of the -highlights, but there are a lot more details, which we will link to below. - -### Code Review - -When you open a PR on the `rust-lang/rust` repo, a bot called `@rustbot` will -automatically assign a reviewer to the PR based on which files you changed. -The reviewer is the person that will approve the PR to be tested and merged. -If you want a specific reviewer (e.g. a team member you've been working with), -you can specifically request them by writing `r? @user` (e.g. `r? @jyn514`) in -either the original post or a followup comment -(you can see [this comment][r?] for example). - -Please note that the reviewers are humans, who for the most part work on `rustc` -in their free time. This means that they can take some time to respond and review -your PR. It also means that reviewers can miss some PRs that are assigned to them. - -To try to move PRs forward, the Triage WG regularly goes through all PRs that -are waiting for review and haven't been discussed for at least 2 weeks. If you -don't get a review within 2 weeks, feel free to ask the Triage WG on -Zulip ([#t-release/triage]). They have knowledge of when to ping, who might be -on vacation, etc. - -The reviewer may request some changes using the GitHub code review interface. -They may also request special procedures (such as a [crater] run; [see -below][break]) for some PRs. - -[r?]: https://github.com/rust-lang/rust/pull/78133#issuecomment-712692371 -[#t-release/triage]: https://rust-lang.zulipchat.com/#narrow/stream/242269-t-release.2Ftriage -[break]: #breaking-changes - -When the PR is ready to be merged, the reviewer will issue a command to -`@bors`, the CI bot. Usually, this is `@bors r+` or `@bors r=user` to approve -a PR (there are few other commands, but they are less relevant here). -You can see [this comment][r+] for example. This puts the PR in [bors's queue][bors] -to be tested and merged. Be patient; this can take a while and the queue can -sometimes be long. PRs are never merged by hand. - -[r+]: https://github.com/rust-lang/rust/pull/78133#issuecomment-712726339 -[bors]: https://bors.rust-lang.org/queue/rust - -### Bug Fixes or "Normal" code changes - -For most PRs, no special procedures are needed. You can just open a PR, and it -will be reviewed, approved, and merged. This includes most bug fixes, -refactorings, and other user-invisible changes. The next few sections talk -about exceptions to this rule. - -Also, note that it is perfectly acceptable to open WIP PRs or GitHub [Draft -PRs][draft]. Some people prefer to do this so they can get feedback along the -way or share their code with a collaborator. Others do this so they can utilize -the CI to build and test their PR (e.g. if you are developing on a laptop). - -[draft]: https://github.blog/2019-02-14-introducing-draft-pull-requests/ - -### New Features - -Rust has strong backwards-compatibility guarantees. Thus, new features can't -just be implemented directly in stable Rust. Instead, we have 3 release -channels: stable, beta, and nightly. - -- **Stable**: this is the latest stable release for general usage. -- **Beta**: this is the next release (will be stable within 6 weeks). -- **Nightly**: follows the `master` branch of the repo. This is the only - channel where unstable, incomplete, or experimental features are usable with - feature gates. - -In order to implement a new feature, usually you will need to go through [the -RFC process][rfc] to propose a design, have discussions, etc. In some cases, -small features can be added with only an FCP ([see below][break]). If in doubt, ask the -compiler, language, or libs team (whichever is most relevant). - -[rfc]: https://github.com/rust-lang/rfcs/blob/master/README.md - -After a feature is approved to be added, a tracking issue is created on the -`rust-lang/rust` repo, which tracks the progress towards the implementation of -the feature, any bugs reported, and eventually stabilization. - -The feature then needs to be implemented behind a feature gate, which prevents -it from being accidentally used. - -Finally, somebody may propose stabilizing the feature in an upcoming version of -Rust. This requires a Final Comment Period ([see below][break]) to get the -approval of the relevant teams. - -After that, the feature gate can be removed and the feature turned on for all users. - -For more details on this process, see [this chapter on implementing new -features.](./implementing_new_features.md) - -### Breaking Changes - -As mentioned above, Rust has strong backwards-compatibility guarantees. To this -end, we are reluctant to make breaking changes. However, sometimes they are -needed to correct compiler bugs (e.g. code that compiled but should not) or -make progress on some features. - -Depending on the scale of the breakage, there are a few different actions that -can be taken. If the reviewer believes the breakage is very minimal (i.e. very -unlikely to be actually encountered by users), they may just merge the change. -More often, they will request a Final Comment Period (FCP), which calls for -rough consensus among the members of a relevant team. The team members can -discuss the issue and either accept, reject, or request changes on the PR. - -If the scale of breakage is large, a deprecation warning may be needed. This is -a warning that the compiler will display to users whose code will break in the -future. After some time, an FCP can be used to move forward with the actual -breakage. - -If the scale of breakage is unknown, a team member or contributor may request a -[crater] run. This is a bot that will compile all crates.io crates and many -public github repos with the compiler with your changes. A report will then be -generated with crates that ceased to compile with or began to compile with your -changes. Crater runs can take a few days to complete. - -[crater]: https://github.com/rust-lang/crater - -### Major Changes - -The compiler team has a special process for large changes, whether or not they -cause breakage. This process is called a Major Change Proposal (MCP). MCP is a -relatively lightweight mechanism for getting feedback on large changes to the -compiler (as opposed to a full RFC or a design meeting with the team). - -Example of things that might require MCPs include major refactorings, changes -to important types, or important changes to how the compiler does something, or -smaller user-facing changes. - -**When in doubt, ask on [zulip][z]. It would be a shame to put a lot of work -into a PR that ends up not getting merged!** [See this document][mcpinfo] for -more info on MCPs. - -[mcpinfo]: https://forge.rust-lang.org/compiler/mcp.html - -### Performance - -Compiler performance is important. We have put a lot of effort over the last -few years into [gradually improving it][perfdash]. - -[perfdash]: https://perf.rust-lang.org/dashboard.html +## Cloning and Building -If you suspect that your change may cause a performance regression (or -improvement), you can request a "perf run" (your reviewer may also request one -before approving). This is yet another bot that will compile a collection of -benchmarks on a compiler with your changes. The numbers are reported -[here][perf], and you can see a comparison of your changes against the latest -master. +See ["How to build and run the compiler"](./building//how-to-build-and-run.md). -For an introduction to the performance of Rust code in general -which would also be useful in rustc development, see [The Rust Performance Book]. +## Contributor Procedures -[perf]: https://perf.rust-lang.org -[The Rust Performance Book]: https://nnethercote.github.io/perf-book/ +This section has moved to the ["Contribution Procedures"](./contributing.md) chapter. ## Other Resources -- This guide: talks about how `rustc` works -- [The t-compiler zulip][z] -- [The compiler's documentation (rustdocs)](https://doc.rust-lang.org/nightly/nightly-rustc/) -- [The Forge](https://forge.rust-lang.org/) has more documentation about various procedures. -- `#contribute` and `#rustdoc` on [Discord](https://discord.gg/rust-lang). +This section has moved to the ["About this guide"][more-links] chapter. + +[more-links]: ./about-this-guide.md#other-places-to-find-information diff --git a/src/doc/rustc-dev-guide/src/git.md b/src/doc/rustc-dev-guide/src/git.md index a426157a2..34f2f101e 100644 --- a/src/doc/rustc-dev-guide/src/git.md +++ b/src/doc/rustc-dev-guide/src/git.md @@ -508,6 +508,18 @@ See [the docs for `--color-moved`](https://git-scm.com/docs/git-diff#Documentati See [the relevant section for PR authors](#git-range-diff). This can be useful for comparing code that was force-pushed to make sure there are no unexpected changes. +### Ignoring changes to specific files + +Many large files in the repo are autogenerated. To view a diff that ignores changes to those files, +you can use the following syntax (e.g. Cargo.lock): + +``` +git log -p ':!Cargo.lock' +``` + +Arbitrary patterns are supported (e.g. `:!compiler/*`). Patterns use the same syntax as +`.gitignore`, with `:` prepended to indicate a pattern. + ## Git submodules **NOTE**: submodules are a nice thing to know about, but it *isn't* an absolute diff --git a/src/doc/rustc-dev-guide/src/identifiers.md b/src/doc/rustc-dev-guide/src/identifiers.md index 1b60b3b0b..09e85c019 100644 --- a/src/doc/rustc-dev-guide/src/identifiers.md +++ b/src/doc/rustc-dev-guide/src/identifiers.md @@ -65,8 +65,7 @@ See the [HIR chapter][hir-map] for more detailed information. - [`BasicBlock`] identifies a *basic block*. It points to an instance of [`BasicBlockData`], which can be retrieved by indexing into - [`Body::basic_blocks()`] (note that you must call a function; the field is - private). + [`Body.basic_blocks`]. - [`Local`] identifies a local variable in a function. Its associated data is in [`LocalDecl`], which can be retrieved by indexing into [`Body.local_decls`]. @@ -93,7 +92,7 @@ See the [HIR chapter][hir-map] for more detailed information. [`BasicBlock`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.BasicBlock.html [`BasicBlockData`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.BasicBlockData.html -[`Body::basic_blocks()`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Body.html#method.basic_blocks +[`Body.basic_blocks`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Body.html#structfield.basic_blocks [`Local`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Local.html [`LocalDecl`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.LocalDecl.html [`Body.local_decls`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Body.html#structfield.local_decls diff --git a/src/doc/rustc-dev-guide/src/implementing_new_features.md b/src/doc/rustc-dev-guide/src/implementing_new_features.md index 9bd853080..946637d29 100644 --- a/src/doc/rustc-dev-guide/src/implementing_new_features.md +++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md @@ -1,5 +1,7 @@ # Implementing new features +<!-- toc --> + When you want to implement a new significant feature in the compiler, you need to go through this process to make sure everything goes smoothly. diff --git a/src/doc/rustc-dev-guide/src/mir/index.md b/src/doc/rustc-dev-guide/src/mir/index.md index 0c00928c0..dc0be167b 100644 --- a/src/doc/rustc-dev-guide/src/mir/index.md +++ b/src/doc/rustc-dev-guide/src/mir/index.md @@ -217,7 +217,7 @@ over the overflow checks.) ## MIR data types The MIR data types are defined in the [`compiler/rustc_middle/src/mir/`][mir] -module. Each of the key concepts mentioned in the previous section +module. Each of the key concepts mentioned in the previous section maps in a fairly straightforward way to a Rust type. The main MIR data type is [`Body`]. It contains the data for a single @@ -233,15 +233,14 @@ but [you can read about those below](#promoted)). - **Terminators** are represented by the [`Terminator`]. - **Locals** are represented by a [newtype'd] index type [`Local`]. The data for a local variable is found in the - [`Body::local_decls`][localdecls] vector). There is also a special constant + [`Body::local_decls`][localdecls] vector. There is also a special constant [`RETURN_PLACE`] identifying the special "local" representing the return value. -- **Places** are identified by the enum [`Place`]. There are a few - variants: +- **Places** are identified by the struct [`Place`]. There are a few + fields: - Local variables like `_1` - - Static variables `FOO` - **Projections**, which are fields or other things that "project - out" from a base place. These are represented by the type - [`ProjectionElem`]. So e.g. the place `_1.f` is a projection, + out" from a base place. These are represented by the [newtype'd] type + [`ProjectionElem`]. So e.g. the place `_1.f` is a projection, with `f` being the "projection element" and `_1` being the base path. `*_1` is also a projection, with the `*` being represented by the [`ProjectionElem::Deref`] element. diff --git a/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md b/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md index 436b51fd1..2e7b1766c 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md @@ -77,38 +77,13 @@ various builds of rustc. For recent regressions, it is even able to use the builds from our CI to track down the regression to a specific PR; for older regressions, it will simply identify a nightly. -To learn to use [cargo-bisect-rustc], check out [this blog -post][learn], which gives a quick introduction to how it works. You -can also ask questions at the Zulip stream -[`#t-compiler/cargo-bisect-rustc`][zcbr], or help in improving the tool. +To learn to use [cargo-bisect-rustc], check out [this blog post][learn], which +gives a quick introduction to how it works. Additionally, there is a [Guide] +which goes into more detail on how to use it. You can also ask questions at +the Zulip stream [`#t-compiler/cargo-bisect-rustc`][zcbr], or help in +improving the tool. [cargo-bisect-rustc]: https://github.com/rust-lang/cargo-bisect-rustc/ [learn]: https://blog.rust-lang.org/inside-rust/2019/12/18/bisecting-rust-compiler.html [zcbr]: https://rust-lang.zulipchat.com/#narrow/stream/217417-t-compiler.2Fcargo-bisect-rustc - -### identifying the range of PRs in a nightly - -If the regression occurred more than 90 days ago, then -cargo-bisect-rustc will not able to identify the particular PR that -caused the regression, just the nightly build. In that case, we can -identify the set of PRs that this corresponds to by using the git -history. - -The command `rustc +nightly -vV` will cause rustc to output a number -of useful bits of version info, including the `commit-hash`. Given the -commit-hash of two nightly versions, you can find all of PRs that have -landed in between by taking the following steps: - -1. Go to an update checkout of the [rust-lang/rust] repository -2. Execute the command `git log --author=bors --format=oneline SHA1..SHA2` - * This will list out all of the commits by bors, which is our merge bot - * Each commit corresponds to one PR, and information about the PR should be in the description -3. Copy and paste that information into the bug report - -Often, just eye-balling the PR descriptions (which are included in the -commit messages) will give you a good idea which one likely caused the -problem. But if you're unsure feel free to just ping the compiler team -(`@rust-lang/compiler`) or else to ping the authors of the PR -themselves. - -[rust-lang/rust]: https://github.com/rust-lang/rust/ +[Guide]: https://rust-lang.github.io/cargo-bisect-rustc/ diff --git a/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md b/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md index 3c2102a50..47b9fb5d9 100644 --- a/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md +++ b/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md @@ -7,7 +7,7 @@ To get diagnostics from the compiler, configure `rustc_interface::Config` to output diagnostic to a buffer, and run `TyCtxt.analysis`. The following was tested -with <!-- date-check: Feb 2023 --> `nightly-2023-02-13`: +with <!-- date-check: mar 2023 --> `nightly-2023-03-27`: ```rust {{#include ../examples/rustc-driver-getting-diagnostics.rs}} diff --git a/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md b/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md index d058a5838..4edbbca00 100644 --- a/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md +++ b/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md @@ -5,7 +5,7 @@ ## Getting the type of an expression To get the type of an expression, use the `global_ctxt` to get a `TyCtxt`. -The following was tested with <!-- date-check: Feb 2023 --> `nightly-2023-02-13`: +The following was tested with <!-- date-check: mar 2023 --> `nightly-2023-03-27`: ```rust {{#include ../examples/rustc-driver-interacting-with-the-ast.rs}} diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md index a8cc0c376..d58c2d280 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md @@ -7,38 +7,61 @@ see the ["Rustdoc overview" chapter](./rustdoc.md). ## From crate to clean -In `core.rs` are two central items: the `DocContext` struct, and the `run_core` -function. The latter is where rustdoc calls out to rustc to compile a crate to -the point where rustdoc can take over. The former is a state container used -when crawling through a crate to gather its documentation. +In `core.rs` are two central items: the `DocContext` struct, and the +`run_global_ctxt` function. The latter is where rustdoc calls out to rustc to +compile a crate to the point where rustdoc can take over. The former is a state +container used when crawling through a crate to gather its documentation. The main process of crate crawling is done in `clean/mod.rs` through several -implementations of the `Clean` trait defined within. This is a conversion -trait, which defines one method: +functions with names that start with `clean_`. Each function accepts an `hir` +or `ty` data structure, and outputs a `clean` structure used by rustdoc. For +example, this function for converting lifetimes: ```rust,ignore -pub trait Clean<T> { - fn clean(&self, cx: &DocContext) -> T; +fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime { + let def = cx.tcx.named_bound_var(lifetime.hir_id); + if let Some( + rbv::ResolvedArg::EarlyBound(node_id) + | rbv::ResolvedArg::LateBound(_, _, node_id) + | rbv::ResolvedArg::Free(_, node_id), + ) = def + { + if let Some(lt) = cx.substs.get(&node_id).and_then(|p| p.as_lt()).cloned() { + return lt; + } + } + Lifetime(lifetime.ident.name) } ``` `clean/mod.rs` also defines the types for the "cleaned" AST used later on to -render documentation pages. Each usually accompanies an implementation of -`Clean` that takes some AST or HIR type from rustc and converts it into the +render documentation pages. Each usually accompanies a `clean` function +that takes some AST or HIR type from rustc and converts it into the appropriate "cleaned" type. "Big" items like modules or associated items may -have some extra processing in its `Clean` implementation, but for the most part +have some extra processing in its `clean` function, but for the most part these impls are straightforward conversions. The "entry point" to this module -is the `impl Clean<Crate> for visit_ast::RustdocVisitor`, which is called by -`run_core` above. - -You see, I actually lied a little earlier: There's another AST transformation -that happens before the events in `clean/mod.rs`. In `visit_ast.rs` is the -type `RustdocVisitor`, which *actually* crawls a `rustc_hir::Crate` to get the first -intermediate representation, defined in `doctree.rs`. This pass is mainly to -get a few intermediate wrappers around the HIR types and to process visibility -and inlining. This is where `#[doc(inline)]`, `#[doc(no_inline)]`, and -`#[doc(hidden)]` are processed, as well as the logic for whether a `pub use` -should get the full page or a "Reexport" line in the module page. +is `clean::krate`, which is called by +`run_global_ctxt` above. + +The first step in `clean::krate` is to invoke `visit_ast::RustdocVisitor` to +process the module tree into an intermediate `visit_ast::Module`. This is the +step that actually crawls the `rustc_hir::Crate`, normalizing various aspects +of name resolution, such as: + + * showing `#[macro_export]`-ed macros at the crate root, regardless of where + they're defined + * inlining public `use` exports of private items, or showing a "Reexport" + line in the module page + * inlining items with `#[doc(hidden)]` if the base item is hidden but the + reexport is not + * handling `#[doc(inline)]` and `#[doc(no_inline)]` + * handling import globs and cycles, so there are no duplicates or infinite + directory trees + +After this step, `clean::krate` invokes `clean_doc_module`, which actually +converts the HIR items to the cleaned AST. This is also the step where cross- +crate inlining is performed, which requires converting `rustc_middle` data +structures into the cleaned AST instead. The other major thing that happens in `clean/mod.rs` is the collection of doc comments and `#[doc=""]` attributes into a separate field of the Attributes @@ -48,41 +71,28 @@ easier to collect this documentation later in the process. The primary output of this process is a `clean::Crate` with a tree of Items which describe the publicly-documentable items in the target crate. -### Hot potato +### Passes anything but a gas station + +(alternate title: [hot potato](https://www.youtube.com/watch?v=WNFBIt5HxdY)) Before moving on to the next major step, a few important "passes" occur over -the documentation. These do things like combine the separate "attributes" into -a single string to make the document easier on the markdown parser, -or drop items that are not public or deliberately hidden with `#[doc(hidden)]`. +the cleaned AST. Several of these passes are lints and reports, but some of +them mutate or generate new items. + These are all implemented in the `passes/` directory, one file per pass. By default, all of these passes are run on a crate, but the ones regarding dropping private/hidden items can be bypassed by passing `--document-private-items` to rustdoc. Note that unlike the previous set of AST transformations, the passes are run on the _cleaned_ crate. -(Strictly speaking, you can fine-tune the passes run and even add your own, but -[we're trying to deprecate that][44136]. If you need finer-grain control over -these passes, please let us know!) - -[44136]: https://github.com/rust-lang/rust/issues/44136 - -Here is the list of passes as of <!-- date-check --> November 2022: +Here is the list of passes as of <!-- date-check --> March 2023: - `calculate-doc-coverage` calculates information used for the `--show-coverage` flag. -- `check-bare-urls` detects links that are not linkified, e.g., in Markdown such as - `Go to https://example.com/.` It suggests wrapping the link with angle brackets: - `Go to <https://example.com/>.` to linkify it. This is the code behind the <!-- - date: 2022-05 --> `rustdoc::bare_urls` lint. - -- `check-code-block-syntax` validates syntax inside Rust code blocks - (<code>```rust</code>) - -- `check-doc-test-visibility` runs doctest visibility–related lints. - -- `check-invalid-html-tags` detects invalid HTML (like an unclosed `<span>`) - in doc comments. +- `check-doc-test-visibility` runs doctest visibility–related lints. This pass + runs before `strip-private`, which is why it needs to be separate from + `run-lints`. - `collect-intra-doc-links` resolves [intra-doc links](https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html). @@ -92,44 +102,66 @@ Here is the list of passes as of <!-- date-check --> November 2022: - `propagate-doc-cfg` propagates `#[doc(cfg(...))]` to child items. +- `run-lints` runs some of rustdoc's lints, defined in `passes/lint`. This is + the last pass to run. + + - `bare_urls` detects links that are not linkified, e.g., in Markdown such as + `Go to https://example.com/.` It suggests wrapping the link with angle brackets: + `Go to <https://example.com/>.` to linkify it. This is the code behind the <!-- + date-check: may 2022 --> `rustdoc::bare_urls` lint. + + - `check_code_block_syntax` validates syntax inside Rust code blocks + (<code>```rust</code>) + + - `html_tags` detects invalid HTML (like an unclosed `<span>`) + in doc comments. + +- `strip-hidden` and `strip-private` strip all `doc(hidden)` and private items + from the output. `strip-private` implies `strip-priv-imports`. Basically, the + goal is to remove items that are not relevant for public documentation. This + pass is skipped when `--document-hidden-items` is passed. + - `strip-priv-imports` strips all private import statements (`use`, `extern crate`) from a crate. This is necessary because rustdoc will handle *public* imports by either inlining the item's documentation to the module or creating a "Reexports" section with the import in it. The pass ensures that all of - these imports are actually relevant to documentation. + these imports are actually relevant to documentation. It is technically + only run when `--document-private-items` is passed, but `strip-private` + accomplishes the same thing. -- `strip-hidden` and `strip-private` strip all `doc(hidden)` and private items - from the output. `strip-private` implies `strip-priv-imports`. Basically, the - goal is to remove items that are not relevant for public documentation. +- `strip-private` strips all private items from a crate which cannot be seen + externally. This pass is skipped when `--document-private-items` is passed. There is also a `stripper` module in `passes/`, but it is a collection of utility functions for the `strip-*` passes and is not a pass itself. -## From clean to crate +## From clean to HTML This is where the "second phase" in rustdoc begins. This phase primarily lives -in the `html/` folder, and it all starts with `run()` in `html/render.rs`. This -code is responsible for setting up the `Context`, `SharedContext`, and `Cache` -which are used during rendering, copying out the static files which live in -every rendered set of documentation (things like the fonts, CSS, and JavaScript -that live in `html/static/`), creating the search index, and printing out the -source code rendering, before beginning the process of rendering all the -documentation for the crate. - -Several functions implemented directly on `Context` take the `clean::Crate` and -set up some state between rendering items or recursing on a module's child -items. From here the "page rendering" begins, via an enormous `write!()` call -in `html/layout.rs`. The parts that actually generate HTML from the items and -documentation occurs within a series of `std::fmt::Display` implementations and -functions that pass around a `&mut std::fmt::Formatter`. The top-level -implementation that writes out the page body is the `impl<'a> fmt::Display for -Item<'a>` in `html/render.rs`, which switches out to one of several `item_*` -functions based on the kind of `Item` being rendered. +in the `formats/` and `html/` folders, and it all starts with +`formats::run_format`. This code is responsible for setting up a type that +`impl FormatRenderer`, which for HTML is [`Context`]. + +This structure contains methods that get called by `run_format` to drive the +doc rendering, which includes: + +* `init` generates `static.files`, as well as search index and `src/` +* `item` generates the item HTML files themselves +* `after_krate` generates other global resources like `all.html` + +In `item`, the "page rendering" occurs, via a mixture of [Askama] templates +and manual `write!()` calls, starting in `html/layout.rs`. The parts that have +not been converted to templates occur within a series of `std::fmt::Display` +implementations and functions that pass around a `&mut std::fmt::Formatter`. + +The parts that actually generate HTML from the items and documentation start +with `print_item` defined in `html/render/print_item.rs`, which switches out +to one of several `item_*` functions based on kind of `Item` being rendered. Depending on what kind of rendering code you're looking for, you'll probably -find it either in `html/render.rs` for major items like "what sections should I -print for a struct page" or `html/format.rs` for smaller component pieces like -"how should I print a where clause as part of some other item". +find it either in `html/render/mod.rs` for major items like "what sections +should I print for a struct page" or `html/format/mod.rs` for smaller +component pieces like "how should I print a where clause as part of some other item". Whenever rustdoc comes across an item that should print hand-written documentation alongside, it calls out to `html/markdown.rs` which interfaces @@ -148,23 +180,46 @@ to us"][video]) [video]: https://www.youtube.com/watch?v=hOLAGYmUQV0 -It's important to note that the AST cleaning can ask the compiler for -information (crucially, `DocContext` contains a `TyCtxt`), but page rendering -cannot. The `clean::Crate` created within `run_core` is passed outside the -compiler context before being handed to `html::render::run`. This means that a -lot of the "supplementary data" that isn't immediately available inside an -item's definition, like which trait is the `Deref` trait used by the language, -needs to be collected during cleaning, stored in the `DocContext`, and passed -along to the `SharedContext` during HTML rendering. This manifests as a bunch -of shared state, context variables, and `RefCell`s. - -Also of note is that some items that come from "asking the compiler" don't go -directly into the `DocContext` - for example, when loading items from a foreign -crate, rustdoc will ask about trait implementations and generate new `Item`s -for the impls based on that information. This goes directly into the returned -`Crate` rather than roundabout through the `DocContext`. This way, these -implementations can be collected alongside the others, right before rendering -the HTML. +It's important to note that rustdoc can ask the compiler for type information +directly, even during HTML generation. This [didn't used to be the case], and +a lot of rustdoc's architecture was designed around not doing that, but a +`TyCtxt` is now passed to `formats::renderer::run_format`, which is used to +run generation for both HTML and the +(unstable as of <!-- date-check --> March 2023) JSON format. + +[didn't used to be the case]: https://github.com/rust-lang/rust/pull/80090 + +This change has allowed other changes to remove data from the "clean" AST +that can be easily derived from `TyCtxt` queries, and we'll usually accept +PRs that remove fields from "clean" (it's been soft-deprecated), but this +is complicated from two other constraints that rustdoc runs under: + +* Docs can be generated for crates that don't actually pass type checking. + This is used for generating docs that cover mutually-exclusive platform + configurations, such as `libstd` having a single package of docs that + cover all supported operating systems. This means rustdoc has to be able + to generate docs from HIR. +* Docs can inline across crates. Since crate metadata doesn't contain HIR, + it must be possible to generate inlined docs from the `rustc_middle` data. + +The "clean" AST acts as a common output format for both input formats. There +is also some data in clean that doesn't correspond directly to HIR, such as +synthetic `impl`s for auto traits and blanket `impl`s generated by the +`collect-trait-impls` pass. + +Some additional data is stored in +`html::render::context::{Context, SharedContext}`. These two types serve as +ways to segregate rustdoc's data for an eventual future with multithreaded doc +generation, as well as just keeping things organized: + +* [`Context`] stores data used for generating the current page, such as its + path, a list of HTML IDs that have been used (to avoid duplicate `id=""`), + and the pointer to `SharedContext`. +* [`SharedContext`] stores data that does not vary by page, such as the `tcx` + pointer, and a list of all types. + +[`Context`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/html/render/context/struct.Context.html +[`SharedContext`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/html/render/context/struct.SharedContext.html ## Other tricks up its sleeve diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md index d58b27bb7..cbe5e8b1f 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc.md +++ b/src/doc/rustc-dev-guide/src/rustdoc.md @@ -1,8 +1,5 @@ # Rustdoc overview -`rustdoc` uses `rustc` internals (and, of course, the standard library), so you -will have to build the compiler and `std` once before you can build `rustdoc`. - `rustdoc` lives in-tree with the compiler and standard library. This chapter is about how it works. For information about Rustdoc's features and how to use them, see @@ -12,6 +9,11 @@ For more details about how rustdoc works, see the [Rustdoc internals]: ./rustdoc-internals.md +<!-- toc --> + +`rustdoc` uses `rustc` internals (and, of course, the standard library), so you +will have to build the compiler and `std` once before you can build `rustdoc`. + Rustdoc is implemented entirely within the crate [`librustdoc`][rd]. It runs the compiler up to the point where we have an internal representation of a crate (HIR) and the ability to run some queries about the types of items. [HIR] diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index 5fc6ba809..f066992dc 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -11,6 +11,16 @@ efficient test execution (parallel execution is supported), and allows the test author to configure behavior and expected results of both individual and groups of tests. +> NOTE: +> For macOS users, `SIP` (System Integrity Protection) [may consistently +> check the compiled binary by sending network requests to Apple][zulip], +> so you may get a huge performance degradation when running tests. +> +> You can resolve it by tweaking the following settings: +> `Privacy & Security -> Developer Tools -> Add Terminal (Or VsCode, etc.)`. + +[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/.E2.9C.94.20Is.20there.20any.20performance.20issue.20for.20MacOS.3F + `compiletest` may check test code for success, for runtime failure, or for compile-time failure. Tests are typically organized as a Rust source file with annotations in diff --git a/src/doc/rustc-dev-guide/src/the-parser.md b/src/doc/rustc-dev-guide/src/the-parser.md index 0d37704e8..f0436350a 100644 --- a/src/doc/rustc-dev-guide/src/the-parser.md +++ b/src/doc/rustc-dev-guide/src/the-parser.md @@ -1,8 +1,5 @@ # Lexing and Parsing -As of <!-- date-check --> January 2021, the lexer and parser are undergoing -refactoring to allow extracting them into libraries. - The very first thing the compiler does is take the program (in Unicode characters) and turn it into something the compiler can work with more conveniently than strings. This happens in two stages: Lexing and Parsing. diff --git a/src/doc/rustc-dev-guide/src/tracing.md b/src/doc/rustc-dev-guide/src/tracing.md index 0bba73f74..af484ab5f 100644 --- a/src/doc/rustc-dev-guide/src/tracing.md +++ b/src/doc/rustc-dev-guide/src/tracing.md @@ -144,6 +144,9 @@ $ RUSTC_LOG=debug rustc +stage1 my-file.rs 2>all-log # compilers. $ RUSTC_LOG=rustc_codegen_ssa=info rustc +stage1 my-file.rs +# This will show all logs in `rustc_codegen_ssa` and `rustc_resolve`. +$ RUSTC_LOG=rustc_codegen_ssa,rustc_resolve rustc +stage1 my-file.rs + # This will show the output of all `info!` calls made by rustdoc # or any rustc library it calls. $ RUSTDOC_LOG=info rustdoc +stage1 my-file.rs diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md index 2bafeb247..4043789d0 100644 --- a/src/doc/rustc-dev-guide/src/type-inference.md +++ b/src/doc/rustc-dev-guide/src/type-inference.md @@ -68,7 +68,7 @@ inference works, or perhaps this blog post on [Unification in the Chalk project]: http://smallcultfollowing.com/babysteps/blog/2017/03/25/unification-in-chalk-part-1/ All told, the inference context stores five kinds of inference variables -(as of <!-- date-check --> June 2021): +(as of <!-- date-check --> March 2023): - Type variables, which come in three varieties: - General type variables (the most common). These can be unified with any diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 752f1cc4a..8ded2ee59 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -26,8 +26,10 @@ - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) - [\*-android and \*-androideabi](platform-support/android.md) + - [\*-linux-ohos](platform-support/openharmony.md) - [\*-unknown-fuchsia](platform-support/fuchsia.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) + - [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md) - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) - [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md) - [mipsel-sony-psx](platform-support/mipsel-sony-psx.md) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index c7f120daf..62347f169 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -71,9 +71,11 @@ If not specified, debug assertions are automatically enabled only if the This flag controls the generation of debug information. It takes one of the following values: -* `0`: no debug info at all (the default). -* `1`: line tables only. -* `2`: full debug info. +* `0` or `none`: no debug info at all (the default). +* `line-directives-only`: line info directives only. For the nvptx* targets this enables [profiling](https://reviews.llvm.org/D46061). For other use cases, `line-tables-only` is the better, more compatible choice. +* `line-tables-only`: line tables only. Generates the minimal amount of debug info for backtraces with filename/line number info, but not anything else, i.e. no variable or function parameter info. +* `1` or `limited`: debug info without type or variable-level information. +* `2` or `full`: full debug info. Note: The [`-g` flag][option-g-debug] is an alias for `-C debuginfo=2`. diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md index da91e2559..b0b2f4196 100644 --- a/src/doc/rustc/src/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -31,7 +31,7 @@ Rust's source-based code coverage requires the Rust "profiler runtime". Without The Rust `nightly` distribution channel includes the profiler runtime, by default. -> **Important**: If you are building the Rust compiler from the source distribution, the profiler runtime is _not_ enabled in the default `config.toml.example`. Edit your `config.toml` file and ensure the `profiler` feature is set it to `true` (either under the `[build]` section, or under the settings for an individual `[target.<triple>]`): +> **Important**: If you are building the Rust compiler from the source distribution, the profiler runtime is _not_ enabled in the default `config.example.toml`. Edit your `config.toml` file and ensure the `profiler` feature is set it to `true` (either under the `[build]` section, or under the settings for an individual `[target.<triple>]`): > > ```toml > # Build the profiler runtime (required when compiling with options that depend diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 9eafa27e2..c378532db 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -218,6 +218,7 @@ target | std | host | notes [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | +[`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | ARM64 OpenHarmony | [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore @@ -240,6 +241,7 @@ target | std | host | notes [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain) `armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8 [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ? | | ARM Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) +[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | ARMv7 OpenHarmony | [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7 Linux with uClibc, softfloat [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7 Linux with uClibc, hardfloat `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD @@ -255,6 +257,7 @@ target | std | host | notes `bpfel-unknown-none` | * | | BPF (little endian) `hexagon-unknown-linux-musl` | ? | | `i386-apple-ios` | ✓ | | 32-bit x86 iOS +[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS | `i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.7+, Lion+) `i686-pc-windows-msvc` | * | | 32-bit Windows XP support `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku @@ -263,6 +266,7 @@ target | std | host | notes `i686-uwp-windows-gnu` | ? | | `i686-uwp-windows-msvc` | ? | | `i686-wrs-vxworks` | ? | | +[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | ? | | LoongArch64 Linux (LP64D ABI) [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux `mips-unknown-linux-uclibc` | ✓ | | MIPS Linux with uClibc [`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? | | MIPS64 for OpenWrt Linux MUSL @@ -295,6 +299,7 @@ target | std | host | notes [`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) `riscv32imc-esp-espidf` | ✓ | | RISC-V ESP-IDF `riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD +`riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia `riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.0) [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 `s390x-unknown-linux-musl` | | | S390x Linux (kernel 3.2, MUSL) diff --git a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md index 432e0cfc9..32d3440f1 100644 --- a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md +++ b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md @@ -26,7 +26,6 @@ Therefore, you can build Rust with support for the target by adding it to the ta ```toml [llvm] download-ci-llvm = false -skip-rebuild = true optimize = true ninja = true targets = "ARM;X86" diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md index cf831e159..a230eba6b 100644 --- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md @@ -17,13 +17,6 @@ specific with this target, so any ARMv4T device should work fine. The target is cross-compiled, and uses static linking. -The linker that comes with rustc cannot link for this platform (the platform is -too old). You will need the `arm-none-eabi-ld` linker from a GNU Binutils -targeting ARM. This can be obtained for Windows/Mac/Linux from the [ARM -Developer Website][arm-dev], or possibly from your OS's package manager. - -[arm-dev]: https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain - This target doesn't provide a linker script, you'll need to bring your own according to the specific device you want to target. Pass `-Clink-arg=-Tyour_script.ld` as a rustc argument to make the linker use diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md new file mode 100644 index 000000000..d7d31d872 --- /dev/null +++ b/src/doc/rustc/src/platform-support/loongarch-linux.md @@ -0,0 +1,92 @@ +# loongarch\*-unknown-linux-\* + +**Tier: 3** + +[LoongArch] is a new RISC ISA developed by Loongson Technology Corporation Limited. + +[LoongArch]: https://loongson.github.io/LoongArch-Documentation/README-EN.html + +The target name follow this format: `<machine>-<vendor>-<os><fabi_suffix>`, where `<machine>` specifies the CPU family/model, `<vendor>` specifies the vendor and `<os>` the operating system name. +While the integer base ABI is implied by the machine field, the floating point base ABI type is encoded into the os field of the specifier using the string suffix `<fabi-suffix>`. + +| `<fabi-suffix>` | `Description` | +|------------------------|--------------------------------------------------------------------| +| f64 | The base ABI use 64-bits FPRs for parameter passing. (lp64d)| +| f32 | The base ABI uses 32-bit FPRs for parameter passing. (lp64f)| +| sf | The base ABI uses no FPR for parameter passing. (lp64s) | + +|`ABI type(Base ABI/ABI extension)`| `C library` | `kernel` | `target tuple` | +|----------------------------------|-------------|----------|----------------------------------| +| lp64d/base | glibc | linux | loongarch64-unknown-linux-gnu | +| lp64f/base | glibc | linux | loongarch64-unknown-linux-gnuf32 | +| lp64s/base | glibc | linux | loongarch64-unknown-linux-gnusf | +| lp64d/base | musl libc | linux | loongarch64-unknown-linux-musl| +| lp64f/base | musl libc | linux | loongarch64-unknown-linux-muslf32| +| lp64s/base | musl libc | linux | loongarch64-unknown-linux-muslsf | + +## Target maintainers + +- [ZHAI Xiaojuan](https://github.com/zhaixiaojuan) `zhaixiaojuan@loongson.cn` +- [WANG Rui](https://github.com/heiher) `wangrui@loongson.cn` +- [ZHAI Xiang](https://github.com/xiangzhai) `zhaixiang@loongson.cn` +- [WANG Xuerui](https://github.com/xen0n) `git@xen0n.name` + +## Requirements + +This target is cross-compiled. +A GNU toolchain for LoongArch target is required. It can be downloaded from https://github.com/loongson/build-tools/releases, or built from the source code of GCC (12.1.0 or later) and Binutils (2.40 or later). + +## Building the target + +The target can be built by enabling it for a `rustc` build. + +```toml +[build] +target = ["loongarch64-unknown-linux-gnu"] +``` + +Make sure `loongarch64-unknown-linux-gnu-gcc` can be searched from the directories specified in`$PATH`. Alternatively, you can use GNU LoongArch Toolchain by adding the following to `config.toml`: + +```toml +[target.loongarch64-unknown-linux-gnu] +# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN +cc = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc" +cxx = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-g++" +ar = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-ar" +ranlib = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-ranlib" +linker = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc" +``` + +## Cross-compilation + +This target can be cross-compiled on a `x86_64-unknown-linux-gnu` host. Cross-compilation on other hosts may work but is not tested. + +## Testing +To test a cross-compiled binary on your build system, install the qemu binary that supports the LoongArch architecture and execute the following commands. +```text +CC_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \ +CXX_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-g++ \ +AR_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc-ar \ +CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_LINKER=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \ +# SET TARGET SYSTEM LIBRARY PATH +CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_RUNNER="qemu-loongarch64 -L /TOOLCHAIN_PATH/TARGET_LIBRAY_PATH" \ +cargo run --target loongarch64-unknown-linux-gnu --release +``` +Tested on x86 architecture, other architectures not tested. + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for this target, you will either need to build Rust with the target enabled (see "Building the target" above), or build your own copy of `std` by using `build-std` or similar. + +If `rustc` has support for that target and the library artifacts are available, then Rust static libraries can be built for that target: + +```shell +$ rustc --target loongarch64-unknown-linux-gnu your-code.rs --crate-type staticlib +$ ls libyour_code.a +``` + +On Rust Nightly it's possible to build without the target artifacts available: + +```text +cargo build -Z build-std --target loongarch64-unknown-linux-gnu +``` diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 38198fe6c..0d815c9b5 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -16,10 +16,18 @@ and [Blackberry QNX][BlackBerry]. ## Requirements -Currently, only cross-compilation for QNX Neutrino on AArch64 and x86_64 are supported (little endian). +Currently, the following QNX Neutrino versions and compilation targets are supported: + +| QNX Neutrino Version | Target Architecture | Full support | `no_std` support | +|----------------------|---------------------|:------------:|:----------------:| +| 7.1 | AArch64 | ✓ | ✓ | +| 7.1 | x86_64 | ✓ | ✓ | +| 7.0 | x86 | | ✓ | + Adding other architectures that are supported by QNX Neutrino is possible. -The standard library, including `core` and `alloc` (with default allocator) are supported. +In the table above, 'full support' indicates support for building Rust applications with the full standard library. +'`no_std` support' indicates that only `core` and `alloc` are available. For building or using the Rust toolchain for QNX Neutrino, the [QNX Software Development Platform (SDP)](https://blackberry.qnx.com/en/products/foundation-software/qnx-software-development-platform) @@ -70,7 +78,7 @@ fn panic(_panic: &PanicInfo<'_>) -> ! { pub extern "C" fn rust_eh_personality() {} ``` -The QNX Neutrino support of Rust has been tested with QNX Neutrino 7.1. +The QNX Neutrino support of Rust has been tested with QNX Neutrino 7.0 and 7.1. There are no further known requirements. @@ -80,6 +88,7 @@ For conditional compilation, following QNX Neutrino specific attributes are defi - `target_os` = `"nto"` - `target_env` = `"nto71"` (for QNX Neutrino 7.1) +- `target_env` = `"nto70"` (for QNX Neutrino 7.0) ## Building the target diff --git a/src/doc/rustc/src/platform-support/openharmony.md b/src/doc/rustc/src/platform-support/openharmony.md new file mode 100644 index 000000000..a8dcc6443 --- /dev/null +++ b/src/doc/rustc/src/platform-support/openharmony.md @@ -0,0 +1,128 @@ +# `*-unknown-linux-ohos` + +**Tier: 3** + +Targets for the [OpenHarmony](https://gitee.com/openharmony/docs/) operating +system. + +## Target maintainers + +- Amanieu d'Antras ([@Amanieu](https://github.com/Amanieu)) + +## Setup + +The OpenHarmony SDK doesn't currently support Rust compilation directly, so +some setup is required. + +First, you must obtain the OpenHarmony SDK from [this page](https://gitee.com/openharmony/docs/tree/master/en/release-notes). +Select the version of OpenHarmony you are developing for and download the "Public SDK package for the standard system". + +Create the following shell scripts that wrap Clang from the OpenHarmony SDK: + +`aarch64-unknown-linux-ohos-clang.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \ + -target aarch64-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + "$@" +``` + +`aarch64-unknown-linux-ohos-clang++.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \ + -target aarch64-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + "$@" +``` + +`armv7-unknown-linux-ohos-clang.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \ + -target arm-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + -march=armv7-a \ + -mfloat-abi=softfp \ + -mtune=generic-armv7-a \ + -mthumb \ + "$@" +``` + +`armv7-unknown-linux-ohos-clang++.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \ + -target arm-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + -march=armv7-a \ + -mfloat-abi=softfp \ + -mtune=generic-armv7-a \ + -mthumb \ + "$@" +``` + +Future versions of the OpenHarmony SDK will avoid the need for this process. + +## Building the target + +To build a rust toolchain, create a `config.toml` with the following contents: + +```toml +profile = "compiler" +changelog-seen = 2 + +[build] +sanitizers = true +profiler = true + +[target.aarch64-unknown-linux-ohos] +cc = "/path/to/aarch64-unknown-linux-ohos-clang.sh" +cxx = "/path/to/aarch64-unknown-linux-ohos-clang++.sh" +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib" +linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh" + +[target.armv7-unknown-linux-ohos] +cc = "/path/to/armv7-unknown-linux-ohos-clang.sh" +cxx = "/path/to/armv7-unknown-linux-ohos-clang++.sh" +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib" +linker = "/path/to/armv7-unknown-linux-ohos-clang.sh" +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +You will need to configure the linker to use in `~/.cargo/config`: +```toml +[target.aarch64-unknown-linux-ohos] +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh" + +[target.armv7-unknown-linux-ohos] +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +linker = "/path/to/armv7-unknown-linux-ohos-clang.sh" +``` + +## Testing + +Running the Rust testsuite is possible, but currently difficult due to the way +the OpenHarmony emulator is set up (no networking). + +## Cross-compilation toolchains and C code + +You can use the shell scripts above to compile C code for the target. diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index 2a2e51b2f..b46d80eb3 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -179,7 +179,7 @@ $ rustdoc src/lib.rs --test This flag will run your code examples as tests. For more, see [the chapter on documentation tests](write-documentation/documentation-tests.md). -See also `--test-args`. +See also `--test-args` and `--test-run-directory`. ## `--test-args`: pass options to test runner @@ -194,6 +194,19 @@ For more, see [the chapter on documentation tests](write-documentation/documenta See also `--test`. +## `--test-run-directory`: run code examples in a specific directory + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs --test --test-run-directory=/path/to/working/directory +``` + +This flag will run your code examples in the specified working directory. +For more, see [the chapter on documentation tests](write-documentation/documentation-tests.md). + +See also `--test`. + ## `--target`: generate documentation for the specified target triple Using this flag looks like this: @@ -320,10 +333,7 @@ $ rustdoc src/lib.rs --extend-css extra.css ``` With this flag, the contents of the files you pass are included at the bottom -of Rustdoc's `theme.css` file. - -While this flag is stable, the contents of `theme.css` are not, so be careful! -Updates may break your theme extensions. +of the `theme.css` file. ## `--sysroot`: override the system root diff --git a/src/doc/rustdoc/src/how-to-read-rustdoc.md b/src/doc/rustdoc/src/how-to-read-rustdoc.md index 28a004a92..56342f65d 100644 --- a/src/doc/rustdoc/src/how-to-read-rustdoc.md +++ b/src/doc/rustdoc/src/how-to-read-rustdoc.md @@ -80,13 +80,31 @@ functions, and "In Return Types" shows matches in the return types of functions. Both are very useful when looking for a function whose name you can't quite bring to mind when you know the type you have or want. -When typing in the search bar, you can prefix your search term with a type -followed by a colon (such as `mod:`) to restrict the results to just that -kind of item. (The available items are listed in the help popup.) - -Searching for `println!` will search for a macro named `println`, just like +Names in the search interface can be prefixed with an item type followed by a +colon (such as `mod:`) to restrict the results to just that kind of item. Also, +searching for `println!` will search for a macro named `println`, just like searching for `macro:println` does. +Function signature searches can query generics, wrapped in angle brackets, and +traits are normalized like types in the search engine. For example, a function +with the signature `fn my_function<I: Iterator<Item=u32>>(input: I) -> usize` +can be matched with the following queries: + +* `Iterator<u32> -> usize` +* `trait:Iterator<primitive:u32> -> primitive:usize` +* `Iterator -> usize` + +Generics and function parameters are order-agnostic, but sensitive to nesting +and number of matches. For example, a function with the signature +`fn read_all(&mut self: impl Read) -> Result<Vec<u8>, Error>` +will match these queries: + +* `Read -> Result<Vec<u8>, Error>` +* `Read -> Result<Error, Vec>` +* `Read -> Result<Vec<u8>>` + +But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`. + ### Changing displayed theme You can change the displayed theme by opening the settings menu (the gear diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index b8b5014ab..ae180439d 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -38,6 +38,15 @@ future. Attempting to use these error numbers on stable will result in the code sample being interpreted as plain text. +### `missing_doc_code_examples` lint + +This lint will emit a warning if an item doesn't have a code example in its documentation. +It can be enabled using: + +```rust,ignore (nightly) +#![deny(rustdoc::missing_doc_code_examples)] +``` + ## Extensions to the `#[doc]` attribute These features operate by extending the `#[doc]` attribute, and thus can be caught by the compiler @@ -177,9 +186,9 @@ Book][unstable-masked] and [its tracking issue][issue-masked]. This is for Rust compiler internal use only. Since primitive types are defined in the compiler, there's no place to attach documentation -attributes. The `#[doc(primitive)]` attribute is used by the standard library to provide a way -to generate documentation for primitive types, and requires `#![feature(rustdoc_internals)]` to -enable. +attributes. The `#[rustc_doc_primitive = "..."]` attribute is used by the standard library to +provide a way to generate documentation for primitive types, and requires `#![feature(rustc_attrs)]` +to enable. ### Document keywords diff --git a/src/doc/rustdoc/src/write-documentation/documentation-tests.md b/src/doc/rustdoc/src/write-documentation/documentation-tests.md index 1cb5b049d..a7d3186fb 100644 --- a/src/doc/rustdoc/src/write-documentation/documentation-tests.md +++ b/src/doc/rustdoc/src/write-documentation/documentation-tests.md @@ -443,3 +443,15 @@ pub struct ReadmeDoctests; This will include your README as documentation on the hidden struct `ReadmeDoctests`, which will then be tested alongside the rest of your doctests. + +## Controlling the compilation and run directories + +By default, `rustdoc --test` will compile and run documentation test examples +from the same working directory. +The compilation directory is being used for compiler diagnostics, the `file!()` macro and +the output of `rustdoc` test runner itself, whereas the run directory has an influence on file-system +operations within documentation test examples, such as `std::fs::read_to_string`. + +The `--test-run-directory` flag allows controlling the run directory separately from the compilation directory. +This is particularly useful in workspaces, where compiler invocations and thus diagnostics should be +relative to the workspace directory, but documentation test examples should run relative to the crate directory. diff --git a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md index 36bc312b9..eb2285ef9 100644 --- a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md +++ b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md @@ -103,6 +103,13 @@ macro_rules! foo { } ``` +There is one case where the disambiguation will be performed automatically: if an intra doc +link is resolved at the same time as a trait and as a derive proc-macro. In this case, it'll +always generate a link to the trait and not emit a "missing disambiguation" warning. A good +example of this case is when you link to the `Clone` trait: there is also a `Clone` +proc-macro but it ignores it in this case. If you want to link to the proc-macro, you can +use the `macro@` disambiguator. + ## Warnings, re-exports, and scoping Links are resolved in the scope of the module where the item is defined, even diff --git a/src/doc/rustdoc/src/write-documentation/what-to-include.md b/src/doc/rustdoc/src/write-documentation/what-to-include.md index e1e09aa4a..16457ed0f 100644 --- a/src/doc/rustdoc/src/write-documentation/what-to-include.md +++ b/src/doc/rustdoc/src/write-documentation/what-to-include.md @@ -39,9 +39,7 @@ warning: 1 warning emitted As a library author, adding the lint `#![deny(missing_docs)]` is a great way to ensure the project does not drift away from being documented well, and `#![warn(missing_docs)]` is a good way to move towards comprehensive -documentation. In addition to docs, `#![deny(missing_doc_code_examples)]` -ensures each function contains a usage example. In our example above, the -warning is resolved by adding crate level documentation. +documentation. There are more lints in the upcoming chapter [Lints][rustdoc-lints]. diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md index c7d0446dd..96f66c89c 100644 --- a/src/doc/style-guide/src/expressions.md +++ b/src/doc/style-guide/src/expressions.md @@ -643,7 +643,7 @@ Examples: ```rust match foo { foo => bar, - a_very_long_patten | another_pattern if an_expression() => { + a_very_long_pattern | another_pattern if an_expression() => { no_room_for_this_expression() } foo => { diff --git a/src/doc/unstable-book/src/compiler-flags/cf-protection.md b/src/doc/unstable-book/src/compiler-flags/cf-protection.md index ab698c82b..efe5f5642 100644 --- a/src/doc/unstable-book/src/compiler-flags/cf-protection.md +++ b/src/doc/unstable-book/src/compiler-flags/cf-protection.md @@ -1,5 +1,9 @@ # `cf-protection` +The tracking issue for this feature is: [#93754](https://github.com/rust-lang/rust/issues/93754). + +------------------------ + This option enables control-flow enforcement technology (CET) on x86; a more detailed description of CET is available [here]. Similar to `clang`, this flag takes one of the following values: diff --git a/src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md b/src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md index a497a7526..05ffdcf20 100644 --- a/src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md +++ b/src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md @@ -3,4 +3,4 @@ -------------------- The `-Z dump-mono-stats-format` compiler flag controls what file format to use for `-Z dump-mono-stats`. -The default is markdown; currently JSON is also supported. JSON can be useful for programatically manipulating the results (e.g. to find the item that took the longest to compile). +The default is markdown; currently JSON is also supported. JSON can be useful for programmatically manipulating the results (e.g. to find the item that took the longest to compile). diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 262cef345..b55348b78 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -213,7 +213,7 @@ See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details. ## Example -```text +```rust,ignore (making doc tests pass cross-platform is hard) #![feature(naked_functions)] use std::arch::asm; @@ -238,7 +238,7 @@ pub extern "C" fn add_two(x: i32) { nop nop nop - lea rax, [rdi+2] + lea eax, [edi+2] ret ", options(noreturn) diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index 0a48eb4f8..1f52ab750 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -16,6 +16,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect - SPIR-V - AVR - MSP430 +- M68k ## Register classes @@ -41,6 +42,9 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | AVR | `reg_iw` | `r25r24`, `X`, `Z` | `w` | | AVR | `reg_ptr` | `X`, `Z` | `e` | | MSP430 | `reg` | `r[0-15]` | `r` | +| M68k | `reg` | `d[0-7]`, `a[0-7]` | `r` | +| M68k | `reg_data` | `d[0-7]` | `d` | +| M68k | `reg_addr` | `a[0-3]` | `a` | > **Notes**: > - NVPTX doesn't have a fixed register set, so named registers are not supported. @@ -70,6 +74,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | AVR | `reg`, `reg_upper` | None | `i8` | | AVR | `reg_pair`, `reg_iw`, `reg_ptr` | None | `i16` | | MSP430 | `reg` | None | `i8`, `i16` | +| M68k | `reg`, `reg_addr` | None | `i16`, `i32` | +| M68k | `reg_data` | None | `i8`, `i16`, `i32` | ## Register aliases @@ -88,6 +94,9 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | MSP430 | `r2` | `sr` | | MSP430 | `r3` | `cg` | | MSP430 | `r4` | `fp` | +| M68k | `a5` | `bp` | +| M68k | `a6` | `fp` | +| M68k | `a7` | `sp`, `usp`, `ssp`, `isp` | > **Notes**: > - TI does not mandate a frame pointer for MSP430, but toolchains are allowed @@ -98,7 +107,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Architecture | Unsupported register | Reason | | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. | -| All | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430) | The frame pointer cannot be used as an input or output. | +| All | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k) | The frame pointer cannot be used as an input or output. | | All | `r19` (Hexagon) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. | | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | | MIPS | `$1` or `$at` | Reserved for assembler. | @@ -108,6 +117,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | | AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. | |MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to. | +| M68k | `a4`, `a5` | Used internally by LLVM for the base pointer and global base pointer. | ## Template modifiers @@ -130,3 +140,5 @@ These flags registers must be restored upon exiting the asm block if the `preser - The status register `SREG`. - MSP430 - The status register `r2`. +- M68k + - The condition code register `ccr`. diff --git a/src/doc/unstable-book/src/language-features/box-patterns.md b/src/doc/unstable-book/src/language-features/box-patterns.md index 584f4295c..a1ac09633 100644 --- a/src/doc/unstable-book/src/language-features/box-patterns.md +++ b/src/doc/unstable-book/src/language-features/box-patterns.md @@ -4,8 +4,6 @@ The tracking issue for this feature is: [#29641] [#29641]: https://github.com/rust-lang/rust/issues/29641 -See also [`box_syntax`](box-syntax.md) - ------------------------ Box patterns let you match on `Box<T>`s: diff --git a/src/doc/unstable-book/src/language-features/box-syntax.md b/src/doc/unstable-book/src/language-features/box-syntax.md deleted file mode 100644 index 9569974d2..000000000 --- a/src/doc/unstable-book/src/language-features/box-syntax.md +++ /dev/null @@ -1,22 +0,0 @@ -# `box_syntax` - -The tracking issue for this feature is: [#49733] - -[#49733]: https://github.com/rust-lang/rust/issues/49733 - -See also [`box_patterns`](box-patterns.md) - ------------------------- - -Currently the only stable way to create a `Box` is via the `Box::new` method. -Also it is not possible in stable Rust to destructure a `Box` in a match -pattern. The unstable `box` keyword can be used to create a `Box`. An example -usage would be: - -```rust -#![feature(box_syntax)] - -fn main() { - let b = box 5; -} -``` diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md index 39238dffa..6adb3506e 100644 --- a/src/doc/unstable-book/src/language-features/lang-items.md +++ b/src/doc/unstable-book/src/language-features/lang-items.md @@ -16,18 +16,26 @@ and one for deallocation. A freestanding program that uses the `Box` sugar for dynamic allocations via `malloc` and `free`: ```rust,ignore (libc-is-finicky) -#![feature(lang_items, box_syntax, start, libc, core_intrinsics, rustc_private)] +#![feature(lang_items, start, libc, core_intrinsics, rustc_private, rustc_attrs)] #![no_std] use core::intrinsics; use core::panic::PanicInfo; +use core::ptr::NonNull; extern crate libc; -struct Unique<T>(*mut T); +struct Unique<T>(NonNull<T>); #[lang = "owned_box"] pub struct Box<T>(Unique<T>); +impl<T> Box<T> { + pub fn new(x: T) -> Self { + #[rustc_box] + Box::new(x) + } +} + #[lang = "exchange_malloc"] unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { let p = libc::malloc(size as libc::size_t) as *mut u8; @@ -47,13 +55,13 @@ unsafe fn box_free<T: ?Sized>(ptr: *mut T) { #[start] fn main(_argc: isize, _argv: *const *const u8) -> isize { - let _x = box 1; + let _x = Box::new(1); 0 } #[lang = "eh_personality"] extern fn rust_eh_personality() {} -#[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } } +#[lang = "panic_impl"] extern fn rust_begin_panic(_info: &PanicInfo) -> ! { intrinsics::abort() } #[no_mangle] pub extern fn rust_eh_register_frames () {} #[no_mangle] pub extern fn rust_eh_unregister_frames () {} ``` diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index dfbb468d4..1fade6ce9 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -37,7 +37,7 @@ additional checks for code style, safety, etc. Now let's write a plugin that warns about any item named `lintme`. ```rust,ignore (requires-stage-2) -#![feature(box_syntax, rustc_private)] +#![feature(rustc_private)] extern crate rustc_ast; @@ -68,7 +68,7 @@ impl EarlyLintPass for Pass { #[no_mangle] fn __rustc_plugin_registrar(reg: &mut Registry) { reg.lint_store.register_lints(&[&TEST_LINT]); - reg.lint_store.register_early_pass(|| box Pass); + reg.lint_store.register_early_pass(|| Box::new(Pass)); } ``` diff --git a/src/doc/unstable-book/src/the-unstable-book.md b/src/doc/unstable-book/src/the-unstable-book.md index 554c52c3c..9090b134d 100644 --- a/src/doc/unstable-book/src/the-unstable-book.md +++ b/src/doc/unstable-book/src/the-unstable-book.md @@ -5,16 +5,31 @@ each one organized by a "feature flag." That is, when using an unstable feature of Rust, you must use a flag, like this: ```rust -#![feature(box_syntax)] +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; fn main() { - let five = box 5; + let mut generator = || { + yield 1; + return "foo" + }; + + match Pin::new(&mut generator).resume(()) { + GeneratorState::Yielded(1) => {} + _ => panic!("unexpected value from resume"), + } + match Pin::new(&mut generator).resume(()) { + GeneratorState::Complete("foo") => {} + _ => panic!("unexpected value from resume"), + } } ``` -The `box_syntax` feature [has a chapter][box] describing how to use it. +The `generators` feature [has a chapter][generators] describing how to use it. -[box]: language-features/box-syntax.md +[generators]: language-features/generators.md Because this documentation relates to unstable features, we make no guarantees that what is contained here is accurate or up to date. It's developed on a |