Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit bdc5f20

Browse files
authoredFeb 23, 2018
Merge branch 'master' into traits
2 parents c5db341 + 6e1eccd commit bdc5f20

15 files changed

+992
-7
lines changed
 

‎.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ deploy:
1616
provider: pages
1717
skip-cleanup: true
1818
github-token: $GITHUB_TOKEN
19-
local-dir: book
19+
local-dir: book/html
2020
on:
2121
branch: master

‎ci/install.sh

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@ function cargo_install() {
66
local version=$2
77

88
if command -v $name >/dev/null 2>&1; then
9-
echo "$name is already installed at $(command -v $name)"
9+
local installed_version=`$name --version | sed -E 's/[a-zA-Z_-]+ v?//g'`
10+
if [ "$installed_version" == "$version" ]; then
11+
echo "$name $version is already installed at $(command -v $name)"
12+
else
13+
echo "Forcing install $name $version"
14+
cargo install $name --version $version --force
15+
fi
1016
else
11-
echo "Installing $name"
17+
echo "Installing $name $version"
1218
cargo install $name --version $version
1319
fi
1420
}

‎src/SUMMARY.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
- [About this guide](./about-this-guide.md)
44
- [How to build the compiler and run what you built](./how-to-build-and-run.md)
5-
- [Using the compiler testing framework](./running-tests.md)
5+
- [Coding conventions](./conventions.md)
6+
- [The compiler testing framework](./tests/intro.md)
7+
- [Running tests](./tests/running.md)
8+
- [Adding new tests](./tests/adding.md)
9+
- [Using `compiletest` + commands to control test execution](./compiletest.md)
610
- [Walkthrough: a typical contribution](./walkthrough.md)
711
- [High-level overview of the compiler source](./high-level-overview.md)
812
- [Queries: demand-driven compilation](./query.md)
@@ -22,5 +26,8 @@
2226
- [MIR construction](./mir-construction.md)
2327
- [MIR borrowck](./mir-borrowck.md)
2428
- [MIR optimizations](./mir-optimizations.md)
29+
- [Constant evaluation](./const-eval.md)
30+
- [miri const evaluator](./miri.md)
31+
- [Parameter Environments](./param_env.md)
2532
- [Generating LLVM IR](./trans.md)
2633
- [Glossary](./glossary.md)

