blob: 3fbf3f60fa835413806a52330c351592102a6ff1 [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Error codes - 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 -->
<link rel="stylesheet" href="../pagetoc.css">
<!-- 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/diagnostics/error-codes.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="error-codes"><a class="header" href="#error-codes">Error codes</a></h1>
<p>We generally try to assign each error message a unique code like <code>E0123</code>. These
codes are defined in the compiler in the <code>diagnostics.rs</code> files found in each
crate, which basically consist of macros. All error codes have an associated
explanation: new error codes must include them. Note that not all <em>historical</em>
(no longer emitted) error codes have explanations.</p>
<h2 id="error-explanations"><a class="header" href="#error-explanations">Error explanations</a></h2>
<p>The explanations are written in Markdown (see the <a href="https://spec.commonmark.org/current/">CommonMark Spec</a> for
specifics around syntax), and all of them are linked in the <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_error_codes/index.html"><code>rustc_error_codes</code></a>
crate. Please read <a href="https://github.com/rust-lang/rfcs/blob/master/text/1567-long-error-codes-explanation-normalization.md">RFC 1567</a> for details on how to format and write long error
codes. As of <!-- date-check --> February 2023, there is an
effort<sup class="footnote-reference" id="fr-new-explanations-1"><a href="#footnote-new-explanations">1</a></sup> to replace this largely outdated RFC with a new more
flexible standard.</p>
<p>Error explanations should expand on the error message and provide details about
<em>why</em> the error occurs. It is not helpful for users to copy-paste a quick fix;
explanations should help users understand why their code cannot be accepted by
the compiler. Rust prides itself on helpful error messages and long-form
explanations are no exception. However, before error explanations are
overhauled<sup class="footnote-reference" id="fr-new-explanations-2"><a href="#footnote-new-explanations">1</a></sup> it is a bit open as to how exactly they should be
written, as always: ask your reviewer or ask around on the Rust Zulip.</p>
<h2 id="allocating-a-fresh-code"><a class="header" href="#allocating-a-fresh-code">Allocating a fresh code</a></h2>
<p>Error codes are stored in <code>compiler/rustc_error_codes</code>.</p>
<p>To create a new error, you first need to find the next available
code. You can find it with <code>tidy</code>:</p>
<pre><code>./x test tidy
</code></pre>
<p>This will invoke the tidy script, which generally checks that your code obeys
our coding conventions. Some of these jobs check error codes and ensure that
there aren't duplicates, etc (the tidy check is defined in
<code>src/tools/tidy/src/error_codes.rs</code>). Once it is finished with that, tidy will
print out the highest used error code:</p>
<pre><code>...
tidy check
Found 505 error codes
Highest error code: `E0591`
...
</code></pre>
<p>Here we see the highest error code in use is <code>E0591</code>, so we <em>probably</em> want
<code>E0592</code>. To be sure, run <code>rg E0592</code> and check, you should see no references.</p>
<p>You will have to write an extended description for your error,
which will go in <code>rustc_error_codes/src/error_codes/E0592.md</code>.
To register the error, open <code>rustc_error_codes/src/error_codes.rs</code> and add the
code (in its proper numerical order) into<code> register_diagnostics!</code> macro, like
this:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>register_diagnostics! {
...
E0592: include_str!("./error_codes/E0592.md"),
}
<span class="boring">}</span></code></pre></pre>
<p>To actually issue the error, you can use the <code>struct_span_code_err!</code> macro:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct_span_code_err!(self.dcx(), // some path to the `DiagCtxt` here
span, // whatever span in the source you want
E0592, // your new error code
fluent::example::an_error_message)
.emit() // actually issue the error
<span class="boring">}</span></code></pre></pre>
<p>If you want to add notes or other snippets, you can invoke methods before you
call <code>.emit()</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct_span_code_err!(...)
.span_label(another_span, fluent::example::example_label)
.span_note(another_span, fluent::example::separate_note)
.emit()
<span class="boring">}</span></code></pre></pre>
<p>For an example of a PR adding an error code, see <a href="https://github.com/rust-lang/rust/pull/76143">#76143</a>.</p>
<h2 id="running-error-code-doctests"><a class="header" href="#running-error-code-doctests">Running error code doctests</a></h2>
<p>To test the examples added in <code>rustc_error_codes/src/error_codes</code>, run the
error index generator using:</p>
<pre><code>./x test ./src/tools/error_index_generator
</code></pre>
<hr>
<ol class="footnote-definition"><li id="footnote-new-explanations">
<p>See the draft RFC <a href="https://github.com/rust-lang/rfcs/pull/3370">here</a>. <a href="#fr-new-explanations-1"></a> <a href="#fr-new-explanations-2">↩2</a></p>
</li>
</ol>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../diagnostics/lintstore.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="../diagnostics/diagnostic-items.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="../diagnostics/lintstore.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="../diagnostics/diagnostic-items.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>
<script src="../pagetoc.js"></script>
</div>
</body>
</html>