blob: 9359992351ba4a81a473fef0e89155b16478875a [file] [log] [blame] [edit]
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Variance - 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-de23e50b.svg">
<link rel="shortcut icon" href="favicon-8114d1fc.png">
<link rel="stylesheet" href="css/variables-8adf115d.css">
<link rel="stylesheet" href="css/general-2459343d.css">
<link rel="stylesheet" href="css/chrome-ae938929.css">
<link rel="stylesheet" href="css/print-9e4910d8.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="fonts/fonts-9644e21d.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="mdbook-highlight-css" href="highlight-493f70e1.css">
<link rel="stylesheet" id="mdbook-tomorrow-night-css" href="tomorrow-night-4c0ae647.css">
<link rel="stylesheet" id="mdbook-ayu-highlight-css" href="ayu-highlight-3fdfc3ac.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";
window.path_to_searchindex_js = "searchindex-98315e7b.js";
</script>
<!-- Start loading toc.js asap -->
<script src="toc-9a328f65.js"></script>
</head>
<body>
<div id="mdbook-help-container">
<div id="mdbook-help-popup">
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
<div>
<p>Press <kbd></kbd> or <kbd></kbd> to navigate between chapters</p>
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
<p>Press <kbd>?</kbd> to show this help</p>
<p>Press <kbd>Esc</kbd> to hide this help</p>
</div>
</div>
</div>
<div id="mdbook-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="mdbook-sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("mdbook-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 = false;
}
if (sidebar === 'visible') {
sidebar_toggle.checked = true;
} else {
html.classList.remove('sidebar-visible');
}
</script>
<nav id="mdbook-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="mdbook-sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="mdbook-page-wrapper" class="page-wrapper">
<div class="page">
<div id="mdbook-menu-bar-hover-placeholder"></div>
<div id="mdbook-menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="mdbook-sidebar-toggle" class="icon-button" for="mdbook-sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="mdbook-sidebar">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></span>
</label>
<button id="mdbook-theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="mdbook-theme-list">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M371.3 367.1c27.3-3.9 51.9-19.4 67.2-42.9L600.2 74.1c12.6-19.5 9.4-45.3-7.6-61.2S549.7-4.4 531.1 9.6L294.4 187.2c-24 18-38.2 46.1-38.4 76.1L371.3 367.1zm-19.6 25.4l-116-104.4C175.9 290.3 128 339.6 128 400c0 3.9 .2 7.8 .6 11.6c1.8 17.5-10.2 36.4-27.8 36.4H96c-17.7 0-32 14.3-32 32s14.3 32 32 32H240c61.9 0 112-50.1 112-112c0-2.5-.1-5-.2-7.5z"/></svg></span>
</button>
<ul id="mdbook-theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-ayu">Ayu</button></li>
</ul>
<button id="mdbook-search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="mdbook-searchbar">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352c79.5 0 144-64.5 144-144s-64.5-144-144-144S64 128.5 64 208s64.5 144 144 144z"/></svg></span>
</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">
<span class=fa-svg id="print-button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M128 0C92.7 0 64 28.7 64 64v96h64V64H354.7L384 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L400 18.7C388 6.7 371.7 0 354.7 0H128zM384 352v32 64H128V384 368 352H384zm64 32h32c17.7 0 32-14.3 32-32V256c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v96c0 17.7 14.3 32 32 32H64v64c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V384zm-16-88c-13.3 0-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24s-10.7 24-24 24z"/></svg></span>
</a>
<a href="https://github.com/rust-lang/rustc-dev-guide" title="Git repository" aria-label="Git repository">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg></span>
</a>
<a href="https://github.com/rust-lang/rustc-dev-guide/edit/main/src/variance.md" title="Suggest an edit" aria-label="Suggest an edit" rel="edit">
<span class=fa-svg id="git-edit-button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M421.7 220.3l-11.3 11.3-22.6 22.6-205 205c-6.6 6.6-14.8 11.5-23.8 14.1L30.8 511c-8.4 2.5-17.5 .2-23.7-6.1S-1.5 489.7 1 481.2L38.7 353.1c2.6-9 7.5-17.2 14.1-23.8l205-205 22.6-22.6 11.3-11.3 33.9 33.9 62.1 62.1 33.9 33.9zM96 353.9l-9.3 9.3c-.9 .9-1.6 2.1-2 3.4l-25.3 86 86-25.3c1.3-.4 2.5-1.1 3.4-2l9.3-9.3H112c-8.8 0-16-7.2-16-16V353.9zM453.3 19.3l39.4 39.4c25 25 25 65.5 0 90.5l-14.5 14.5-22.6 22.6-11.3 11.3-33.9-33.9-62.1-62.1L314.3 67.7l11.3-11.3 22.6-22.6 14.5-14.5c25-25 65.5-25 90.5 0z"/></svg></span>
</a>
</div>
</div>
<div id="mdbook-search-wrapper" class="hidden">
<form id="mdbook-searchbar-outer" class="searchbar-outer">
<div class="search-wrapper">
<input type="search" id="mdbook-searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="mdbook-searchresults-outer" aria-describedby="searchresults-header">
<div class="spinner-wrapper">
<span class=fa-svg id="fa-spin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M304 48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zm0 416c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM48 304c26.5 0 48-21.5 48-48s-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48zm464-48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM142.9 437c18.7-18.7 18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zm0-294.2c18.7-18.7 18.7-49.1 0-67.9S93.7 56.2 75 75s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zM369.1 437c18.7 18.7 49.1 18.7 67.9 0s18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9z"/></svg></span>
</div>
</div>
</form>
<div id="mdbook-searchresults-outer" class="searchresults-outer hidden">
<div id="mdbook-searchresults-header" class="searchresults-header"></div>
<ul id="mdbook-searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('mdbook-sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('mdbook-sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#mdbook-sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="mdbook-content" class="content">
<main>
<h1 id="variance-of-type-and-lifetime-parameters"><a class="header" href="#variance-of-type-and-lifetime-parameters">Variance of type and lifetime parameters</a></h1>
<p>For a more general background on variance, see the <a href="./appendix/background.html">background</a> appendix.</p>
<p>During type checking we must infer the variance of type and lifetime
parameters. The algorithm is taken from Section 4 of the paper <a href="https://people.cs.umass.edu/~yannis/variance-extended2011.pdf">“Taming the
Wildcards: Combining Definition- and Use-Site Variance”</a> published in
PLDI’11 and written by Altidor et al., and hereafter referred to as The Paper.</p>
<p>This inference is explicitly designed <em>not</em> to consider the uses of
types within code. To determine the variance of type parameters
defined on type <code>X</code>, we only consider the definition of the type <code>X</code>
and the definitions of any types it references.</p>
<p>We only infer variance for type parameters found on <em>data types</em>
like structs and enums. In these cases, there is a fairly straightforward
explanation for what variance means. The variance of the type
or lifetime parameters defines whether <code>T&lt;A&gt;</code> is a subtype of <code>T&lt;B&gt;</code>
(resp. <code>T&lt;'a&gt;</code> and <code>T&lt;'b&gt;</code>) based on the relationship of <code>A</code> and <code>B</code>
(resp. <code>'a</code> and <code>'b</code>).</p>
<p>We do not infer variance for type parameters found on traits, functions,
or impls. Variance on trait parameters can indeed make sense
(and we used to compute it) but it is actually rather subtle in
meaning and not that useful in practice, so we removed it. See the
<a href="#addendum">addendum</a> for some details. Variances on function/impl parameters, on the
other hand, doesn’t make sense because these parameters are instantiated and
then forgotten, they don’t persist in types or compiled byproducts.</p>
<blockquote>
<p><strong>Notation</strong></p>
<p>We use the notation of The Paper throughout this chapter:</p>
<ul>
<li><code>+</code> is <em>covariance</em>.</li>
<li><code>-</code> is <em>contravariance</em>.</li>
<li><code>*</code> is <em>bivariance</em>.</li>
<li><code>o</code> is <em>invariance</em>.</li>
</ul>
</blockquote>
<h2 id="the-algorithm"><a class="header" href="#the-algorithm">The algorithm</a></h2>
<p>The basic idea is quite straightforward. We iterate over the types
defined and, for each use of a type parameter <code>X</code>, accumulate a
constraint indicating that the variance of <code>X</code> must be valid for the
variance of that use site. We then iteratively refine the variance of
<code>X</code> until all constraints are met. There is <em>always</em> a solution, because at
the limit we can declare all type parameters to be invariant and all
constraints will be satisfied.</p>
<p>As a simple example, consider:</p>
<pre><code class="language-rust ignore">enum Option&lt;A&gt; { Some(A), None }
enum OptionalFn&lt;B&gt; { Some(|B|), None }
enum OptionalMap&lt;C&gt; { Some(|C| -&gt; C), None }</code></pre>
<p>Here, we will generate the constraints:</p>
<pre><code class="language-text">1. V(A) &lt;= +
2. V(B) &lt;= -
3. V(C) &lt;= +
4. V(C) &lt;= -
</code></pre>
<p>These indicate that (1) the variance of A must be at most covariant;
(2) the variance of B must be at most contravariant; and (3, 4) the
variance of C must be at most covariant <em>and</em> contravariant. All of these
results are based on a variance lattice defined as follows:</p>
<pre><code class="language-text"> * Top (bivariant)
- +
o Bottom (invariant)
</code></pre>
<p>Based on this lattice, the solution <code>V(A)=+</code>, <code>V(B)=-</code>, <code>V(C)=o</code> is the
optimal solution. Note that there is always a naive solution which
just declares all variables to be invariant.</p>
<p>You may be wondering why fixed-point iteration is required. The reason
is that the variance of a use site may itself be a function of the
variance of other type parameters. In full generality, our constraints
take the form:</p>
<pre><code class="language-text">V(X) &lt;= Term
Term := + | - | * | o | V(X) | Term x Term
</code></pre>
<p>Here the notation <code>V(X)</code> indicates the variance of a type/region
parameter <code>X</code> with respect to its defining class. <code>Term x Term</code>
represents the “variance transform” as defined in the paper:</p>
<blockquote>
<p>If the variance of a type variable <code>X</code> in type expression <code>E</code> is <code>V2</code>
and the definition-site variance of the corresponding type parameter
of a class <code>C</code> is <code>V1</code>, then the variance of <code>X</code> in the type expression
<code>C&lt;E&gt;</code> is <code>V3 = V1.xform(V2)</code>.</p>
</blockquote>
<h2 id="constraints"><a class="header" href="#constraints">Constraints</a></h2>
<p>If I have a struct or enum with where clauses:</p>
<pre><code class="language-rust ignore">struct Foo&lt;T: Bar&gt; { ... }</code></pre>
<p>you might wonder whether the variance of <code>T</code> with respect to <code>Bar</code> affects the
variance <code>T</code> with respect to <code>Foo</code>. I claim no. The reason: assume that <code>T</code> is
invariant with respect to <code>Bar</code> but covariant with respect to <code>Foo</code>. And then
we have a <code>Foo&lt;X&gt;</code> that is upcast to <code>Foo&lt;Y&gt;</code>, where <code>X &lt;: Y</code>. However, while
<code>X : Bar</code>, <code>Y : Bar</code> does not hold. In that case, the upcast will be illegal,
but not because of a variance failure, but rather because the target type
<code>Foo&lt;Y&gt;</code> is itself just not well-formed. Basically we get to assume
well-formedness of all types involved before considering variance.</p>
<h3 id="dependency-graph-management"><a class="header" href="#dependency-graph-management">Dependency graph management</a></h3>
<p>Because variance is a whole-crate inference, its dependency graph
can become quite muddled if we are not careful. To resolve this, we refactor
into two queries:</p>
<ul>
<li><code>crate_variances</code> computes the variance for all items in the current crate.</li>
<li><code>variances_of</code> accesses the variance for an individual reading; it
works by requesting <code>crate_variances</code> and extracting the relevant data.</li>
</ul>
<p>If you limit yourself to reading <code>variances_of</code>, your code will only
depend then on the inference of that particular item.</p>
<p>Ultimately, this setup relies on the <a href="./queries/incremental-compilation.html">red-green algorithm</a>. In particular,
every variance query effectively depends on all type definitions in the entire
crate (through <code>crate_variances</code>), but since most changes will not result in a
change to the actual results from variance inference, the <code>variances_of</code> query
will wind up being considered green after it is re-evaluated.</p>
<p><a id="addendum"></a></p>
<h2 id="addendum-variance-on-traits"><a class="header" href="#addendum-variance-on-traits">Addendum: Variance on traits</a></h2>
<p>As mentioned above, we used to permit variance on traits. This was
computed based on the appearance of trait type parameters in
method signatures and was used to represent the compatibility of
vtables in trait objects (and also “virtual” vtables or dictionary
in trait bounds). One complication was that variance for
associated types is less obvious, since they can be projected out
and put to myriad uses, so it’s not clear when it is safe to allow
<code>X&lt;A&gt;::Bar</code> to vary (or indeed just what that means). Moreover (as
covered below) all inputs on any trait with an associated type had
to be invariant, limiting the applicability. Finally, the
annotations (<code>MarkerTrait</code>, <code>PhantomFn</code>) needed to ensure that all
trait type parameters had a variance were confusing and annoying
for little benefit.</p>
<p>Just for historical reference, I am going to preserve some text indicating how
one could interpret variance and trait matching.</p>
<h3 id="variance-and-object-types"><a class="header" href="#variance-and-object-types">Variance and object types</a></h3>
<p>Just as with structs and enums, we can decide the subtyping
relationship between two object types <code>&amp;Trait&lt;A&gt;</code> and <code>&amp;Trait&lt;B&gt;</code>
based on the relationship of <code>A</code> and <code>B</code>. Note that for object
types we ignore the <code>Self</code> type parameter – it is unknown, and
the nature of dynamic dispatch ensures that we will always call a
function that is expected the appropriate <code>Self</code> type. However, we
must be careful with the other type parameters, or else we could
end up calling a function that is expecting one type but provided
another.</p>
<p>To see what I mean, consider a trait like so:</p>
<pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait ConvertTo&lt;A&gt; {
fn convertTo(&amp;self) -&gt; A;
}
<span class="boring">}</span></code></pre>
<p>Intuitively, If we had one object <code>O=&amp;ConvertTo&lt;Object&gt;</code> and another
<code>S=&amp;ConvertTo&lt;String&gt;</code>, then <code>S &lt;: O</code> because <code>String &lt;: Object</code>
(presuming Java-like “string” and “object” types, my go to examples
for subtyping). The actual algorithm would be to compare the
(explicit) type parameters pairwise respecting their variance: here,
the type parameter A is covariant (it appears only in a return
position), and hence we require that <code>String &lt;: Object</code>.</p>
<p>You’ll note though that we did not consider the binding for the
(implicit) <code>Self</code> type parameter: in fact, it is unknown, so that’s
good. The reason we can ignore that parameter is precisely because we
don’t need to know its value until a call occurs, and at that time (as
you said) the dynamic nature of virtual dispatch means the code we run
will be correct for whatever value <code>Self</code> happens to be bound to for
the particular object whose method we called. <code>Self</code> is thus different
from <code>A</code>, because the caller requires that <code>A</code> be known in order to
know the return type of the method <code>convertTo()</code>. (As an aside, we
have rules preventing methods where <code>Self</code> appears outside of the
receiver position from being called via an object.)</p>
<h3 id="trait-variance-and-vtable-resolution"><a class="header" href="#trait-variance-and-vtable-resolution">Trait variance and vtable resolution</a></h3>
<p>But traits aren’t only used with objects. They’re also used when
deciding whether a given impl satisfies a given trait bound. To set the
scene here, imagine I had a function:</p>
<pre><code class="language-rust ignore">fn convertAll&lt;A,T:ConvertTo&lt;A&gt;&gt;(v: &amp;[T]) { ... }</code></pre>
<p>Now imagine that I have an implementation of <code>ConvertTo</code> for <code>Object</code>:</p>
<pre><code class="language-rust ignore">impl ConvertTo&lt;i32&gt; for Object { ... }</code></pre>
<p>And I want to call <code>convertAll</code> on an array of strings. Suppose
further that for whatever reason I specifically supply the value of
<code>String</code> for the type parameter <code>T</code>:</p>
<pre><code class="language-rust ignore">let mut vector = vec!["string", ...];
convertAll::&lt;i32, String&gt;(vector);</code></pre>
<p>Is this legal? To put another way, can we apply the <code>impl</code> for
<code>Object</code> to the type <code>String</code>? The answer is yes, but to see why
we have to expand out what will happen:</p>
<ul>
<li>
<p><code>convertAll</code> will create a pointer to one of the entries in the
vector, which will have type <code>&amp;String</code></p>
</li>
<li>
<p>It will then call the impl of <code>convertTo()</code> that is intended
for use with objects. This has the type <code>fn(self: &amp;Object) -&gt; i32</code>.</p>
<p>It is OK to provide a value for <code>self</code> of type <code>&amp;String</code> because
<code>&amp;String &lt;: &amp;Object</code>.</p>
</li>
</ul>
<p>OK, so intuitively we want this to be legal, so let’s bring this back
to variance and see whether we are computing the correct result. We
must first figure out how to phrase the question “is an impl for
<code>Object,i32</code> usable where an impl for <code>String,i32</code> is expected?”</p>
<p>Maybe it’s helpful to think of a dictionary-passing implementation of
type classes. In that case, <code>convertAll()</code> takes an implicit parameter
representing the impl. In short, we <em>have</em> an impl of type:</p>
<pre><code class="language-text">V_O = ConvertTo&lt;i32&gt; for Object
</code></pre>
<p>and the function prototype expects an impl of type:</p>
<pre><code class="language-text">V_S = ConvertTo&lt;i32&gt; for String
</code></pre>
<p>As with any argument, this is legal if the type of the value given
(<code>V_O</code>) is a subtype of the type expected (<code>V_S</code>). So is <code>V_O &lt;: V_S</code>?
The answer will depend on the variance of the various parameters. In
this case, because the <code>Self</code> parameter is contravariant and <code>A</code> is
covariant, it means that:</p>
<pre><code class="language-text">V_O &lt;: V_S iff
i32 &lt;: i32
String &lt;: Object
</code></pre>
<p>These conditions are satisfied and so we are happy.</p>
<h3 id="variance-and-associated-types"><a class="header" href="#variance-and-associated-types">Variance and associated types</a></h3>
<p>Traits with associated types – or at minimum projection
expressions – must be invariant with respect to all of their
inputs. To see why this makes sense, consider what subtyping for a
trait reference means:</p>
<pre><code class="language-text">&lt;T as Trait&gt; &lt;: &lt;U as Trait&gt;
</code></pre>
<p>means that if I know that <code>T as Trait</code>, I also know that <code>U as Trait</code>. Moreover, if you think of it as dictionary passing style,
it means that a dictionary for <code>&lt;T as Trait&gt;</code> is safe to use where
a dictionary for <code>&lt;U as Trait&gt;</code> is expected.</p>
<p>The problem is that when you can project types out from <code>&lt;T as Trait&gt;</code>, the relationship to types projected out of <code>&lt;U as Trait&gt;</code>
is completely unknown unless <code>T==U</code> (see #21726 for more
details). Making <code>Trait</code> invariant ensures that this is true.</p>
<p>Another related reason is that if we didn’t make traits with
associated types invariant, then projection is no longer a
function with a single result. Consider:</p>
<pre><code class="language-rust ignore">trait Identity { type Out; fn foo(&amp;self); }
impl&lt;T&gt; Identity for T { type Out = T; ... }</code></pre>
<p>Now if I have <code>&lt;&amp;'static () as Identity&gt;::Out</code>, this can be
validly derived as <code>&amp;'a ()</code> for any <code>'a</code>:</p>
<pre><code class="language-text">&lt;&amp;'a () as Identity&gt; &lt;: &lt;&amp;'static () as Identity&gt;
if &amp;'static () &lt; : &amp;'a () -- Identity is contravariant in Self
if 'static : 'a -- Subtyping rules for relations
</code></pre>
<p>This change otoh means that <code>&lt;'static () as Identity&gt;::Out</code> is
always <code>&amp;'static ()</code> (which might then be upcast to <code>'a ()</code>,
separately). This was helpful in solving #21750.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="traits/unsize.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg></span>
</a>
<a rel="next prefetch" href="coherence.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z"/></svg></span>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="traits/unsize.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg></span>
</a>
<a rel="next prefetch" href="coherence.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z"/></svg></span>
</a>
</nav>
</div>
<template id=fa-eye><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg></span></template>
<template id=fa-eye-slash><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z"/></svg></span></template>
<template id=fa-copy><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M502.6 70.63l-61.25-61.25C435.4 3.371 427.2 0 418.7 0H255.1c-35.35 0-64 28.66-64 64l.0195 256C192 355.4 220.7 384 256 384h192c35.2 0 64-28.8 64-64V93.25C512 84.77 508.6 76.63 502.6 70.63zM464 320c0 8.836-7.164 16-16 16H255.1c-8.838 0-16-7.164-16-16L239.1 64.13c0-8.836 7.164-16 16-16h128L384 96c0 17.67 14.33 32 32 32h47.1V320zM272 448c0 8.836-7.164 16-16 16H63.1c-8.838 0-16-7.164-16-16L47.98 192.1c0-8.836 7.164-16 16-16H160V128H63.99c-35.35 0-64 28.65-64 64l.0098 256C.002 483.3 28.66 512 64 512h192c35.2 0 64-28.8 64-64v-32h-47.1L272 448z"/></svg></span></template>
<template id=fa-play><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"/></svg></span></template>
<template id=fa-clock-rotate-left><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M75 75L41 41C25.9 25.9 0 36.6 0 57.9V168c0 13.3 10.7 24 24 24H134.1c21.4 0 32.1-25.9 17-41l-30.8-30.8C155 85.5 203 64 256 64c106 0 192 86 192 192s-86 192-192 192c-40.8 0-78.6-12.7-109.7-34.4c-14.5-10.1-34.4-6.6-44.6 7.9s-6.6 34.4 7.9 44.6C151.2 495 201.7 512 256 512c141.4 0 256-114.6 256-256S397.4 0 256 0C185.3 0 121.3 28.7 75 75zm181 53c-13.3 0-24 10.7-24 24V256c0 6.4 2.5 12.5 7 17l72 72c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-65-65V152c0-13.3-10.7-24-24-24z"/></svg></span></template>
<script>
window.playground_copyable = true;
</script>
<script src="elasticlunr-ef4e11c1.min.js"></script>
<script src="mark-09e88c2c.min.js"></script>
<script src="searcher-c2a407aa.js"></script>
<script src="clipboard-1626706a.min.js"></script>
<script src="highlight-abc7f01d.js"></script>
<script src="book-a0b12cfe.js"></script>
<!-- Custom JS scripts -->
<script src="mermaid-cc85ecea.min.js"></script>
<script src="mermaid-init-4533fb11.js"></script>
</div>
</body>
</html>