‎src/compiletest.md

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# `compiletest`
2+
## Introduction
3+
`compiletest` is the main test harness of the Rust test suite. It allows test authors to organize large numbers of tests (the
4+
Rust compiler has many thousands), efficient test execution (parallel execution is supported), and allows the test author to
5+
configure behavior and expected results of both individual and groups of tests.
6+
7+
`compiletest` tests may check test code for success, for failure or in some cases, even failure to compile. Tests are
8+
typically organized as a Rust source file with annotations in comments before and/or within the test code, which serve to
9+
direct `compiletest` on if or how to run the test, what behavior to expect, and more. If you are unfamiliar with the compiler
10+
testing framework, see [`this chapter`](./tests/intro.html) for additional background.
11+
12+
The tests themselves are typically (but not always) organized into "suites"--for example, `run-pass`, a folder
13+
representing tests that should succeed, `run-fail`, a folder holding tests that should compile successfully, but return
14+
a failure (non-zero status), `compile-fail`, a folder holding tests that should fail to compile, and many more. The various
15+
suites are defined in [src/tools/compiletest/src/common.rs](https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/common.rs) in the `pub struct Config` declaration. And a very good
16+
introduction to the different suites of compiler tests along with details about them can be found in [`Adding new tests`](./tests/adding.html).
17+
18+
## Adding a new test file
19+
Briefly, simply create your new test in the appropriate location under [src/test](https://github.com/rust-lang/rust/tree/master/src/test). No registration of test files is necessary as
20+
`compiletest` will scan the [src/test](https://github.com/rust-lang/rust/tree/master/src/test) subfolder recursively, and will execute any Rust source files it finds as tests.
21+
See [`Adding new tests`](./tests/adding.html) for a complete guide on how to adding new tests.
22+
23+
## Header Commands
24+
Source file annotations which appear in comments near the top of the source file *before* any test code are known as header
25+
commands. These commands can instruct `compiletest` to ignore this test, set expectations on whether it is expected to
26+
succeed at compiling, or what the test's return code is expected to be. Header commands (and their inline counterparts,
27+
Error Info commands) are described more fully [here](./tests/adding.html#header-commands-configuring-rustc).
28+
29+
### Adding a new header command
30+
Header commands are defined in the `TestProps` struct in [src/tools/compiletest/src/header.rs](https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/header.rs). At a high level, there are dozens of test properties defined here, all set to default values in the `TestProp` struct's `impl` block. Any test can override this
31+
default value by specifying the property in question as header command as a comment (`//`) in the test source file, before any source code.
32+
33+
#### Using a header command
34+
Here is an example, specifying the `must-compile-successfully` header command, which takes no arguments, followed by the
35+
`failure-status` header command, which takes a single argument (which, in this case is a value of 1). `failure-status` is
36+
instructing `compiletest` to expect a failure status of 1 (rather than the current Rust default of 101 at the time of this
37+
writing). The header command and the argument list (if present) are typically separated by a colon:
38+
```
39+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
40+
// file at the top-level directory of this distribution and at
41+
// http://rust-lang.org/COPYRIGHT.
42+
//
43+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
44+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
45+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
46+
// option. This file may not be copied, modified, or distributed
47+
// except according to those terms.
48+
49+
// must-compile-successfully
50+
// failure-status: 1
51+
52+
#![feature(termination_trait)]
53+
54+
use std::io::{Error, ErrorKind};
55+
56+
fn main() -> Result<(), Box<Error>> {
57+
Err(Box::new(Error::new(ErrorKind::Other, "returned Box<Error> from main()")))
58+
}
59+
```
60+
61+
#### Adding a new header command property
62+
One would add a new header command if there is a need to define some test property or behavior on an individual, test-by-test
63+
basis. A header command property serves as the header command's backing store (holds the command's current value) at
64+
runtime.
65+
66+
To add a new header command property:
67+
1. Look for the `pub struct TestProps` declaration in [src/tools/compiletest/src/header.rs](https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/header.rs) and add
68+
the new public property to the end of the declaration.
69+
2. Look for the `impl TestProps` implementation block immediately following the struct declaration and initialize the new
70+
property to its default value.
71+
72+
#### Adding a new header command parser
73+
When `compiletest` encounters a test file, it parses the file a line at a time by calling every parser defined in the
74+
`Config` struct's implementation block, also in [src/tools/compiletest/src/header.rs](https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/header.rs) (note the `Config` struct's declaration
75+
block is found in [src/tools/compiletest/src/common.rs](https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/common.rs). `TestProps`'s `load_from()` method will try passing the current
76+
line of text to each parser, which, in turn typically checks to see if the line begins with a particular commented (`//`)
77+
header command such as `// must-compile-successfully` or `// failure-status`. Whitespace after the comment marker is
78+
optional.
79+
80+
Parsers will override a given header command property's default value merely by being specified in the test file as a header
81+
command or by having a parameter value specified in the test file, depending on the header command.
82+
83+
Parsers defined in `impl Config` are typically named `parse_<header_command>` (note kebab-case `<header-command>` transformed
84+
to snake-case `<header_command>`). `impl Config` also defines several 'low-level' parsers which make it simple to parse
85+
common patterns like simple presence or not (`parse_name_directive()`), header-command:parameter(s)
86+
(`parse_name_value_directive()`), optional parsing only if a particular `cfg` attribute is defined (`has_cfg_prefix()`) and
87+
many more. The low-level parsers are found near the end of the `impl Config` block; be sure to look through them and their
88+
associated parsers immediately above to see how they are used to avoid writing additional parsing code unneccessarily.
89+
90+
As a concrete example, here is the implementation for the `parse_failure_status()` parser, in
91+
[src/tools/compiletest/src/header.rs](https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/header.rs):
92+
```diff
93+
@@ -232,6 +232,7 @@ pub struct TestProps {
94+
// customized normalization rules
95+
pub normalize_stdout: Vec<(String, String)>,
96+
pub normalize_stderr: Vec<(String, String)>,
97+
+ pub failure_status: i32,
98+
}
99+
100+
impl TestProps {
101+
@@ -260,6 +261,7 @@ impl TestProps {
102+
run_pass: false,
103+
normalize_stdout: vec![],
104+
normalize_stderr: vec![],
105+
+ failure_status: 101,
106+
}
107+
}
108+
109+
@@ -383,6 +385,10 @@ impl TestProps {
110+
if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stderr") {
111+
self.normalize_stderr.push(rule);
112+
}
113+
+
114+
+ if let Some(code) = config.parse_failure_status(ln) {
115+
+ self.failure_status = code;
116+
+ }
117+
});
118+
119+
for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
120+
@@ -488,6 +494,13 @@ impl Config {
121+
self.parse_name_directive(line, "pretty-compare-only")
122+
}
123+
124+
+ fn parse_failure_status(&self, line: &str) -> Option<i32> {
125+
+ match self.parse_name_value_directive(line, "failure-status") {
126+
+ Some(code) => code.trim().parse::<i32>().ok(),
127+
+ _ => None,
128+
+ }
129+
+ }
130+
```
131+
132+
## Implementing the behavior change
133+
When a test invokes a particular header command, it is expected that some behavior will change as a result. What behavior,
134+
obviously, will depend on the purpose of the header command. In the case of `failure-status`, the behavior that changes
135+
is that `compiletest` expects the failure code defined by the header command invoked in the test, rather than the default
136+
value.
137+
138+
Although specific to `failure-status` (as every header command will have a different implementation in order to invoke
139+
behavior change) perhaps it is helpful to see the behavior change implementation of one case, simply as an example. To implement `failure-status`, the `check_correct_failure_status()` function found in the `TestCx` implementation block,
140+
located in [src/tools/compiletest/src/runtest.rs](https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/runtest.rs), was modified as per below:
141+
```diff
142+
@@ -295,11 +295,14 @@ impl<'test> TestCx<'test> {
143+
}
144+
145+
fn check_correct_failure_status(&self, proc_res: &ProcRes) {
146+
- // The value the rust runtime returns on failure
147+
- const RUST_ERR: i32 = 101;
148+
- if proc_res.status.code() != Some(RUST_ERR) {
149+
+ let expected_status = Some(self.props.failure_status);
150+
+ let received_status = proc_res.status.code();
151+
+
152+
+ if expected_status != received_status {
153+
self.fatal_proc_rec(
154+
- &format!("failure produced the wrong error: {}", proc_res.status),
155+
+ &format!("Error: expected failure status ({:?}) but received status {:?}.",
156+
+ expected_status,
157+
+ received_status),
158+
proc_res,
159+
);
160+
}
161+
@@ -320,7 +323,6 @@ impl<'test> TestCx<'test> {
162+
);
163+
164+
let proc_res = self.exec_compiled_test();
165+
-
166+
if !proc_res.status.success() {
167+
self.fatal_proc_rec("test run failed!", &proc_res);
168+
}
169+
@@ -499,7 +501,6 @@ impl<'test> TestCx<'test> {
170+
expected,
171+
actual
172+
);
173+
- panic!();
174+
}
175+
}
176+
```
177+
Note the use of `self.props.failure_status` to access the header command property. In tests which do not specify the failure
178+
status header command, `self.props.failure_status` will evaluate to the default value of 101 at the time of this writing.
179+
But for a test which specifies a header command of, for example, `// failure-status: 1`, `self.props.failure_status` will
180+
evaluate to 1, as `parse_failure_status()` will have overridden the `TestProps` default value, for that test specifically.

‎src/const-eval.md

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Constant Evaluation
2+
3+
Constant evaluation is the process of computing values at compile time. For a
4+
specific item (constant/static/array length) this happens after the MIR for the
5+
item is borrow-checked and optimized. In many cases trying to const evaluate an
6+
item will trigger the computation of its MIR for the first time.
7+
8+
Prominent examples are
9+
10+
* The initializer of a `static`
11+
* Array length
12+
* needs to be known to reserve stack or heap space
13+
* Enum variant discriminants
14+
* needs to be known to prevent two variants from having the same discriminant
15+
* Patterns
16+
* need to be known to check for overlapping patterns
17+
18+
Additionally constant evaluation can be used to reduce the workload or binary
19+
size at runtime by precomputing complex operations at compiletime and only
20+
storing the result.
21+
22+
Constant evaluation can be done by calling the `const_eval` query of `TyCtxt`.
23+
24+
The `const_eval` query takes a [`ParamEnv`](./param_env.html) of environment in
25+
which the constant is evaluated (e.g. the function within which the constant is
26+
used) and a `GlobalId`. The `GlobalId` is made up of an
27+
`Instance` referring to a constant or static or of an
28+
`Instance` of a function and an index into the function's `Promoted` table.
29+
30+
Constant evaluation returns a `Result` with either the error, or the simplest
31+
representation of the constant. "simplest" meaning if it is representable as an
32+
integer or fat pointer, it will directly yield the value (via `Value::ByVal` or
33+
`Value::ByValPair`), instead of referring to the [`miri`](./miri.html) virtual
34+
memory allocation (via `Value::ByRef`). This means that the `const_eval`
35+
function cannot be used to create miri-pointers to the evaluated constant or
36+
static. If you need that, you need to directly work with the functions in
37+
[src/librustc_mir/interpret/const_eval.rs](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/interpret/const_eval.rs).

‎src/conventions.md

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
This file offers some tips on the coding conventions for rustc. This
2+
chapter covers [formatting](#formatting), [coding for correctness](#cc),
3+
[using crates from crates.io](#cio), and some tips on
4+
[structuring your PR for easy review](#er).
5+
6+
<a name=formatting>
7+
8+
# Formatting and the tidy script
9+
10+
rustc is slowly moving towards the [Rust standard coding style][fmt];
11+
at the moment, however, it follows a rather more *chaotic* style. We
12+
do have some mandatory formatting conventions, which are automatically
13+
enforced by a script we affectionately call the "tidy" script. The
14+
tidy script runs automatically when you do `./x.py test`.
15+
16+
[fmt]: https://github.com/rust-lang-nursery/fmt-rfcs
17+
18+
<a name=copyright>
19+
20+
### Copyright notice
21+
22+
All files must begin with the following copyright notice:
23+
24+
```
25+
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
26+
// file at the top-level directory of this distribution and at
27+
// http://rust-lang.org/COPYRIGHT.
28+
//
29+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
30+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
31+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
32+
// option. This file may not be copied, modified, or distributed
33+
// except according to those terms.
34+
```
35+
36+
The year at the top is not meaningful: copyright protections are in
37+
fact automatic from the moment of authorship. We do not typically edit
38+
the years on existing files. When creating a new file, you can use the
39+
current year if you like, but you don't have to.
40+
41+
## Line length
42+
43+
Lines should be at most 100 characters. It's even better if you can
44+
keep things to 80.
45+
46+
**Ignoring the line length limit.** Sometimes -- in particular for
47+
tests -- it can be necessary to exempt yourself from this limit. In
48+
that case, you can add a comment towards the top of the file (after
49+
the copyright notice) like so:
50+
51+
```
52+
// ignore-tidy-linelength
53+
```
54+
55+
## Tabs vs spaces
56+
57+
Prefer 4-space indent.
58+
59+
<a name=cc>
60+
61+
# Coding for correctness
62+
63+
Beyond formatting, there are a few other tips that are worth
64+
following.
65+
66+
## Prefer exhaustive matches
67+
68+
Using `_` in a match is convenient, but it means that when new
69+
variants are added to the enum, they may not get handled correctly.
70+
Ask yourself: if a new variant were added to this enum, what's the
71+
chance that it would want to use the `_` code, versus having some
72+
other treatment? Unless the answer is "low", then prefer an
73+
exhaustive match. (The same advice applies to `if let` and `while
74+
let`, which are effectively tests for a single variant.)
75+
76+
## Use "TODO" comments for things you don't want to forget
77+
78+
As a useful tool to yourself, you can insert a `// TODO` comment
79+
for something that you want to get back to before you land your PR:
80+
81+
```rust,ignore
82+
fn do_something() {
83+
if something_else {
84+
unimplemented!(): // TODO write this
85+
}
86+
}
87+
```
88+
89+
The tidy script will report an error for a `// TODO` comment, so this
90+
code would not be able to land until the TODO is fixed (or removed).
91+
92+
This can also be useful in a PR as a way to signal from one commit that you are
93+
leaving a bug that a later commit will fix:
94+
95+
```rust,ignore
96+
if foo {
97+
return true; // TODO wrong, but will be fixed in a later commit
98+
}
99+
```
100+
101+
<a name=cio>
102+
103+
# Using crates from crates.io
104+
105+
It is allowed to use crates from crates.io, though external
106+
dependencies should not be added gratuitously. All such crates must
107+
have a suitably permissive license. There is an automatic check which
108+
inspects the Cargo metadata to ensure this.
109+
110+
<a name=er>
111+
112+
# How to structure your PR
113+
114+
How you prepare the commits in your PR can make a big difference for the reviewer.
115+
Here are some tips.
116+
117+
**Isolate "pure refactorings" into their own commit.** For example, if
118+
you rename a method, then put that rename into its own commit, along
119+
with the renames of all the uses.
120+
121+
**More commits is usually better.** If you are doing a large change,
122+
it's almost always better to break it up into smaller steps that can
123+
be independently understood. The one thing to be aware of is that if
124+
you introduce some code following one strategy, then change it
125+
dramatically (versus adding to it) in a later commit, that
126+
'back-and-forth' can be confusing.
127+
128+
**If you run rustfmt and the file was not already formatted, isolate
129+
that into its own commit.** This is really the same as the previous
130+
rule, but it's worth highlighting. It's ok to rustfmt files, but since
131+
we do not currently run rustfmt all the time, that can introduce a lot
132+
of noise into your commit. Please isolate that into its own
133+
commit. This also makes rebases a lot less painful, since rustfmt
134+
tends to cause a lot of merge conflicts, and having those isolated
135+
into their own commit makes htem easier to resolve.
136+
137+
**No merges.** We do not allow merge commits into our history, other
138+
than those by bors. If you get a merge conflict, rebase instead via a
139+
command like `git rebase -i rust-lang/master` (presuming you use the
140+
name `rust-lang` for your remote).
141+
142+
**Individual commits do not have to build (but it's nice).** We do not
143+
require that every intermediate commit successfully builds -- we only
144+
expect to be able to bisect at a PR level. However, if you *can* make
145+
individual commits build, that is always helpful.
146+

‎src/glossary.md

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Term | Meaning
77
------------------------|--------
88
AST | the abstract syntax tree produced by the syntax crate; reflects user syntax very closely.
99
codegen unit | when we produce LLVM IR, we group the Rust code into a number of codegen units. Each of these units is processed by LLVM independently from one another, enabling parallelism. They are also the unit of incremental re-use.
10+
completeness | completeness is a technical term in type theory. Completeness means that every type-safe program also type-checks. Having both soundness and completeness is very hard, and usually soundness is more important. (see "soundness").
1011
cx | we tend to use "cx" as an abbrevation for context. See also `tcx`, `infcx`, etc.
1112
DAG | a directed acyclic graph is used during compilation to keep track of dependencies between queries. ([see more](incremental-compilation.html))
1213
DefId | an index identifying a definition (see `librustc/hir/def_id.rs`). Uniquely identifies a `DefPath`.
@@ -17,6 +18,9 @@ generics | the set of generic type parameters defined on a type
1718
ICE | internal compiler error. When the compiler crashes.
1819
ICH | incremental compilation hash. ICHs are used as fingerprints for things such as HIR and crate metadata, to check if changes have been made. This is useful in incremental compilation to see if part of a crate has changed and should be recompiled.
1920
infcx | the inference context (see `librustc/infer`)
21+
MIR | the Mid-level IR that is created after type-checking for use by borrowck and trans ([see more](./mir.html))
22+
miri | an interpreter for MIR used for constant evaluation ([see more](./miri.html))
23+
obligation | something that must be proven by the trait system ([see more](trait-resolution.html))
2024
local crate | the crate currently being compiled.
2125
MIR | the Mid-level IR that is created after type-checking for use by borrowck and trans ([see more](./mir.html))
2226
node-id or NodeId | an index identifying a particular node in the AST or HIR; gradually being phased out and replaced with `HirId`.
@@ -25,6 +29,7 @@ provider | the function that executes a query ([see more](query.
2529
query | perhaps some sub-computation during compilation ([see more](query.html))
2630
sess | the compiler session, which stores global data used throughout compilation
2731
side tables | because the AST and HIR are immutable once created, we often carry extra information about them in the form of hashtables, indexed by the id of a particular node.
32+
soundness | soundness is a technical term in type theory. Roughly, if a type system is sound, then if a program type-checks, it is type-safe; i.e. I can never (in safe rust) force a value into a variable of the wrong type. (see "completeness").
2833
span | a location in the user's source code, used for error reporting primarily. These are like a file-name/line-number/column tuple on steroids: they carry a start/end point, and also track macro expansions and compiler desugaring. All while being packed into a few bytes (really, it's an index into a table). See the Span datatype for more.
2934
substs | the substitutions for a given generic type or item (e.g. the `i32`, `u32` in `HashMap<i32, u32>`)
3035
tcx | the "typing context", main data structure of the compiler ([see more](ty.html))

‎src/how-to-build-and-run.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,6 @@ Here are a few other useful x.py commands. We'll cover some of them in detail in
132132
- `./x.py clean` – clean up the build directory (`rm -rf build` works too, but then you have to rebuild LLVM)
133133
- `./x.py build --stage 1` – builds everything using the stage 1 compiler, not just up to libstd
134134
- `./x.py build` – builds the stage2 compiler
135-
- Running tests (see the section [running tests](./running-tests.html) for more details):
135+
- Running tests (see the [section on running tests](./tests/running.html) for more details):
136136
- `./x.py test --stage 1 src/libstd` – runs the `#[test]` tests from libstd
137137
- `./x.py test --stage 1 src/test/run-pass` – runs the `run-pass` test suite

‎src/miri.md

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Miri
2+
3+
Miri (**MIR** **I**nterpreter) is a virtual machine for executing MIR without
4+
compiling to machine code. It is usually invoked via `tcx.const_eval`.
5+
6+
If you start out with a constant
7+
8+
```rust
9+
const FOO: usize = 1 << 12;
10+
```
11+
12+
rustc doesn't actually invoke anything until the constant is either used or
13+
placed into metadata.
14+
15+
Once you have a use-site like
16+
17+
```rust
18+
type Foo = [u8; FOO - 42];
19+
```
20+
21+
The compiler needs to figure out the length of the array before being able to
22+
create items that use the type (locals, constants, function arguments, ...).
23+
24+
To obtain the (in this case empty) parameter environment, one can call
25+
`let param_env = tcx.param_env(length_def_id);`. The `GlobalId` needed is
26+
27+
```rust
28+
let gid = GlobalId {
29+
promoted: None,
30+
instance: Instance::mono(length_def_id),
31+
};
32+
```
33+
34+
Invoking `tcx.const_eval(param_env.and(gid))` will now trigger the creation of
35+
the MIR of the array length expression. The MIR will look something like this:
36+
37+
```mir
38+
const Foo::{{initializer}}: usize = {
39+
let mut _0: usize; // return pointer
40+
let mut _1: (usize, bool);
41+
42+
bb0: {
43+
_1 = CheckedSub(const Unevaluated(FOO, Slice([])), const 42usize);
44+
assert(!(_1.1: bool), "attempt to subtract with overflow") -> bb1;
45+
}
46+
47+
bb1: {
48+
_0 = (_1.0: usize);
49+
return;
50+
}
51+
}
52+
```
53+
54+
Before the evaluation, a virtual memory location (in this case essentially a
55+
`vec![u8; 4]` or `vec![u8; 8]`) is created for storing the evaluation result.
56+
57+
At the start of the evaluation, `_0` and `_1` are
58+
`Value::ByVal(PrimVal::Undef)`. When the initialization of `_1` is invoked, the
59+
value of the `FOO` constant is required, and triggers another call to
60+
`tcx.const_eval`, which will not be shown here. If the evaluation of FOO is
61+
successful, 42 will be subtracted by its value `4096` and the result stored in
62+
`_1` as `Value::ByValPair(PrimVal::Bytes(4054), PrimVal::Bytes(0))`. The first
63+
part of the pair is the computed value, the second part is a bool that's true if
64+
an overflow happened.
65+
66+
The next statement asserts that said boolean is `0`. In case the assertion
67+
fails, its error message is used for reporting a compile-time error.
68+
69+
Since it does not fail, `Value::ByVal(PrimVal::Bytes(4054))` is stored in the
70+
virtual memory was allocated before the evaluation. `_0` always refers to that
71+
location directly.
72+
73+
After the evaluation is done, the virtual memory allocation is interned into the
74+
`TyCtxt`. Future evaluations of the same constants will not actually invoke
75+
miri, but just extract the value from the interned allocation.
76+
77+
The `tcx.const_eval` function has one additional feature: it will not return a
78+
`ByRef(interned_allocation_id)`, but a `ByVal(computed_value)` if possible. This
79+
makes using the result much more convenient, as no further queries need to be
80+
executed in order to get at something as simple as a `usize`.
81+
82+
## Datastructures
83+
84+
Miri's core datastructures can be found in
85+
[librustc/mir/interpret](https://github.com/rust-lang/rust/blob/master/src/librustc/mir/interpret).
86+
This is mainly the error enum and the `Value` and `PrimVal` types. A `Value` can
87+
be either `ByVal` (a single `PrimVal`), `ByValPair` (two `PrimVal`s, usually fat
88+
pointers or two element tuples) or `ByRef`, which is used for anything else and
89+
refers to a virtual allocation. These allocations can be accessed via the
90+
methods on `tcx.interpret_interner`.
91+
92+
If you are expecting a numeric result, you can use `unwrap_u64` (panics on
93+
anything that can't be representad as a `u64`) or `to_raw_bits` which results
94+
in an `Option<u128>` yielding the `ByVal` if possible.
95+
96+
## Allocations
97+
98+
A miri allocation is either a byte sequence of the memory or an `Instance` in
99+
the case of function pointers. Byte sequences can additionally contain
100+
relocations that mark a group of bytes as a pointer to another allocation. The
101+
actual bytes at the relocation refer to the offset inside the other allocation.
102+
103+
These allocations exist so that references and raw pointers have something to
104+
point to. There is no global linear heap in which things are allocated, but each
105+
allocation (be it for a local variable, a static or a (future) heap allocation)
106+
gets its own little memory with exactly the required size. So if you have a
107+
pointer to an allocation for a local variable `a`, there is no possible (no
108+
matter how unsafe) operation that you can do that would ever change said pointer
109+
to a pointer to `b`.
110+
111+
## Interpretation
112+
113+
Although the main entry point to constant evaluation is the `tcx.const_eval`
114+
query, there are additional functions in
115+
[librustc_mir/interpret/const_eval.rs](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/interpret/const_eval.rs)
116+
that allow accessing the fields of a `Value` (`ByRef` or otherwise). You should
117+
never have to access an `Allocation` directly except for translating it to the
118+
compilation target (at the moment just LLVM).
119+
120+
Miri starts by creating a virtual stack frame for the current constant that is
121+
being evaluated. There's essentially no difference between a constant and a
122+
function with no arguments, except that constants do not allow local (named)
123+
variables at the time of writing this guide.
124+
125+
A stack frame is defined by the `Frame` type in
126+
[librustc_mir/interpret/eval_context.rs](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/interpret/eval_context.rs)
127+
and contains all the local
128+
variables memory (`None` at the start of evaluation). Each frame refers to the
129+
evaluation of either the root constant or subsequent calls to `const fn`. The
130+
evaluation of another constant simply calls `tcx.const_eval`, which produces an
131+
entirely new and independent stack frame.
132+
133+
The frames are just a `Vec<Frame>`, there's no way to actually refer to a
134+
`Frame`'s memory even if horrible shenigans are done via unsafe code. The only
135+
memory that can be referred to are `Allocation`s.
136+
137+
Miri now calls the `step` method (in
138+
[librustc_mir/interpret/step.rs](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/interpret/step.rs)
139+
) until it either returns an error or has no further statements to execute. Each
140+
statement will now initialize or modify the locals or the virtual memory
141+
referred to by a local. This might require evaluating other constants or
142+
statics, which just recursively invokes `tcx.const_eval`.

‎src/param_env.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Parameter Environment
2+
3+
When working with associated and/or or generic items (types, constants,
4+
functions/methods) it is often relevant to have more information about the
5+
`Self` or generic parameters. Trait bounds and similar information is encoded in
6+
the `ParamEnv`. Often this is not enough information to obtain things like the
7+
type's `Layout`, but you can do all kinds of other checks on it (e.g. whether a
8+
type implements `Copy`) or you can evaluate an associated constant whose value
9+
does not depend on anything from the parameter environment.
10+
11+
For example if you have a function
12+
13+
```rust
14+
fn foo<T: Copy>(t: T) {
15+
}
16+
```
17+
18+
the parameter environment for that function is `[T: Copy]`. This means any
19+
evaluation within this function will, when accessing the type `T`, know about
20+
its `Copy` bound via the parameter environment.
21+
22+
Although you can obtain a valid `ParamEnv` for any item via
23+
`tcx.param_env(def_id)`, this `ParamEnv` can be too generic for your use case.
24+
Using the `ParamEnv` from the surrounding context can allow you to evaluate more
25+
things.
26+
27+
Another great thing about `ParamEnv` is that you can use it to bundle the thing
28+
depending on generic parameters (e.g. a `Ty`) by calling `param_env.and(ty)`.
29+
This will produce a `ParamEnvAnd<Ty>`, making clear that you should probably not
30+
be using the inner value without taking care to also use the `ParamEnv`.

‎src/running-tests.md

-1
This file was deleted.

‎src/tests/adding.md

+304
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
# Adding new tests
2+
3+
**In general, we expect every PR that fixes a bug in rustc to come
4+
accompanied by a regression test of some kind.** This test should fail
5+
in master but pass after the PR. These tests are really useful for
6+
preventing us from repeating the mistakes of the past.
7+
8+
To add a new test, the first thing you generally do is to create a
9+
file, typically a Rust source file. Test files have a particular
10+
structure:
11+
12+
- They always begin with the [copyright notice](./conventions.html#copyright);
13+
- then they should have some kind of
14+
[comment explaining what the test is about](#explanatory_comment);
15+
- next, they can have one or more [header commands](#header_commands), which are special
16+
comments that the test interpreter knows how to interpret.
17+
- finally, they have the Rust source. This may have various [error
18+
annotations](#error_annotations) which indicate expected compilation errors or
19+
warnings.
20+
21+
Depending on the test suite, there may be some other details to be aware of:
22+
- For [the `ui` test suite](#ui), you need to generate reference output files.
23+
24+
## What kind of test should I add?
25+
26+
It can be difficult to know what kind of test to use. Here are some
27+
rough heuristics:
28+
29+
- Some tests have specialized needs:
30+
- need to run gdb or lldb? use the `debuginfo` test suite
31+
- need to inspect LLVM IR or MIR IR? use the `codegen` or `mir-opt` test suites
32+
- need to run rustdoc? Prefer a `rustdoc` test
33+
- need to inspect the resulting binary in some way? Then use `run-make`
34+
- For most other things, [a `ui` (or `ui-fulldeps`) test](#ui) is to be preferred:
35+
- `ui` tests subsume both run-pass, compile-fail, and parse-fail tests
36+
- in the case of warnings or errors, `ui` tests capture the full output,
37+
which makes it easier to review but also helps prevent "hidden" regressions
38+
in the output
39+
40+
## Naming your test
41+
42+
We have not traditionally had a lot of structure in the names of
43+
tests. Moreover, for a long time, the rustc test runner did not
44+
support subdirectories (it now does), so test suites like
45+
[`src/test/run-pass`] have a huge mess of files in them. This is not
46+
considered an ideal setup.
47+
48+
[`src/test/run-pass`]: https://github.com/rust-lang/rust/tree/master/src/test/run-pass/
49+
50+
For regression tests -- basically, some random snippet of code that
51+
came in from the internet -- we often just name the test after the
52+
issue. For example, `src/test/run-pass/issue-12345.rs`. If possible,
53+
though, it is better if you can put the test into a directory that
54+
helps identify what piece of code is being tested here (e.g.,
55+
`borrowck/issue-12345.rs` is much better), or perhaps give it a more
56+
meaningful name. Still, **do include the issue number somewhere**.
57+
58+
When writing a new feature, **create a subdirectory to store your
59+
tests**. For example, if you are implementing RFC 1234 ("Widgets"),
60+
then it might make sense to put the tests in directories like:
61+
62+
- `src/test/ui/rfc1234-widgets/`
63+
- `src/test/run-pass/rfc1234-widgets/`
64+
- etc
65+
66+
In other cases, there may already be a suitable directory. (The proper
67+
directory structure to use is actually an area of active debate.)
68+
69+
<a name=explanatory_comment>
70+
71+
## Comment explaining what the test is about
72+
73+
When you create a test file, **include a comment summarizing the point
74+
of the test immediately after the copyright notice**. This should
75+
highlight which parts of the test are more important, and what the bug
76+
was that the test is fixing. Citing an issue number is often very
77+
helpful.
78+
79+
This comment doesn't have to be super extensive. Just something like
80+
"Regression test for #18060: match arms were matching in the wrong
81+
order." might already be enough.
82+
83+
These comments are very useful to others later on when your test
84+
breaks, since they often can highlight what the problem is. They are
85+
also useful if for some reason the tests need to be refactored, since
86+
they let others know which parts of the test were important (often a
87+
test must be rewritten because it no longer tests what is was meant to
88+
test, and then it's useful to know what it *was* meant to test
89+
exactly).
90+
91+
<a name=header_commands>
92+
93+
## Header commands: configuring rustc
94+
95+
Header commands are special comments that the test runner knows how to
96+
interpret. They must appear before the Rust source in the test. They
97+
are normally put after the short comment that explains the point of
98+
this test. For example, this test uses the `// compile-flags` command
99+
to specify a custom flag to give to rustc when the test is compiled:
100+
101+
```rust
102+
// Copyright 2017 The Rust Project Developers. blah blah blah.
103+
// ...
104+
// except according to those terms.
105+
106+
// Test the behavior of `0 - 1` when overflow checks are disabled.
107+
108+
// compile-flags: -Coverflow-checks=off
109+
110+
fn main() {
111+
let x = 0 - 1;
112+
...
113+
}
114+
```
115+
116+
### Ignoring tests
117+
118+
These are used to ignore the test in some situations, which means the test won't
119+
be compiled or run.
120+
121+
* `ignore-X` where `X` is a target detail or stage will ignore the test accordingly (see below)
122+
* `ignore-pretty` will not compile the pretty-printed test (this is done to test the pretty-printer, but might not always work)
123+
* `ignore-test` always ignores the test
124+
* `ignore-lldb` and `ignore-gdb` will skip a debuginfo test on that debugger.
125+
126+
Some examples of `X` in `ignore-X`:
127+
128+
* Architecture: `aarch64`, `arm`, `asmjs`, `mips`, `wasm32`, `x86_64`, `x86`, ...
129+
* OS: `android`, `emscripten`, `freebsd`, `ios`, `linux`, `macos`, `windows`, ...
130+
* Environment (fourth word of the target triple): `gnu`, `msvc`, `musl`.
131+
* Pointer width: `32bit`, `64bit`.
132+
* Stage: `stage0`, `stage1`, `stage2`.
133+
134+
### Other Header Commands
135+
136+
Here is a list of other header commands. This list is not
137+
exhaustive. Header commands can generally be found by browsing the
138+
`TestProps` structure found in [`header.rs`] from the compiletest
139+
source.
140+
141+
* `min-{gdb,lldb}-version`
142+
* `min-llvm-version`
143+
* `must-compile-successfully` for UI tests, indicates that the test is supposed
144+
to compile, as opposed to the default where the test is supposed to error out.
145+
* `compile-flags` passes extra command-line args to the compiler,
146+
e.g. `compile-flags -g` which forces debuginfo to be enabled.
147+
* `should-fail` indicates that the test should fail; used for "meta testing",
148+
where we test the compiletest program itself to check that it will generate
149+
errors in appropriate scenarios. This header is ignored for pretty-printer tests.
150+
* `gate-test-X` where `X` is a feature marks the test as "gate test" for feature X.
151+
Such tests are supposed to ensure that the compiler errors when usage of a gated
152+
feature is attempted without the proper `#![feature(X)]` tag.
153+
Each unstable lang feature is required to have a gate test.
154+
155+
[`header.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/header.rs
156+
157+
<a name="error_annotations">
158+
159+
## Error annotations
160+
161+
Error annotations specify the errors that the compiler is expected to
162+
emit. They are "attached" to the line in source where the error is
163+
located.
164+
165+
* `~`: Associates the following error level and message with the
166+
current line
167+
* `~|`: Associates the following error level and message with the same
168+
line as the previous comment
169+
* `~^`: Associates the following error level and message with the
170+
previous line. Each caret (`^`) that you add adds a line to this, so
171+
`~^^^^^^^` is seven lines up.
172+
173+
The error levels that you can have are:
174+
175+
1. `ERROR`
176+
2. `WARNING`
177+
3. `NOTE`
178+
4. `HELP` and `SUGGESTION`*
179+
180+
\* **Note**: `SUGGESTION` must follow immediately after `HELP`.
181+
182+
## Revisions
183+
184+
Certain classes of tests support "revisions" (as of the time of this
185+
writing, this includes run-pass, compile-fail, run-fail, and
186+
incremental, though incremental tests are somewhat
187+
different). Revisions allow a single test file to be used for multiple
188+
tests. This is done by adding a special header at the top of the file:
189+
190+
```
191+
// revisions: foo bar baz
192+
```
193+
194+
This will result in the test being compiled (and tested) three times,
195+
once with `--cfg foo`, once with `--cfg bar`, and once with `--cfg
196+
baz`. You can therefore use `#[cfg(foo)]` etc within the test to tweak
197+
each of these results.
198+
199+
You can also customize headers and expected error messages to a particular
200+
revision. To do this, add `[foo]` (or `bar`, `baz`, etc) after the `//`
201+
comment, like so:
202+
203+
```
204+
// A flag to pass in only for cfg `foo`:
205+
//[foo]compile-flags: -Z verbose
206+
207+
#[cfg(foo)]
208+
fn test_foo() {
209+
let x: usize = 32_u32; //[foo]~ ERROR mismatched types
210+
}
211+
```
212+
213+
Note that not all headers have meaning when customized to a revision.
214+
For example, the `ignore-test` header (and all "ignore" headers)
215+
currently only apply to the test as a whole, not to particular
216+
revisions. The only headers that are intended to really work when
217+
customized to a revision are error patterns and compiler flags.
218+
219+
<a name="ui">
220+
221+
## Guide to the UI tests
222+
223+
The UI tests are intended to capture the compiler's complete output,
224+
so that we can test all aspects of the presentation. They work by
225+
compiling a file (e.g., [`ui/hello_world/main.rs`][hw-main]),
226+
capturing the output, and then applying some normalization (see
227+
below). This normalized result is then compared against reference
228+
files named `ui/hello_world/main.stderr` and
229+
`ui/hello_world/main.stdout`. If either of those files doesn't exist,
230+
the output must be empty (that is actually the case for
231+
[this particular test][hw]). If the test run fails, we will print out
232+
the current output, but it is also saved in
233+
`build/<target-triple>/test/ui/hello_world/main.stdout` (this path is
234+
printed as part of the test failure message), so you can run `diff`
235+
and so forth.
236+
237+
[hw-main]: https://github.com/rust-lang/rust/blob/master/src/test/ui/hello_world/main.rs
238+
[hw]: https://github.com/rust-lang/rust/blob/master/src/test/ui/hello_world/
239+
240+
### Tests that do not result in compile errors
241+
242+
By default, a UI test is expected **not to compile** (in which case,
243+
it should contain at least one `//~ ERROR` annotation). However, you
244+
can also make UI tests where compilation is expected to succeed, and
245+
you can even run the resulting program. Just add one of the following
246+
[header commands](#header_commands):
247+
248+
- `// must-compile-successfully` -- compilation should succeed but do not run the resulting binary
249+
- `// run-pass` -- compilation should succeed and we should run the resulting binary
250+
251+
### Editing and updating the reference files
252+
253+
If you have changed the compiler's output intentionally, or you are
254+
making a new test, you can use the script `ui/update-references.sh` to
255+
update the references. When you run the test framework, it will report
256+
various errors: in those errors is a command you can use to run the
257+
`ui/update-references.sh` script, which will then copy over the files
258+
from the build directory and use them as the new reference. You can
259+
also just run `ui/update-all-references.sh`. In both cases, you can run
260+
the script with `--help` to get a help message.
261+
262+
### Normalization
263+
264+
The normalization applied is aimed at eliminating output difference
265+
between platforms, mainly about filenames:
266+
267+
- the test directory is replaced with `$DIR`
268+
- all backslashes (`\`) are converted to forward slashes (`/`) (for Windows)
269+
- all CR LF newlines are converted to LF
270+
271+
Sometimes these built-in normalizations are not enough. In such cases, you
272+
may provide custom normalization rules using the header commands, e.g.
273+
274+
```
275+
// normalize-stdout-test: "foo" -> "bar"
276+
// normalize-stderr-32bit: "fn\(\) \(32 bits\)" -> "fn\(\) \($$PTR bits\)"
277+
// normalize-stderr-64bit: "fn\(\) \(64 bits\)" -> "fn\(\) \($$PTR bits\)"
278+
```
279+
280+
This tells the test, on 32-bit platforms, whenever the compiler writes
281+
`fn() (32 bits)` to stderr, it should be normalized to read `fn() ($PTR bits)`
282+
instead. Similar for 64-bit. The replacement is performed by regexes using
283+
default regex flavor provided by `regex` crate.
284+
285+
The corresponding reference file will use the normalized output to test both
286+
32-bit and 64-bit platforms:
287+
288+
```
289+
...
290+
|
291+
= note: source type: fn() ($PTR bits)
292+
= note: target type: u16 (16 bits)
293+
...
294+
```
295+
296+
Please see [`ui/transmute/main.rs`][mrs] and [`main.stderr`][] for a concrete usage example.
297+
298+
[mrs]: https://github.com/rust-lang/rust/blob/master/src/test/ui/transmute/main.rs
299+
[`main.stderr`]: https://github.com/rust-lang/rust/blob/master/src/test/ui/transmute/main.stderr
300+
301+
Besides `normalize-stderr-32bit` and `-64bit`, one may use any target
302+
information or stage supported by `ignore-X` here as well (e.g.
303+
`normalize-stderr-windows` or simply `normalize-stderr-test` for unconditional
304+
replacement).

‎src/tests/intro.md

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Using the compiler testing framework
2+
3+
The compiler has an extensive testing framework, masterminded by the
4+
compiletest tool (sources in the [`src/tools/compiletest`]). This
5+
section gives a brief overview of how the testing framework is setup,
6+
and then gets into some of the details on
7+
[how to run tests](./tests/running.html#ui) as well as
8+
[how to add new tests](./tests/adding.html).
9+
10+
[`src/tools/compiletest`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest
11+
12+
## Test suites
13+
14+
The tests are located in the tree in the [`src/test`]
15+
directory. Immediately within you will see a series of subdirectories
16+
(e.g. `ui`, `run-make`, and so forth). Each of those directories is
17+
called a **test suite** -- they house a group of tests that are run in
18+
a distinct mode.
19+
20+
[`src/test`]: https://github.com/rust-lang/rust/tree/master/src/test
21+
22+
Here is a brief summary of the test suites as of this writing and what
23+
they mean. In some cases, the test suites are linked to parts of the manual
24+
that give more details.
25+
26+
- [`ui`](./tests/adding.html#ui) -- tests that check the exact stdout/stderr from compilation
27+
and/or running the test
28+
- `run-pass` -- tests that are expected to compile and execute successfully (no panics)
29+
- `run-pass-valgrind` -- tests that ought to run with valrind
30+
- `run-fail` -- tests that are expected to compile but then panic during execution
31+
- `compile-fail` -- tests that are expected to fail compilation.
32+
- `parse-fail` -- tests that are expected to fail to parse
33+
- `pretty` -- tests targeting the Rust "pretty printer", which
34+
generates valid Rust code from the AST
35+
- `debuginfo` -- tests that run in gdb or lldb and query the debug info
36+
- `codegen` -- tests that compile and then test the generated LLVM
37+
code to make sure that the optimizations we want are taking effect.
38+
- `mir-opt` -- tests that check parts of the generated MIR to make
39+
sure we are building things correctly or doing the optimizations we
40+
expect.
41+
- `incremental` -- tests for incremental compilation, checking that
42+
when certain modifications are performed, we are able to reuse the
43+
results from previous compilations.
44+
- `run-make` -- tests that basically just execute a `Makefile`; the
45+
ultimate in flexibility but quite annoying to write.
46+
- `rustdoc` -- tests for rustdoc, making sure that the generated files contain
47+
the expected documentation.
48+
- `*-fulldeps` -- same as above, but indicates that the test depends on things other
49+
than `libstd` (and hence those things must be built)
50+
51+
## Further reading
52+
53+
The following blog posts may also be of interest:
54+
55+
- brson's classic ["How Rust is tested"][howtest]
56+
57+
[howtest]: https://brson.github.io/2017/07/10/how-rust-is-tested

‎src/tests/running.md

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Running tests
2+
3+
You can run the tests using `x.py`. The most basic command -- which
4+
you will almost never want to use! -- is as follows:
5+
6+
```
7+
./x.py test
8+
```
9+
10+
This will build the full stage 2 compiler and then run the whole test
11+
suite. You probably don't want to do this very often, because it takes
12+
a very long time, and anyway bors / travis will do it for you. (Often,
13+
I will run this command in the background after opening a PR that I
14+
think is done, but rarely otherwise. -nmatsakis)
15+
16+
## Tidy
17+
18+
When you run the full suite of tests via `./x.py test`, the first
19+
thing that executes is a "tidy suite" that checks for long lines and
20+
other formatting conventions. There is more information in the
21+
[section on coding conventions](./conventions.html#formatting).
22+
23+
## Running a subset of the test suites
24+
25+
When working on a specific PR, you will usually want to run a smaller
26+
set of tests, and with a stage 1 build. For example, a good "smoke
27+
test" that can be used after modifying rustc to see if things are
28+
generally working correctly would be the following:
29+
30+
```bash
31+
./x.py test --stage 1 src/test/{ui,compile-fail,run-pass}
32+
```
33+
34+
This will run the `ui`, `compile-fail`, and `run-pass` test suites, and
35+
only with the stage 1 build. Of course, the choice of test suites is somewhat
36+
arbitrary, and may not suit the task you are doing. For example, if you are hacking
37+
on debuginfo, you may be better off with the debuginfo test suite:
38+
39+
```bash
40+
./x.py test --stage 1 src/test/debuginfo
41+
```
42+
43+
**Warning:** Note that bors only runs the tests with the full stage 2
44+
build; therefore, while the tests **usually** work fine with stage 1,
45+
there are some limitations. In particular, the stage1 compiler doesn't
46+
work well with procedural macros or custom derive tests.
47+
48+
## Running an individual test
49+
50+
Another common thing that people want to do is to run an **individual
51+
test**, often the test they are trying to fix. One way to do this is
52+
to invoke `x.py` with the `--test-args` option:
53+
54+
```
55+
./x.py test --stage 1 src/test/ui --test-args issue-1234
56+
```
57+
58+
Under the hood, the test runner invokes the standard rust test runner
59+
(the same one you get with `#[test]`), so this command would wind up
60+
filtering for tests that include "issue-1234" in the name.
61+
62+
Often, though, it's easier to just run the test by hand. Most tests are
63+
just `rs` files, so you can do something like
64+
65+
```
66+
rustc +stage1 src/test/ui/issue-1234.rs
67+
```
68+
69+
This is much faster, but doesn't always work. For example, some tests
70+
include directives that specify specific compiler flags, or which rely
71+
on other crates, and they may not run the same without those options.
72+

‎src/trait-resolution.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -300,4 +300,4 @@ After one shallow round of selection for an obligation like `Vec<isize>
300300
nested obligation `isize : Bar<U>` to find out that `U=usize`.
301301

302302
It would be good to only do *just as much* nested resolution as
303-
necessary. Currently, though, we just do a full resolution.
303+
necessary. Currently, though, we just do a full resolution.

0 commit comments

Comments
 (0)
Please sign in to comment.