863 lines
51 KiB
HTML
863 lines
51 KiB
HTML
<!DOCTYPE HTML>
|
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
|
<head>
|
|
<!-- Book generated using mdBook -->
|
|
<meta charset="UTF-8">
|
|
<title>Compiletest - Rust Compiler Development Guide</title>
|
|
|
|
|
|
<!-- Custom HTML head -->
|
|
|
|
<meta name="description" content="A guide to developing the Rust compiler (rustc)">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="theme-color" content="#ffffff">
|
|
|
|
<link rel="icon" href="../favicon.svg">
|
|
<link rel="shortcut icon" href="../favicon.png">
|
|
<link rel="stylesheet" href="../css/variables.css">
|
|
<link rel="stylesheet" href="../css/general.css">
|
|
<link rel="stylesheet" href="../css/chrome.css">
|
|
<link rel="stylesheet" href="../css/print.css" media="print">
|
|
|
|
<!-- Fonts -->
|
|
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
|
<link rel="stylesheet" href="../fonts/fonts.css">
|
|
|
|
<!-- Highlight.js Stylesheets -->
|
|
<link rel="stylesheet" id="highlight-css" href="../highlight.css">
|
|
<link rel="stylesheet" id="tomorrow-night-css" href="../tomorrow-night.css">
|
|
<link rel="stylesheet" id="ayu-highlight-css" href="../ayu-highlight.css">
|
|
|
|
<!-- Custom theme stylesheets -->
|
|
|
|
|
|
<!-- Provide site root and default themes to javascript -->
|
|
<script>
|
|
const path_to_root = "../";
|
|
const default_light_theme = "light";
|
|
const default_dark_theme = "navy";
|
|
</script>
|
|
<!-- Start loading toc.js asap -->
|
|
<script src="../toc.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="body-container">
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
|
<script>
|
|
try {
|
|
let theme = localStorage.getItem('mdbook-theme');
|
|
let sidebar = localStorage.getItem('mdbook-sidebar');
|
|
|
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
|
}
|
|
|
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
|
}
|
|
} catch (e) { }
|
|
</script>
|
|
|
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
|
<script>
|
|
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
|
|
let theme;
|
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
|
const html = document.documentElement;
|
|
html.classList.remove('light')
|
|
html.classList.add(theme);
|
|
html.classList.add("js");
|
|
</script>
|
|
|
|
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
|
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
|
<script>
|
|
let sidebar = null;
|
|
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
|
if (document.body.clientWidth >= 1080) {
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
|
sidebar = sidebar || 'visible';
|
|
} else {
|
|
sidebar = 'hidden';
|
|
}
|
|
sidebar_toggle.checked = sidebar === 'visible';
|
|
html.classList.remove('sidebar-visible');
|
|
html.classList.add("sidebar-" + sidebar);
|
|
</script>
|
|
|
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
|
<!-- populated by js -->
|
|
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
|
<noscript>
|
|
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
|
|
</noscript>
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
|
<div class="sidebar-resize-indicator"></div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div id="page-wrapper" class="page-wrapper">
|
|
|
|
<div class="page">
|
|
<div id="menu-bar-hover-placeholder"></div>
|
|
<div id="menu-bar" class="menu-bar sticky">
|
|
<div class="left-buttons">
|
|
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
|
<i class="fa fa-bars"></i>
|
|
</label>
|
|
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
|
<i class="fa fa-paint-brush"></i>
|
|
</button>
|
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
|
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
|
</ul>
|
|
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<h1 class="menu-title">Rust Compiler Development Guide</h1>
|
|
|
|
<div class="right-buttons">
|
|
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
|
<i id="print-button" class="fa fa-print"></i>
|
|
</a>
|
|
<a href="https://github.com/rust-lang/rustc-dev-guide" title="Git repository" aria-label="Git repository">
|
|
<i id="git-repository-button" class="fa fa-github"></i>
|
|
</a>
|
|
<a href="https://github.com/rust-lang/rustc-dev-guide/edit/master/src/tests/compiletest.md" title="Suggest an edit" aria-label="Suggest an edit">
|
|
<i id="git-edit-button" class="fa fa-edit"></i>
|
|
</a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div id="search-wrapper" class="hidden">
|
|
<form id="searchbar-outer" class="searchbar-outer">
|
|
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
|
</form>
|
|
<div id="searchresults-outer" class="searchresults-outer hidden">
|
|
<div id="searchresults-header" class="searchresults-header"></div>
|
|
<ul id="searchresults">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
|
<script>
|
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
|
});
|
|
</script>
|
|
|
|
<div id="content" class="content">
|
|
<main>
|
|
<h1 id="compiletest"><a class="header" href="#compiletest">Compiletest</a></h1>
|
|
<ul>
|
|
<li><a href="#introduction">Introduction</a></li>
|
|
<li><a href="#test-suites">Test suites</a>
|
|
<ul>
|
|
<li><a href="#compiler-specific-test-suites">Compiler-specific test suites</a></li>
|
|
<li><a href="#general-purpose-test-suite">General purpose test suite</a></li>
|
|
<li><a href="#rustdoc-test-suites">Rustdoc test suites</a></li>
|
|
<li><a href="#pretty-printer-tests">Pretty-printer tests</a></li>
|
|
<li><a href="#incremental-tests">Incremental tests</a></li>
|
|
<li><a href="#debuginfo-tests">Debuginfo tests</a></li>
|
|
<li><a href="#codegen-tests">Codegen tests</a></li>
|
|
<li><a href="#assembly-tests">Assembly tests</a></li>
|
|
<li><a href="#codegen-units-tests">Codegen-units tests</a></li>
|
|
<li><a href="#mir-opt-tests">Mir-opt tests</a></li>
|
|
<li><a href="#run-make-tests"><code>run-make</code> tests</a>
|
|
<ul>
|
|
<li><a href="#using-rust-recipes">Using Rust recipes</a></li>
|
|
<li><a href="#quickly-check-if-rmakers-tests-can-be-compiled">Quickly check if <code>rmake.rs</code> tests can be compiled</a></li>
|
|
<li><a href="#using-rust-analyzer-with-rmakers">Using rust-analyzer with <code>rmake.rs</code></a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#coverage-tests">Coverage tests</a>
|
|
<ul>
|
|
<li><a href="#coverage-map-suite"><code>coverage-map</code> suite</a></li>
|
|
<li><a href="#coverage-run-suite"><code>coverage-run</code> suite</a></li>
|
|
<li><a href="#coverage-run-rustdoc-suite"><code>coverage-run-rustdoc</code> suite</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#crashes-tests">Crashes tests</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#building-auxiliary-crates">Building auxiliary crates</a>
|
|
<ul>
|
|
<li><a href="#auxiliary-proc-macro">Auxiliary proc-macro</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#revisions">Revisions</a>
|
|
<ul>
|
|
<li><a href="#ignoring-unused-revision-names">Ignoring unused revision names</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#compare-modes">Compare modes</a></li>
|
|
</ul>
|
|
<h2 id="introduction"><a class="header" href="#introduction">Introduction</a></h2>
|
|
<p><code>compiletest</code> is the main test harness of the Rust test suite. It allows test
|
|
authors to organize large numbers of tests (the Rust compiler has many
|
|
thousands), 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.</p>
|
|
<blockquote>
|
|
<p><strong>Note for macOS users</strong></p>
|
|
<p>For macOS users, <code>SIP</code> (System Integrity Protection) <a href="https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/.E2.9C.94.20Is.20there.20any.20performance.20issue.20for.20MacOS.3F">may consistently check
|
|
the compiled binary by sending network requests to Apple</a>, so you may
|
|
get a huge performance degradation when running tests.</p>
|
|
<p>You can resolve it by tweaking the following settings: <code>Privacy & Security -> Developer Tools -> Add Terminal (Or VsCode, etc.)</code>.</p>
|
|
</blockquote>
|
|
<p><code>compiletest</code> may check test code for compile-time or run-time success/failure.</p>
|
|
<p>Tests are typically organized as a Rust source file with annotations in comments
|
|
before and/or within the test code. These comments serve to direct <code>compiletest</code>
|
|
on if or how to run the test, what behavior to expect, and more. See
|
|
<a href="directives.html">directives</a> and the test suite documentation below for more details
|
|
on these annotations.</p>
|
|
<p>See the <a href="adding.html">Adding new tests</a> and <a href="best-practices.html">Best practies</a>
|
|
chapters for a tutorial on creating a new test and advice on writing a good
|
|
test, and the <a href="running.html">Running tests</a> chapter on how to run the test suite.</p>
|
|
<p>Arguments can be passed to compiletest using <code>--test-args</code> or by placing them after <code>--</code>, e.g.</p>
|
|
<ul>
|
|
<li><code>x test --test-args --force-rerun</code></li>
|
|
<li><code>x test -- --force-rerun</code></li>
|
|
</ul>
|
|
<p>Additionally, bootstrap accepts several common arguments directly, e.g.</p>
|
|
<p><code>x test --no-capture --force-rerun --run --pass</code>.</p>
|
|
<p>Compiletest itself tries to avoid running tests when the artifacts that are
|
|
involved (mainly the compiler) haven't changed. You can use <code>x test --test-args --force-rerun</code> to rerun a test even when none of the inputs have changed.</p>
|
|
<h2 id="test-suites"><a class="header" href="#test-suites">Test suites</a></h2>
|
|
<p>All of the tests are in the <a href="https://github.com/rust-lang/rust/blob/master/tests"><code>tests</code></a> directory. The tests are organized into
|
|
"suites", with each suite in a separate subdirectory. Each test suite behaves a
|
|
little differently, with different compiler behavior and different checks for
|
|
correctness. For example, the <a href="https://github.com/rust-lang/rust/tree/master/tests/incremental"><code>tests/incremental</code></a> directory contains tests for
|
|
incremental compilation. The various suites are defined in
|
|
<a href="https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/common.rs"><code>src/tools/compiletest/src/common.rs</code></a> in the <code>pub enum Mode</code> declaration.</p>
|
|
<p>The following test suites are available, with links for more information:</p>
|
|
<h3 id="compiler-specific-test-suites"><a class="header" href="#compiler-specific-test-suites">Compiler-specific test suites</a></h3>
|
|
<div class="table-wrapper"><table><thead><tr><th>Test suite</th><th>Purpose</th></tr></thead><tbody>
|
|
<tr><td><a href="ui.html"><code>ui</code></a></td><td>Check the stdout/stderr snapshots from the compilation and/or running the resulting executable</td></tr>
|
|
<tr><td><code>ui-fulldeps</code></td><td><code>ui</code> tests which require a linkable build of <code>rustc</code> (such as using <code>extern crate rustc_span;</code> or used as a plugin)</td></tr>
|
|
<tr><td><a href="#pretty-printer-tests"><code>pretty</code></a></td><td>Check pretty printing</td></tr>
|
|
<tr><td><a href="#incremental-tests"><code>incremental</code></a></td><td>Check incremental compilation behavior</td></tr>
|
|
<tr><td><a href="#debuginfo-tests"><code>debuginfo</code></a></td><td>Check debuginfo generation running debuggers</td></tr>
|
|
<tr><td><a href="#codegen-tests"><code>codegen</code></a></td><td>Check code generation</td></tr>
|
|
<tr><td><a href="#codegen-units-tests"><code>codegen-units</code></a></td><td>Check codegen unit partitioning</td></tr>
|
|
<tr><td><a href="#assembly-tests"><code>assembly</code></a></td><td>Check assembly output</td></tr>
|
|
<tr><td><a href="#mir-opt-tests"><code>mir-opt</code></a></td><td>Check MIR generation and optimizations</td></tr>
|
|
<tr><td><a href="#coverage-tests"><code>coverage</code></a></td><td>Check coverage instrumentation</td></tr>
|
|
<tr><td><a href="#coverage-tests"><code>coverage-run-rustdoc</code></a></td><td><code>coverage</code> tests that also run instrumented doctests</td></tr>
|
|
<tr><td><a href="#crashes-tests"><code>crashes</code></a></td><td>Check that the compiler ICEs/panics/crashes on certain inputs to catch accidental fixes</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="general-purpose-test-suite"><a class="header" href="#general-purpose-test-suite">General purpose test suite</a></h3>
|
|
<p><a href="#run-make-tests"><code>run-make</code></a> are general purpose tests using Rust programs.</p>
|
|
<h3 id="rustdoc-test-suites"><a class="header" href="#rustdoc-test-suites">Rustdoc test suites</a></h3>
|
|
<div class="table-wrapper"><table><thead><tr><th>Test suite</th><th>Purpose</th></tr></thead><tbody>
|
|
<tr><td><a href="../rustdoc-internals/rustdoc-test-suite.html"><code>rustdoc</code></a></td><td>Check HTML output of <code>rustdoc</code></td></tr>
|
|
<tr><td><a href="../rustdoc-internals/rustdoc-gui-test-suite.html"><code>rustdoc-gui</code></a></td><td>Check <code>rustdoc</code>'s GUI using a web browser</td></tr>
|
|
<tr><td><a href="../rustdoc-internals/search.html#testing-the-search-engine"><code>rustdoc-js</code></a></td><td>Check <code>rustdoc</code>'s search engine and index</td></tr>
|
|
<tr><td><a href="../rustdoc-internals/search.html#testing-the-search-engine"><code>rustdoc-js-std</code></a></td><td>Check <code>rustdoc</code>'s search engine and index on the std library docs</td></tr>
|
|
<tr><td><a href="../rustdoc-internals/rustdoc-json-test-suite.html"><code>rustdoc-json</code></a></td><td>Check JSON output of <code>rustdoc</code></td></tr>
|
|
<tr><td><code>rustdoc-ui</code></td><td>Check terminal output of <code>rustdoc</code> (<a href="ui.html">see also</a>)</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<p>Some rustdoc-specific tests can also be found in <code>ui/rustdoc/</code>.
|
|
These check rustdoc-related or -specific lints that (also) run as part of <code>rustc</code>, not (only) <code>rustdoc</code>.
|
|
Run-make tests pertaining to rustdoc are typically named <code>run-make/rustdoc-*/</code>.</p>
|
|
<h3 id="pretty-printer-tests"><a class="header" href="#pretty-printer-tests">Pretty-printer tests</a></h3>
|
|
<p>The tests in <a href="https://github.com/rust-lang/rust/tree/master/tests/pretty"><code>tests/pretty</code></a> exercise the "pretty-printing" functionality of
|
|
<code>rustc</code>. The <code>-Z unpretty</code> CLI option for <code>rustc</code> causes it to translate the
|
|
input source into various different formats, such as the Rust source after macro
|
|
expansion.</p>
|
|
<p>The pretty-printer tests have several <a href="directives.html">directives</a> described below.
|
|
These commands can significantly change the behavior of the test, but the
|
|
default behavior without any commands is to:</p>
|
|
<ol>
|
|
<li>Run <code>rustc -Zunpretty=normal</code> on the source file.</li>
|
|
<li>Run <code>rustc -Zunpretty=normal</code> on the output of the previous step.</li>
|
|
<li>The output of the previous two steps should be the same.</li>
|
|
<li>Run <code>rustc -Zno-codegen</code> on the output to make sure that it can type check
|
|
(similar to <code>cargo check</code>).</li>
|
|
</ol>
|
|
<p>If any of the commands above fail, then the test fails.</p>
|
|
<p>The directives for pretty-printing tests are:</p>
|
|
<ul>
|
|
<li><code>pretty-mode</code> specifies the mode pretty-print tests should run in (that is,
|
|
the argument to <code>-Zunpretty</code>). The default is <code>normal</code> if not specified.</li>
|
|
<li><code>pretty-compare-only</code> causes a pretty test to only compare the pretty-printed
|
|
output (stopping after step 3 from above). It will not try to compile the
|
|
expanded output to type check it. This is needed for a pretty-mode that does
|
|
not expand to valid Rust, or for other situations where the expanded output
|
|
cannot be compiled.</li>
|
|
<li><code>pp-exact</code> is used to ensure a pretty-print test results in specific output.
|
|
If specified without a value, then it means the pretty-print output should
|
|
match the original source. If specified with a value, as in <code>//@ pp-exact:foo.pp</code>, it will ensure that the pretty-printed output matches the
|
|
contents of the given file. Otherwise, if <code>pp-exact</code> is not specified, then
|
|
the pretty-printed output will be pretty-printed one more time, and the output
|
|
of the two pretty-printing rounds will be compared to ensure that the
|
|
pretty-printed output converges to a steady state.</li>
|
|
</ul>
|
|
<h3 id="incremental-tests"><a class="header" href="#incremental-tests">Incremental tests</a></h3>
|
|
<p>The tests in <a href="https://github.com/rust-lang/rust/tree/master/tests/incremental"><code>tests/incremental</code></a> exercise incremental compilation. They use
|
|
<a href="#revisions"><code>revisions</code> directive</a> to tell compiletest to run the compiler in a
|
|
series of steps.</p>
|
|
<p>Compiletest starts with an empty directory with the <code>-C incremental</code> flag, and
|
|
then runs the compiler for each revision, reusing the incremental results from
|
|
previous steps.</p>
|
|
<p>The revisions should start with:</p>
|
|
<ul>
|
|
<li><code>rpass</code> — the test should compile and run successfully</li>
|
|
<li><code>rfail</code> — the test should compile successfully, but the executable should fail to run</li>
|
|
<li><code>cfail</code> — the test should fail to compile</li>
|
|
</ul>
|
|
<p>To make the revisions unique, you should add a suffix like <code>rpass1</code> and
|
|
<code>rpass2</code>.</p>
|
|
<p>To simulate changing the source, compiletest also passes a <code>--cfg</code> flag with the
|
|
current revision name.</p>
|
|
<p>For example, this will run twice, simulating changing a function:</p>
|
|
<pre><code class="language-rust ignore">//@ revisions: rpass1 rpass2
|
|
|
|
#[cfg(rpass1)]
|
|
fn foo() {
|
|
println!("one");
|
|
}
|
|
|
|
#[cfg(rpass2)]
|
|
fn foo() {
|
|
println!("two");
|
|
}
|
|
|
|
fn main() { foo(); }</code></pre>
|
|
<p><code>cfail</code> tests support the <code>forbid-output</code> directive to specify that a certain
|
|
substring must not appear anywhere in the compiler output. This can be useful to
|
|
ensure certain errors do not appear, but this can be fragile as error messages
|
|
change over time, and a test may no longer be checking the right thing but will
|
|
still pass.</p>
|
|
<p><code>cfail</code> tests support the <code>should-ice</code> directive to specify that a test should
|
|
cause an Internal Compiler Error (ICE). This is a highly specialized directive
|
|
to check that the incremental cache continues to work after an ICE.</p>
|
|
<h3 id="debuginfo-tests"><a class="header" href="#debuginfo-tests">Debuginfo tests</a></h3>
|
|
<p>The tests in <a href="https://github.com/rust-lang/rust/tree/master/tests/debuginfo"><code>tests/debuginfo</code></a> test debuginfo generation. They build a
|
|
program, launch a debugger, and issue commands to the debugger. A single test
|
|
can work with cdb, gdb, and lldb.</p>
|
|
<p>Most tests should have the <code>//@ compile-flags: -g</code> directive or something
|
|
similar to generate the appropriate debuginfo.</p>
|
|
<p>To set a breakpoint on a line, add a <code>// #break</code> comment on the line.</p>
|
|
<p>The debuginfo tests consist of a series of debugger commands along with
|
|
"check" lines which specify output that is expected from the debugger.</p>
|
|
<p>The commands are comments of the form <code>// $DEBUGGER-command:$COMMAND</code> where
|
|
<code>$DEBUGGER</code> is the debugger being used and <code>$COMMAND</code> is the debugger command
|
|
to execute.</p>
|
|
<p>The debugger values can be:</p>
|
|
<ul>
|
|
<li><code>cdb</code></li>
|
|
<li><code>gdb</code></li>
|
|
<li><code>gdbg</code> — GDB without Rust support (versions older than 7.11)</li>
|
|
<li><code>gdbr</code> — GDB with Rust support</li>
|
|
<li><code>lldb</code></li>
|
|
<li><code>lldbg</code> — LLDB without Rust support</li>
|
|
<li><code>lldbr</code> — LLDB with Rust support (this no longer exists)</li>
|
|
</ul>
|
|
<p>The command to check the output are of the form <code>// $DEBUGGER-check:$OUTPUT</code>
|
|
where <code>$OUTPUT</code> is the output to expect.</p>
|
|
<p>For example, the following will build the test, start the debugger, set a
|
|
breakpoint, launch the program, inspect a value, and check what the debugger
|
|
prints:</p>
|
|
<pre><code class="language-rust ignore">//@ compile-flags: -g
|
|
|
|
//@ lldb-command: run
|
|
//@ lldb-command: print foo
|
|
//@ lldb-check: $0 = 123
|
|
|
|
fn main() {
|
|
let foo = 123;
|
|
b(); // #break
|
|
}
|
|
|
|
fn b() {}</code></pre>
|
|
<p>The following <a href="directives.html">directives</a> are available to disable a test based on
|
|
the debugger currently being used:</p>
|
|
<ul>
|
|
<li><code>min-cdb-version: 10.0.18317.1001</code> — ignores the test if the version of cdb
|
|
is below the given version</li>
|
|
<li><code>min-gdb-version: 8.2</code> — ignores the test if the version of gdb is below the
|
|
given version</li>
|
|
<li><code>ignore-gdb-version: 9.2</code> — ignores the test if the version of gdb is equal
|
|
to the given version</li>
|
|
<li><code>ignore-gdb-version: 7.11.90 - 8.0.9</code> — ignores the test if the version of
|
|
gdb is in a range (inclusive)</li>
|
|
<li><code>min-lldb-version: 310</code> — ignores the test if the version of lldb is below
|
|
the given version</li>
|
|
<li><code>rust-lldb</code> — ignores the test if lldb is not contain the Rust plugin. NOTE:
|
|
The "Rust" version of LLDB doesn't exist anymore, so this will always be
|
|
ignored. This should probably be removed.</li>
|
|
</ul>
|
|
<p>By passing the <code>--debugger</code> option to compiletest, you can specify a single debugger to run tests with.
|
|
For example, <code>./x test tests/debuginfo -- --debugger gdb</code> will only test GDB commands.</p>
|
|
<blockquote>
|
|
<p><strong>Note on running lldb debuginfo tests locally</strong></p>
|
|
<p>If you want to run lldb debuginfo tests locally, then currently on Windows it
|
|
is required that:</p>
|
|
<ul>
|
|
<li>You have Python 3.10 installed.</li>
|
|
<li>You have <code>python310.dll</code> available in your <code>PATH</code> env var. This is not
|
|
provided by the standard Python installer you obtain from <code>python.org</code>; you
|
|
need to add this to <code>PATH</code> manually.</li>
|
|
</ul>
|
|
<p>Otherwise the lldb debuginfo tests can produce crashes in mysterious ways.</p>
|
|
</blockquote>
|
|
<blockquote>
|
|
<p><strong>Note on acquiring <code>cdb.exe</code> on Windows 11</strong></p>
|
|
<p><code>cdb.exe</code> is acquired alongside a suitable "Windows 11 SDK" which is part of
|
|
the "Desktop Development with C++" workload profile in a Visual Studio
|
|
installer (e.g. Visual Studio 2022 installer).</p>
|
|
<p><strong>HOWEVER</strong> this is not sufficient by default alone. If you need <code>cdb.exe</code>,
|
|
you must go to Installed Apps, find the newest "Windows Software Development
|
|
Kit" (and yes, this can still say <code>Windows 10.0.22161.3233</code> even though the OS
|
|
is called Windows 11). You must then click "Modify" -> "Change" and then
|
|
selected "Debugging Tools for Windows" in order to acquire <code>cdb.exe</code>.</p>
|
|
</blockquote>
|
|
<h3 id="codegen-tests"><a class="header" href="#codegen-tests">Codegen tests</a></h3>
|
|
<p>The tests in <a href="https://github.com/rust-lang/rust/tree/master/tests/codegen"><code>tests/codegen</code></a> test LLVM code generation. They compile the test
|
|
with the <code>--emit=llvm-ir</code> flag to emit LLVM IR. They then run the LLVM
|
|
<a href="https://llvm.org/docs/CommandGuide/FileCheck.html">FileCheck</a> tool. The test is annotated with various <code>// CHECK</code> comments to
|
|
check the generated code. See the <a href="https://llvm.org/docs/CommandGuide/FileCheck.html">FileCheck</a> documentation for a tutorial and
|
|
more information.</p>
|
|
<p>See also the <a href="#assembly-tests">assembly tests</a> for a similar set of tests.</p>
|
|
<p>If you need to work with <code>#![no_std]</code> cross-compiling tests, consult the
|
|
<a href="./minicore.html"><code>minicore</code> test auxiliary</a> chapter.</p>
|
|
<h3 id="assembly-tests"><a class="header" href="#assembly-tests">Assembly tests</a></h3>
|
|
<p>The tests in <a href="https://github.com/rust-lang/rust/tree/master/tests/assembly"><code>tests/assembly</code></a> test LLVM assembly output. They compile the test
|
|
with the <code>--emit=asm</code> flag to emit a <code>.s</code> file with the assembly output. They
|
|
then run the LLVM <a href="https://llvm.org/docs/CommandGuide/FileCheck.html">FileCheck</a> tool.</p>
|
|
<p>Each test should be annotated with the <code>//@ assembly-output:</code> directive with a
|
|
value of either <code>emit-asm</code> or <code>ptx-linker</code> to indicate the type of assembly
|
|
output.</p>
|
|
<p>Then, they should be annotated with various <code>// CHECK</code> comments to check the
|
|
assembly output. See the <a href="https://llvm.org/docs/CommandGuide/FileCheck.html">FileCheck</a> documentation for a tutorial and more
|
|
information.</p>
|
|
<p>See also the <a href="#codegen-tests">codegen tests</a> for a similar set of tests.</p>
|
|
<p>If you need to work with <code>#![no_std]</code> cross-compiling tests, consult the
|
|
<a href="./minicore.html"><code>minicore</code> test auxiliary</a> chapter.</p>
|
|
<h3 id="codegen-units-tests"><a class="header" href="#codegen-units-tests">Codegen-units tests</a></h3>
|
|
<p>The tests in <a href="https://github.com/rust-lang/rust/tree/master/tests/codegen-units"><code>tests/codegen-units</code></a> test the
|
|
<a href="../backend/monomorph.html">monomorphization</a> collector and CGU partitioning.</p>
|
|
<p>These tests work by running <code>rustc</code> with a flag to print the result of the
|
|
monomorphization collection pass, i.e., <code>-Zprint-mono-items</code>, and then special
|
|
annotations in the file are used to compare against that.</p>
|
|
<p>Then, the test should be annotated with comments of the form <code>//~ MONO_ITEM name</code> where <code>name</code> is the monomorphized string printed by rustc like <code>fn <u32 as Trait>::foo</code>.</p>
|
|
<p>To check for CGU partitioning, a comment of the form <code>//~ MONO_ITEM name @@ cgu</code>
|
|
where <code>cgu</code> is a space separated list of the CGU names and the linkage
|
|
information in brackets. For example: <code>//~ MONO_ITEM static function::FOO @@ statics[Internal]</code></p>
|
|
<h3 id="mir-opt-tests"><a class="header" href="#mir-opt-tests">Mir-opt tests</a></h3>
|
|
<p>The tests in <a href="https://github.com/rust-lang/rust/tree/master/tests/mir-opt"><code>tests/mir-opt</code></a> check parts of the generated MIR to make sure it
|
|
is generated correctly and is doing the expected optimizations. Check out the
|
|
<a href="../mir/optimizations.html">MIR Optimizations</a> chapter for more.</p>
|
|
<p>Compiletest will build the test with several flags to dump the MIR output and
|
|
set a baseline for optimizations:</p>
|
|
<ul>
|
|
<li><code>-Copt-level=1</code></li>
|
|
<li><code>-Zdump-mir=all</code></li>
|
|
<li><code>-Zmir-opt-level=4</code></li>
|
|
<li><code>-Zvalidate-mir</code></li>
|
|
<li><code>-Zdump-mir-exclude-pass-number</code></li>
|
|
</ul>
|
|
<p>The test should be annotated with <code>// EMIT_MIR</code> comments that specify files that
|
|
will contain the expected MIR output. You can use <code>x test --bless</code> to create the
|
|
initial expected files.</p>
|
|
<p>There are several forms the <code>EMIT_MIR</code> comment can take:</p>
|
|
<ul>
|
|
<li>
|
|
<p><code>// EMIT_MIR $MIR_PATH.mir</code> — This will check that the given filename matches
|
|
the exact output from the MIR dump. For example,
|
|
<code>my_test.main.SimplifyCfg-elaborate-drops.after.mir</code> will load that file from
|
|
the test directory, and compare it against the dump from rustc.</p>
|
|
<p>Checking the "after" file (which is after optimization) is useful if you are
|
|
interested in the final state after an optimization. Some rare cases may want
|
|
to use the "before" file for completeness.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>// EMIT_MIR $MIR_PATH.diff</code> — where <code>$MIR_PATH</code> is the filename of the MIR
|
|
dump, such as <code>my_test_name.my_function.EarlyOtherwiseBranch</code>. Compiletest
|
|
will diff the <code>.before.mir</code> and <code>.after.mir</code> files, and compare the diff
|
|
output to the expected <code>.diff</code> file from the <code>EMIT_MIR</code> comment.</p>
|
|
<p>This is useful if you want to see how an optimization changes the MIR.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>// EMIT_MIR $MIR_PATH.dot</code> — When using specific flags that dump additional
|
|
MIR data (e.g. <code>-Z dump-mir-graphviz</code> to produce <code>.dot</code> files), this will
|
|
check that the output matches the given file.</p>
|
|
</li>
|
|
</ul>
|
|
<p>By default 32 bit and 64 bit targets use the same dump files, which can be
|
|
problematic in the presence of pointers in constants or other bit width
|
|
dependent things. In that case you can add <code>// EMIT_MIR_FOR_EACH_BIT_WIDTH</code> to
|
|
your test, causing separate files to be generated for 32bit and 64bit systems.</p>
|
|
<h3 id="run-make-tests"><a class="header" href="#run-make-tests"><code>run-make</code> tests</a></h3>
|
|
<p>The tests in <a href="https://github.com/rust-lang/rust/tree/master/tests/run-make"><code>tests/run-make</code></a> are general-purpose tests using Rust <em>recipes</em>,
|
|
which are small programs (<code>rmake.rs</code>) allowing arbitrary Rust code such as
|
|
<code>rustc</code> invocations, and is supported by a <a href="https://github.com/rust-lang/rust/tree/master/src/tools/run-make-support"><code>run_make_support</code></a> library. Using
|
|
Rust recipes provide the ultimate in flexibility.</p>
|
|
<p><code>run-make</code> tests should be used if no other test suites better suit your needs.</p>
|
|
<h4 id="using-rust-recipes"><a class="header" href="#using-rust-recipes">Using Rust recipes</a></h4>
|
|
<p>Each test should be in a separate directory with a <code>rmake.rs</code> Rust program,
|
|
called the <em>recipe</em>. A recipe will be compiled and executed by compiletest with
|
|
the <code>run_make_support</code> library linked in.</p>
|
|
<p>If you need new utilities or functionality, consider extending and improving the
|
|
<a href="https://github.com/rust-lang/rust/tree/master/src/tools/run-make-support"><code>run_make_support</code></a> library.</p>
|
|
<p>Compiletest directives like <code>//@ only-<target></code> or <code>//@ ignore-<target></code> are
|
|
supported in <code>rmake.rs</code>, like in UI tests. However, revisions or building
|
|
auxiliary via directives are not currently supported.</p>
|
|
<p><code>rmake.rs</code> and <code>run-make-support</code> may <em>not</em> use any nightly/unstable features,
|
|
as they must be compilable by a stage 0 rustc that may be a beta or even stable
|
|
rustc.</p>
|
|
<h4 id="quickly-check-if-rmakers-tests-can-be-compiled"><a class="header" href="#quickly-check-if-rmakers-tests-can-be-compiled">Quickly check if <code>rmake.rs</code> tests can be compiled</a></h4>
|
|
<p>You can quickly check if <code>rmake.rs</code> tests can be compiled without having to
|
|
build stage1 rustc by forcing <code>rmake.rs</code> to be compiled with the stage0
|
|
compiler:</p>
|
|
<pre><code class="language-bash">$ COMPILETEST_FORCE_STAGE0=1 x test --stage 0 tests/run-make/<test-name>
|
|
</code></pre>
|
|
<p>Of course, some tests will not successfully <em>run</em> in this way.</p>
|
|
<h4 id="using-rust-analyzer-with-rmakers"><a class="header" href="#using-rust-analyzer-with-rmakers">Using rust-analyzer with <code>rmake.rs</code></a></h4>
|
|
<p>Like other test programs, the <code>rmake.rs</code> scripts used by run-make tests do not
|
|
have rust-analyzer integration by default.</p>
|
|
<p>To work around this when working on a particular test, temporarily create a
|
|
<code>Cargo.toml</code> file in the test's directory
|
|
(e.g. <code>tests/run-make/sysroot-crates-are-unstable/Cargo.toml</code>)
|
|
with these contents:</p>
|
|
<div class="warning">
|
|
<p>Be careful not to add this <code>Cargo.toml</code> or its <code>Cargo.lock</code> to your actual PR!</p>
|
|
</div>
|
|
<pre><code class="language-toml"># Convince cargo that this isn't part of an enclosing workspace.
|
|
[workspace]
|
|
|
|
[package]
|
|
name = "rmake"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
run_make_support = { path = "../../../src/tools/run-make-support" }
|
|
|
|
[[bin]]
|
|
name = "rmake"
|
|
path = "rmake.rs"
|
|
</code></pre>
|
|
<p>Then add a corresponding entry to <code>"rust-analyzer.linkedProjects"</code>
|
|
(e.g. in <code>.vscode/settings.json</code>):</p>
|
|
<pre><code class="language-json">"rust-analyzer.linkedProjects": [
|
|
"tests/run-make/sysroot-crates-are-unstable/Cargo.toml"
|
|
],
|
|
</code></pre>
|
|
<h3 id="coverage-tests"><a class="header" href="#coverage-tests">Coverage tests</a></h3>
|
|
<p>The tests in <a href="https://github.com/rust-lang/rust/tree/master/tests/coverage"><code>tests/coverage</code></a> are shared by multiple test modes that test
|
|
coverage instrumentation in different ways. Running the <code>coverage</code> test suite
|
|
will automatically run each test in all of the different coverage modes.</p>
|
|
<p>Each mode also has an alias to run the coverage tests in just that mode:</p>
|
|
<pre><code class="language-bash">./x test coverage # runs all of tests/coverage in all coverage modes
|
|
./x test tests/coverage # same as above
|
|
|
|
./x test tests/coverage/if.rs # runs the specified test in all coverage modes
|
|
|
|
./x test coverage-map # runs all of tests/coverage in "coverage-map" mode only
|
|
./x test coverage-run # runs all of tests/coverage in "coverage-run" mode only
|
|
|
|
./x test coverage-map -- tests/coverage/if.rs # runs the specified test in "coverage-map" mode only
|
|
</code></pre>
|
|
<p>If a particular test should not be run in one of the coverage test modes for
|
|
some reason, use the <code>//@ ignore-coverage-map</code> or <code>//@ ignore-coverage-run</code>
|
|
directives.</p>
|
|
<h4 id="coverage-map-suite"><a class="header" href="#coverage-map-suite"><code>coverage-map</code> suite</a></h4>
|
|
<p>In <code>coverage-map</code> mode, these tests verify the mappings between source code
|
|
regions and coverage counters that are emitted by LLVM. They compile the test
|
|
with <code>--emit=llvm-ir</code>, then use a custom tool (<a href="https://github.com/rust-lang/rust/tree/master/src/tools/coverage-dump"><code>src/tools/coverage-dump</code></a>) to
|
|
extract and pretty-print the coverage mappings embedded in the IR. These tests
|
|
don't require the profiler runtime, so they run in PR CI jobs and are easy to
|
|
run/bless locally.</p>
|
|
<p>These coverage map tests can be sensitive to changes in MIR lowering or MIR
|
|
optimizations, producing mappings that are different but produce identical
|
|
coverage reports.</p>
|
|
<p>As a rule of thumb, any PR that doesn't change coverage-specific code should
|
|
<strong>feel free to re-bless</strong> the <code>coverage-map</code> tests as necessary, without
|
|
worrying about the actual changes, as long as the <code>coverage-run</code> tests still
|
|
pass.</p>
|
|
<h4 id="coverage-run-suite"><a class="header" href="#coverage-run-suite"><code>coverage-run</code> suite</a></h4>
|
|
<p>In <code>coverage-run</code> mode, these tests perform an end-to-end test of coverage
|
|
reporting. They compile a test program with coverage instrumentation, run that
|
|
program to produce raw coverage data, and then use LLVM tools to process that
|
|
data into a human-readable code coverage report.</p>
|
|
<p>Instrumented binaries need to be linked against the LLVM profiler runtime, so
|
|
<code>coverage-run</code> tests are <strong>automatically skipped</strong> unless the profiler runtime
|
|
is enabled in <code>bootstrap.toml</code>:</p>
|
|
<pre><code class="language-toml"># bootstrap.toml
|
|
[build]
|
|
profiler = true
|
|
</code></pre>
|
|
<p>This also means that they typically don't run in PR CI jobs, though they do run
|
|
as part of the full set of CI jobs used for merging.</p>
|
|
<h4 id="coverage-run-rustdoc-suite"><a class="header" href="#coverage-run-rustdoc-suite"><code>coverage-run-rustdoc</code> suite</a></h4>
|
|
<p>The tests in <a href="https://github.com/rust-lang/rust/tree/master/tests/coverage-run-rustdoc"><code>tests/coverage-run-rustdoc</code></a> also run instrumented doctests and
|
|
include them in the coverage report. This avoids having to build rustdoc when
|
|
only running the main <code>coverage</code> suite.</p>
|
|
<h3 id="crashes-tests"><a class="header" href="#crashes-tests">Crashes tests</a></h3>
|
|
<p><a href="https://github.com/rust-lang/rust/tree/master/tests/crashes"><code>tests/crashes</code></a> serve as a collection of tests that are expected to cause the
|
|
compiler to ICE, panic or crash in some other way, so that accidental fixes are
|
|
tracked. Formerly, this was done at <a href="https://github.com/rust-lang/glacier">https://github.com/rust-lang/glacier</a> but
|
|
doing it inside the rust-lang/rust testsuite is more convenient.</p>
|
|
<p>It is imperative that a test in the suite causes rustc to ICE, panic, or
|
|
crash in some other way. A test will "pass" if rustc exits with an exit status
|
|
other than 1 or 0.</p>
|
|
<p>If you want to see verbose stdout/stderr, you need to set
|
|
<code>COMPILETEST_VERBOSE_CRASHES=1</code>, e.g.</p>
|
|
<pre><code class="language-bash">$ COMPILETEST_VERBOSE_CRASHES=1 ./x test tests/crashes/999999.rs --stage 1
|
|
</code></pre>
|
|
<p>Anyone can add <a href="https://github.com/rust-lang/rust/issues?q=is%3Aissue+state%3Aopen+label%3AI-ICE%2CI-crash+label%3AT-compiler+label%3AS-has-mcve+-label%3AS-bug-has-test">"untracked" crashes</a> from the issue tracker. It's strongly
|
|
recommended to include test cases from several issues in a single PR.
|
|
When you do so, each issue number should be noted in the file name (<code>12345.rs</code>
|
|
should suffice) and also inside the file by means of a <code>//@ known-bug: #12345</code>
|
|
directive. Please <a href="https://forge.rust-lang.org/release/issue-triaging.html#applying-and-removing-labels">label</a> the relevant issues with <code>S-bug-has-test</code>
|
|
afterwards.</p>
|
|
<p>If you happen to fix one of the crashes, please move it to a fitting
|
|
subdirectory in <code>tests/ui</code> and give it a meaningful name. Please add a doc
|
|
comment at the top of the file explaining why this test exists, even better if
|
|
you can briefly explain how the example causes rustc to crash previously and
|
|
what was done to prevent rustc to ICE/panic/crash.</p>
|
|
<p>Adding</p>
|
|
<pre><code class="language-text">Fixes #NNNNN
|
|
Fixes #MMMMM
|
|
</code></pre>
|
|
<p>to the description of your pull request will ensure the corresponding tickets be closed
|
|
automatically upon merge.</p>
|
|
<p>Make sure that your fix actually fixes the root cause of the issue and not just
|
|
a subset first. The issue numbers can be found in the file name or the <code>//@ known-bug</code> directive inside the test file.</p>
|
|
<h2 id="building-auxiliary-crates"><a class="header" href="#building-auxiliary-crates">Building auxiliary crates</a></h2>
|
|
<p>It is common that some tests require additional auxiliary crates to be compiled.
|
|
There are multiple <a href="directives.html">directives</a> to assist with that:</p>
|
|
<ul>
|
|
<li><code>aux-build</code></li>
|
|
<li><code>aux-crate</code></li>
|
|
<li><code>aux-bin</code></li>
|
|
<li><code>aux-codegen-backend</code></li>
|
|
<li><code>proc-macro</code></li>
|
|
</ul>
|
|
<p><code>aux-build</code> will build a separate crate from the named source file. The source
|
|
file should be in a directory called <code>auxiliary</code> beside the test file.</p>
|
|
<pre><code class="language-rust ignore">//@ aux-build: my-helper.rs
|
|
|
|
extern crate my_helper;
|
|
// ... You can use my_helper.</code></pre>
|
|
<p>The aux crate will be built as a dylib if possible (unless on a platform that
|
|
does not support them, or the <code>no-prefer-dynamic</code> header is specified in the aux
|
|
file). The <code>-L</code> flag is used to find the extern crates.</p>
|
|
<p><code>aux-crate</code> is very similar to <code>aux-build</code>. However, it uses the <code>--extern</code> flag
|
|
to link to the extern crate to make the crate be available as an extern prelude.
|
|
That allows you to specify the additional syntax of the <code>--extern</code> flag, such as
|
|
renaming a dependency. For example, <code>//@ aux-crate:foo=bar.rs</code> will compile
|
|
<code>auxiliary/bar.rs</code> and make it available under then name <code>foo</code> within the test.
|
|
This is similar to how Cargo does dependency renaming.</p>
|
|
<p><code>aux-bin</code> is similar to <code>aux-build</code> but will build a binary instead of a
|
|
library. The binary will be available in <code>auxiliary/bin</code> relative to the working
|
|
directory of the test.</p>
|
|
<p><code>aux-codegen-backend</code> is similar to <code>aux-build</code>, but will then pass the compiled
|
|
dylib to <code>-Zcodegen-backend</code> when building the main file. This will only work
|
|
for tests in <code>tests/ui-fulldeps</code>, since it requires the use of compiler crates.</p>
|
|
<h3 id="auxiliary-proc-macro"><a class="header" href="#auxiliary-proc-macro">Auxiliary proc-macro</a></h3>
|
|
<p>If you want a proc-macro dependency, then you can use the <code>proc-macro</code>
|
|
directive. This directive behaves just like <code>aux-build</code>, i.e. that you should
|
|
place the proc-macro test auxiliary file under a <code>auxiliary</code> folder under the
|
|
same parent folder as the main test file. However, it also has four additional
|
|
preset behavior compared to <code>aux-build</code> for the proc-macro test auxiliary:</p>
|
|
<ol>
|
|
<li>The aux test file is built with <code>--crate-type=proc-macro</code>.</li>
|
|
<li>The aux test file is built without <code>-C prefer-dynamic</code>, i.e. it will not try
|
|
to produce a dylib for the aux crate.</li>
|
|
<li>The aux crate is made available to the test file via extern prelude with
|
|
<code>--extern <aux_crate_name></code>. Note that since UI tests default to edition
|
|
2015, you still need to specify <code>extern <aux_crate_name></code> unless the main
|
|
test file is using an edition that is 2018 or newer if you want to use the
|
|
aux crate name in a <code>use</code> import.</li>
|
|
<li>The <code>proc_macro</code> crate is made available as an extern prelude module. Same
|
|
edition 2015 vs newer edition distinction for <code>extern proc_macro;</code> applies.</li>
|
|
</ol>
|
|
<p>For example, you might have a test <code>tests/ui/cat/meow.rs</code> and proc-macro
|
|
auxiliary <code>tests/ui/cat/auxiliary/whiskers.rs</code>:</p>
|
|
<pre><code class="language-text">tests/ui/cat/
|
|
meow.rs # main test file
|
|
auxiliary/whiskers.rs # auxiliary
|
|
</code></pre>
|
|
<pre><code class="language-rs">// tests/ui/cat/meow.rs
|
|
|
|
//@ proc-macro: whiskers.rs
|
|
|
|
extern crate whiskers; // needed as ui test defaults to edition 2015
|
|
|
|
fn main() {
|
|
whiskers::identity!();
|
|
}
|
|
</code></pre>
|
|
<pre><code class="language-rs">// tests/ui/cat/auxiliary/whiskers.rs
|
|
|
|
extern crate proc_macro;
|
|
use proc_macro::*;
|
|
|
|
#[proc_macro]
|
|
pub fn identity(ts: TokenStream) -> TokenStream {
|
|
ts
|
|
}
|
|
</code></pre>
|
|
<blockquote>
|
|
<p><strong>Note</strong>: The <code>proc-macro</code> header currently does not work with the
|
|
<code>build-aux-doc</code> header for rustdoc tests. In that case, you will need to use
|
|
the <code>aux-build</code> header, and use <code>#![crate_type="proc_macro"]</code>, and <code>//@ force-host</code> and <code>//@ no-prefer-dynamic</code> headers in the proc-macro.</p>
|
|
</blockquote>
|
|
<h2 id="revisions"><a class="header" href="#revisions">Revisions</a></h2>
|
|
<p>Revisions allow a single test file to be used for multiple tests. This is done
|
|
by adding a special directive at the top of the file:</p>
|
|
<pre><code class="language-rust ignore">//@ revisions: foo bar baz</code></pre>
|
|
<p>This will result in the test being compiled (and tested) three times, once with
|
|
<code>--cfg foo</code>, once with <code>--cfg bar</code>, and once with <code>--cfg baz</code>. You can therefore
|
|
use <code>#[cfg(foo)]</code> etc within the test to tweak each of these results.</p>
|
|
<p>You can also customize directives and expected error messages to a particular
|
|
revision. To do this, add <code>[revision-name]</code> after the <code>//@</code> for directives, and
|
|
after <code>//</code> for UI error annotations, like so:</p>
|
|
<pre><code class="language-rust ignore">// A flag to pass in only for cfg `foo`:
|
|
//@[foo]compile-flags: -Z verbose-internals
|
|
|
|
#[cfg(foo)]
|
|
fn test_foo() {
|
|
let x: usize = 32_u32; //[foo]~ ERROR mismatched types
|
|
}</code></pre>
|
|
<p>Multiple revisions can be specified in a comma-separated list, such as
|
|
<code>//[foo,bar,baz]~^</code>.</p>
|
|
<p>In test suites that use the LLVM <a href="https://llvm.org/docs/CommandGuide/FileCheck.html">FileCheck</a> tool, the current revision name is
|
|
also registered as an additional prefix for FileCheck directives:</p>
|
|
<pre><code class="language-rust ignore">//@ revisions: NORMAL COVERAGE
|
|
//@[COVERAGE] compile-flags: -Cinstrument-coverage
|
|
//@[COVERAGE] needs-profiler-runtime
|
|
|
|
// COVERAGE: @__llvm_coverage_mapping
|
|
// NORMAL-NOT: @__llvm_coverage_mapping
|
|
|
|
// CHECK: main
|
|
fn main() {}</code></pre>
|
|
<p>Note that not all directives have meaning when customized to a revision. For
|
|
example, the <code>ignore-test</code> directives (and all "ignore" directives) currently
|
|
only apply to the test as a whole, not to particular revisions. The only
|
|
directives that are intended to really work when customized to a revision are
|
|
error patterns and compiler flags.</p>
|
|
<!-- date-check jul 2023 -->
|
|
<p>The following test suites support revisions:</p>
|
|
<ul>
|
|
<li>ui</li>
|
|
<li>assembly</li>
|
|
<li>codegen</li>
|
|
<li>coverage</li>
|
|
<li>debuginfo</li>
|
|
<li>rustdoc UI tests</li>
|
|
<li>incremental (these are special in that they inherently cannot be run in
|
|
parallel)</li>
|
|
</ul>
|
|
<h3 id="ignoring-unused-revision-names"><a class="header" href="#ignoring-unused-revision-names">Ignoring unused revision names</a></h3>
|
|
<p>Normally, revision names mentioned in other directives and error annotations
|
|
must correspond to an actual revision declared in a <code>revisions</code> directive. This is
|
|
enforced by an <code>./x test tidy</code> check.</p>
|
|
<p>If a revision name needs to be temporarily removed from the revision list for
|
|
some reason, the above check can be suppressed by adding the revision name to an
|
|
<code>//@ unused-revision-names:</code> header instead.</p>
|
|
<p>Specifying an unused name of <code>*</code> (i.e. <code>//@ unused-revision-names: *</code>) will
|
|
permit any unused revision name to be mentioned.</p>
|
|
<h2 id="compare-modes"><a class="header" href="#compare-modes">Compare modes</a></h2>
|
|
<p>Compiletest can be run in different modes, called <em>compare modes</em>, which can be
|
|
used to compare the behavior of all tests with different compiler flags enabled.
|
|
This can help highlight what differences might appear with certain flags, and
|
|
check for any problems that might arise.</p>
|
|
<p>To run the tests in a different mode, you need to pass the <code>--compare-mode</code> CLI
|
|
flag:</p>
|
|
<pre><code class="language-bash">./x test tests/ui --compare-mode=chalk
|
|
</code></pre>
|
|
<p>The possible compare modes are:</p>
|
|
<ul>
|
|
<li><code>polonius</code> — Runs with Polonius with <code>-Zpolonius</code>.</li>
|
|
<li><code>chalk</code> — Runs with Chalk with <code>-Zchalk</code>.</li>
|
|
<li><code>split-dwarf</code> — Runs with unpacked split-DWARF with
|
|
<code>-Csplit-debuginfo=unpacked</code>.</li>
|
|
<li><code>split-dwarf-single</code> — Runs with packed split-DWARF with
|
|
<code>-Csplit-debuginfo=packed</code>.</li>
|
|
</ul>
|
|
<p>See <a href="ui.html#compare-modes">UI compare modes</a> for more information about how UI
|
|
tests support different output for different modes.</p>
|
|
<p>In CI, compare modes are only used in one Linux builder, and only with the
|
|
following settings:</p>
|
|
<ul>
|
|
<li><code>tests/debuginfo</code>: Uses <code>split-dwarf</code> mode. This helps ensure that none of the
|
|
debuginfo tests are affected when enabling split-DWARF.</li>
|
|
</ul>
|
|
<p>Note that compare modes are separate to <a href="#revisions">revisions</a>. All revisions
|
|
are tested when running <code>./x test tests/ui</code>, however compare-modes must be
|
|
manually run individually via the <code>--compare-mode</code> flag.</p>
|
|
|
|
</main>
|
|
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
|
<!-- Mobile navigation buttons -->
|
|
<a rel="prev" href="../tests/best-practices.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next prefetch" href="../tests/ui.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
|
|
<div style="clear: both"></div>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
|
<a rel="prev" href="../tests/best-practices.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next prefetch" href="../tests/ui.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
window.playground_copyable = true;
|
|
</script>
|
|
|
|
|
|
<script src="../elasticlunr.min.js"></script>
|
|
<script src="../mark.min.js"></script>
|
|
<script src="../searcher.js"></script>
|
|
|
|
<script src="../clipboard.min.js"></script>
|
|
<script src="../highlight.js"></script>
|
|
<script src="../book.js"></script>
|
|
|
|
<!-- Custom JS scripts -->
|
|
<script src="../mermaid.min.js"></script>
|
|
<script src="../mermaid-init.js"></script>
|
|
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|