blob: 8e11a16e1289772fd728132027c0644329f75e98 [file] [log] [blame] [edit]
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The ty module: representing types - Guide to Rustc Development</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="A guide to developing 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" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var 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 type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="about-this-guide.html">About this guide</a></li><li class="chapter-item affix "><a href="getting-started.html">Getting Started</a></li><li class="spacer"></li><li class="chapter-item affix "><li class="part-title">Building and debugging rustc</li><li class="chapter-item "><a href="building/how-to-build-and-run.html"><strong aria-hidden="true">1.</strong> How to Build and Run the Compiler</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="building/prerequisites.html"><strong aria-hidden="true">1.1.</strong> Prerequisites</a></li><li class="chapter-item "><a href="building/suggested.html"><strong aria-hidden="true">1.2.</strong> Suggested Workflows</a></li><li class="chapter-item "><a href="building/build-install-distribution-artifacts.html"><strong aria-hidden="true">1.3.</strong> Distribution artifacts</a></li><li class="chapter-item "><a href="building/compiler-documenting.html"><strong aria-hidden="true">1.4.</strong> Documenting Compiler</a></li><li class="chapter-item "><a href="rustdoc.html"><strong aria-hidden="true">1.5.</strong> Rustdoc overview</a></li><li class="chapter-item "><a href="building/new-target.html"><strong aria-hidden="true">1.6.</strong> Adding a new target</a></li></ol></li><li class="chapter-item "><a href="tests/intro.html"><strong aria-hidden="true">2.</strong> The compiler testing framework</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="tests/running.html"><strong aria-hidden="true">2.1.</strong> Running tests</a></li><li class="chapter-item "><a href="tests/adding.html"><strong aria-hidden="true">2.2.</strong> Adding new tests</a></li><li class="chapter-item "><a href="compiletest.html"><strong aria-hidden="true">2.3.</strong> Using compiletest commands to control test execution</a></li></ol></li><li class="chapter-item "><a href="compiler-debugging.html"><strong aria-hidden="true">3.</strong> Debugging the Compiler</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="tracing.html"><strong aria-hidden="true">3.1.</strong> Using the tracing/logging instrumentation</a></li></ol></li><li class="chapter-item "><a href="profiling.html"><strong aria-hidden="true">4.</strong> Profiling the compiler</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="profiling/with_perf.html"><strong aria-hidden="true">4.1.</strong> with the linux perf tool</a></li><li class="chapter-item "><a href="profiling/wpa_profiling.html"><strong aria-hidden="true">4.2.</strong> with Windows Performance Analyzer</a></li></ol></li><li class="chapter-item "><a href="crates-io.html"><strong aria-hidden="true">5.</strong> crates.io Dependencies</a></li><li class="chapter-item affix "><li class="part-title">Contributing to Rust</li><li class="chapter-item "><a href="contributing.html"><strong aria-hidden="true">6.</strong> Introduction</a></li><li class="chapter-item "><a href="compiler-team.html"><strong aria-hidden="true">7.</strong> About the compiler team</a></li><li class="chapter-item "><a href="git.html"><strong aria-hidden="true">8.</strong> Using Git</a></li><li class="chapter-item "><a href="rustbot.html"><strong aria-hidden="true">9.</strong> Mastering @rustbot</a></li><li class="chapter-item "><a href="walkthrough.html"><strong aria-hidden="true">10.</strong> Walkthrough: a typical contribution</a></li><li class="chapter-item "><a href="bug-fix-procedure.html"><strong aria-hidden="true">11.</strong> Bug Fix Procedure</a></li><li class="chapter-item "><a href="implementing_new_features.html"><strong aria-hidden="true">12.</strong> Implementing new features</a></li><li class="chapter-item "><a href="stability.html"><strong aria-hidden="true">13.</strong> Stability attributes</a></li><li class="chapter-item "><a href="stabilization_guide.html"><strong aria-hidden="true">14.</strong> Stabilizing Features</a></li><li class="chapter-item "><a href="feature-gates.html"><strong aria-hidden="true">15.</strong> Feature Gates</a></li><li class="chapter-item "><a href="conventions.html"><strong aria-hidden="true">16.</strong> Coding conventions</a></li><li class="chapter-item "><a href="notification-groups/about.html"><strong aria-hidden="true">17.</strong> Notification groups</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="notification-groups/arm.html"><strong aria-hidden="true">17.1.</strong> ARM</a></li><li class="chapter-item "><a href="notification-groups/cleanup-crew.html"><strong aria-hidden="true">17.2.</strong> Cleanup Crew</a></li><li class="chapter-item "><a href="notification-groups/llvm.html"><strong aria-hidden="true">17.3.</strong> LLVM</a></li><li class="chapter-item "><a href="notification-groups/risc-v.html"><strong aria-hidden="true">17.4.</strong> RISC-V</a></li><li class="chapter-item "><a href="notification-groups/windows.html"><strong aria-hidden="true">17.5.</strong> Windows</a></li></ol></li><li class="chapter-item "><a href="licenses.html"><strong aria-hidden="true">18.</strong> Licenses</a></li><li class="chapter-item affix "><li class="part-title">High-level Compiler Architecture</li><li class="chapter-item "><a href="part-2-intro.html"><strong aria-hidden="true">19.</strong> Prologue</a></li><li class="chapter-item "><a href="overview.html"><strong aria-hidden="true">20.</strong> Overview of the Compiler</a></li><li class="chapter-item "><a href="compiler-src.html"><strong aria-hidden="true">21.</strong> The compiler source code</a></li><li class="chapter-item "><a href="building/bootstrapping.html"><strong aria-hidden="true">22.</strong> Bootstrapping</a></li><li class="chapter-item "><a href="query.html"><strong aria-hidden="true">23.</strong> Queries: demand-driven compilation</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="queries/query-evaluation-model-in-detail.html"><strong aria-hidden="true">23.1.</strong> The Query Evaluation Model in Detail</a></li><li class="chapter-item "><a href="queries/incremental-compilation.html"><strong aria-hidden="true">23.2.</strong> Incremental compilation</a></li><li class="chapter-item "><a href="queries/incremental-compilation-in-detail.html"><strong aria-hidden="true">23.3.</strong> Incremental compilation In Detail</a></li><li class="chapter-item "><a href="incrcomp-debugging.html"><strong aria-hidden="true">23.4.</strong> Debugging and Testing</a></li><li class="chapter-item "><a href="salsa.html"><strong aria-hidden="true">23.5.</strong> Salsa</a></li></ol></li><li class="chapter-item "><a href="memory.html"><strong aria-hidden="true">24.</strong> Memory Management in Rustc</a></li><li class="chapter-item "><a href="serialization.html"><strong aria-hidden="true">25.</strong> Serialization in Rustc</a></li><li class="chapter-item "><a href="parallel-rustc.html"><strong aria-hidden="true">26.</strong> Parallel Compilation</a></li><li class="chapter-item "><a href="rustdoc-internals.html"><strong aria-hidden="true">27.</strong> Rustdoc internals</a></li><li class="chapter-item affix "><li class="part-title">Source Code Representation</li><li class="chapter-item "><a href="part-3-intro.html"><strong aria-hidden="true">28.</strong> Prologue</a></li><li class="chapter-item "><a href="cli.html"><strong aria-hidden="true">29.</strong> Command-line arguments</a></li><li class="chapter-item "><a href="rustc-driver.html"><strong aria-hidden="true">30.</strong> The Rustc Driver and Interface</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="rustc-driver-interacting-with-the-ast.html"><strong aria-hidden="true">30.1.</strong> Ex: Type checking through rustc_interface</a></li><li class="chapter-item "><a href="rustc-driver-getting-diagnostics.html"><strong aria-hidden="true">30.2.</strong> Ex: Getting diagnostics through rustc_interface</a></li></ol></li><li class="chapter-item "><a href="syntax-intro.html"><strong aria-hidden="true">31.</strong> Syntax and the AST</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="the-parser.html"><strong aria-hidden="true">31.1.</strong> Lexing and Parsing</a></li><li class="chapter-item "><a href="macro-expansion.html"><strong aria-hidden="true">31.2.</strong> Macro expansion</a></li><li class="chapter-item "><a href="name-resolution.html"><strong aria-hidden="true">31.3.</strong> Name resolution</a></li><li class="chapter-item "><a href="test-implementation.html"><strong aria-hidden="true">31.4.</strong> #[test] Implementation</a></li><li class="chapter-item "><a href="panic-implementation.html"><strong aria-hidden="true">31.5.</strong> Panic Implementation</a></li><li class="chapter-item "><a href="ast-validation.html"><strong aria-hidden="true">31.6.</strong> AST Validation</a></li><li class="chapter-item "><a href="feature-gate-ck.html"><strong aria-hidden="true">31.7.</strong> Feature Gate Checking</a></li><li class="chapter-item "><a href="lang-items.html"><strong aria-hidden="true">31.8.</strong> Lang Items</a></li></ol></li><li class="chapter-item "><a href="hir.html"><strong aria-hidden="true">32.</strong> The HIR (High-level IR)</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="lowering.html"><strong aria-hidden="true">32.1.</strong> Lowering AST to HIR</a></li><li class="chapter-item "><a href="hir-debugging.html"><strong aria-hidden="true">32.2.</strong> Debugging</a></li></ol></li><li class="chapter-item "><a href="thir.html"><strong aria-hidden="true">33.</strong> The THIR (Typed High-level IR)</a></li><li class="chapter-item "><a href="mir/index.html"><strong aria-hidden="true">34.</strong> The MIR (Mid-level IR)</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="mir/construction.html"><strong aria-hidden="true">34.1.</strong> MIR construction</a></li><li class="chapter-item "><a href="mir/visitor.html"><strong aria-hidden="true">34.2.</strong> MIR visitor and traversal</a></li><li class="chapter-item "><a href="mir/passes.html"><strong aria-hidden="true">34.3.</strong> MIR passes: getting the MIR for a function</a></li></ol></li><li class="chapter-item "><a href="identifiers.html"><strong aria-hidden="true">35.</strong> Identifiers in the Compiler</a></li><li class="chapter-item "><a href="closure.html"><strong aria-hidden="true">36.</strong> Closure expansion</a></li><li class="chapter-item affix "><li class="part-title">Analysis</li><li class="chapter-item "><a href="part-4-intro.html"><strong aria-hidden="true">37.</strong> Prologue</a></li><li class="chapter-item expanded "><a href="ty.html" class="active"><strong aria-hidden="true">38.</strong> The ty module: representing types</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="generics.html"><strong aria-hidden="true">38.1.</strong> Generics and substitutions</a></li><li class="chapter-item "><a href="ty-fold.html"><strong aria-hidden="true">38.2.</strong> TypeFolder and TypeFoldable</a></li><li class="chapter-item "><a href="generic_arguments.html"><strong aria-hidden="true">38.3.</strong> Generic arguments</a></li><li class="chapter-item "><a href="constants.html"><strong aria-hidden="true">38.4.</strong> Constants in the type system</a></li></ol></li><li class="chapter-item "><a href="type-inference.html"><strong aria-hidden="true">39.</strong> Type inference</a></li><li class="chapter-item "><a href="traits/resolution.html"><strong aria-hidden="true">40.</strong> Trait solving</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="early-late-bound.html"><strong aria-hidden="true">40.1.</strong> Early and Late Bound Parameters</a></li><li class="chapter-item "><a href="traits/hrtb.html"><strong aria-hidden="true">40.2.</strong> Higher-ranked trait bounds</a></li><li class="chapter-item "><a href="traits/caching.html"><strong aria-hidden="true">40.3.</strong> Caching subtleties</a></li><li class="chapter-item "><a href="traits/specialization.html"><strong aria-hidden="true">40.4.</strong> Specialization</a></li><li class="chapter-item "><a href="traits/chalk.html"><strong aria-hidden="true">40.5.</strong> Chalk-based trait solving</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="traits/lowering-to-logic.html"><strong aria-hidden="true">40.5.1.</strong> Lowering to logic</a></li><li class="chapter-item "><a href="traits/goals-and-clauses.html"><strong aria-hidden="true">40.5.2.</strong> Goals and clauses</a></li><li class="chapter-item "><a href="traits/canonical-queries.html"><strong aria-hidden="true">40.5.3.</strong> Canonical queries</a></li></ol></li></ol></li><li class="chapter-item "><a href="type-checking.html"><strong aria-hidden="true">41.</strong> Type checking</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="method-lookup.html"><strong aria-hidden="true">41.1.</strong> Method Lookup</a></li><li class="chapter-item "><a href="variance.html"><strong aria-hidden="true">41.2.</strong> Variance</a></li><li class="chapter-item "><a href="opaque-types-type-alias-impl-trait.html"><strong aria-hidden="true">41.3.</strong> Opaque Types</a></li></ol></li><li class="chapter-item "><a href="pat-exhaustive-checking.html"><strong aria-hidden="true">42.</strong> Pattern and Exhaustiveness Checking</a></li><li class="chapter-item "><a href="mir/dataflow.html"><strong aria-hidden="true">43.</strong> MIR dataflow</a></li><li class="chapter-item "><a href="borrow_check.html"><strong aria-hidden="true">44.</strong> The borrow checker</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="borrow_check/moves_and_initialization.html"><strong aria-hidden="true">44.1.</strong> Tracking moves and initialization</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="borrow_check/moves_and_initialization/move_paths.html"><strong aria-hidden="true">44.1.1.</strong> Move paths</a></li></ol></li><li class="chapter-item "><a href="borrow_check/type_check.html"><strong aria-hidden="true">44.2.</strong> MIR type checker</a></li><li class="chapter-item "><a href="borrow_check/region_inference.html"><strong aria-hidden="true">44.3.</strong> Region inference</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="borrow_check/region_inference/constraint_propagation.html"><strong aria-hidden="true">44.3.1.</strong> Constraint propagation</a></li><li class="chapter-item "><a href="borrow_check/region_inference/lifetime_parameters.html"><strong aria-hidden="true">44.3.2.</strong> Lifetime parameters</a></li><li class="chapter-item "><a href="borrow_check/region_inference/member_constraints.html"><strong aria-hidden="true">44.3.3.</strong> Member constraints</a></li><li class="chapter-item "><a href="borrow_check/region_inference/placeholders_and_universes.html"><strong aria-hidden="true">44.3.4.</strong> Placeholders and universes</a></li><li class="chapter-item "><a href="borrow_check/region_inference/closure_constraints.html"><strong aria-hidden="true">44.3.5.</strong> Closure constraints</a></li><li class="chapter-item "><a href="borrow_check/region_inference/error_reporting.html"><strong aria-hidden="true">44.3.6.</strong> Error reporting</a></li></ol></li><li class="chapter-item "><a href="borrow_check/two_phase_borrows.html"><strong aria-hidden="true">44.4.</strong> Two-phase-borrows</a></li></ol></li><li class="chapter-item "><a href="param_env.html"><strong aria-hidden="true">45.</strong> Parameter Environments</a></li><li class="chapter-item "><a href="diagnostics.html"><strong aria-hidden="true">46.</strong> Errors and Lints</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="diagnostics/sessiondiagnostic.html"><strong aria-hidden="true">46.1.</strong> Creating Errors With SessionDiagnostic</a></li><li class="chapter-item "><a href="diagnostics/lintstore.html"><strong aria-hidden="true">46.2.</strong> LintStore</a></li><li class="chapter-item "><a href="diagnostics/diagnostic-codes.html"><strong aria-hidden="true">46.3.</strong> Diagnostic Codes</a></li><li class="chapter-item "><a href="diagnostics/diagnostic-items.html"><strong aria-hidden="true">46.4.</strong> Diagnostic Items</a></li></ol></li><li class="chapter-item "><li class="part-title">MIR to Binaries</li><li class="chapter-item "><a href="part-5-intro.html"><strong aria-hidden="true">47.</strong> Prologue</a></li><li class="chapter-item "><a href="mir/optimizations.html"><strong aria-hidden="true">48.</strong> MIR optimizations</a></li><li class="chapter-item "><a href="mir/debugging.html"><strong aria-hidden="true">49.</strong> Debugging</a></li><li class="chapter-item "><a href="const-eval.html"><strong aria-hidden="true">50.</strong> Constant evaluation</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="miri.html"><strong aria-hidden="true">50.1.</strong> miri const evaluator</a></li></ol></li><li class="chapter-item "><a href="backend/monomorph.html"><strong aria-hidden="true">51.</strong> Monomorphization</a></li><li class="chapter-item "><a href="backend/lowering-mir.html"><strong aria-hidden="true">52.</strong> Lowering MIR</a></li><li class="chapter-item "><a href="backend/codegen.html"><strong aria-hidden="true">53.</strong> Code Generation</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="backend/updating-llvm.html"><strong aria-hidden="true">53.1.</strong> Updating LLVM</a></li><li class="chapter-item "><a href="backend/debugging.html"><strong aria-hidden="true">53.2.</strong> Debugging LLVM</a></li><li class="chapter-item "><a href="backend/backend-agnostic.html"><strong aria-hidden="true">53.3.</strong> Backend Agnostic Codegen</a></li><li class="chapter-item "><a href="backend/implicit-caller-location.html"><strong aria-hidden="true">53.4.</strong> Implicit Caller Location</a></li></ol></li><li class="chapter-item "><a href="backend/libs-and-metadata.html"><strong aria-hidden="true">54.</strong> Libraries and Metadata</a></li><li class="chapter-item "><a href="profile-guided-optimization.html"><strong aria-hidden="true">55.</strong> Profile-guided Optimization</a></li><li class="chapter-item "><a href="llvm-coverage-instrumentation.html"><strong aria-hidden="true">56.</strong> LLVM Source-Based Code Coverage</a></li><li class="chapter-item "><a href="sanitizers.html"><strong aria-hidden="true">57.</strong> Sanitizers Support</a></li><li class="chapter-item "><a href="debugging-support-in-rustc.html"><strong aria-hidden="true">58.</strong> Debugging Support in the Rust Compiler</a></li><li class="spacer"></li><li class="chapter-item affix "><a href="appendix/background.html">Appendix A: Background topics</a></li><li class="chapter-item affix "><a href="appendix/glossary.html">Appendix B: Glossary</a></li><li class="chapter-item affix "><a href="appendix/code-index.html">Appendix C: Code Index</a></li><li class="chapter-item affix "><a href="appendix/compiler-lecture.html">Appendix D: Compiler Lecture Series</a></li><li class="chapter-item affix "><a href="appendix/bibliography.html">Appendix E: Bibliography</a></li><li class="chapter-item affix "><a href="appendix/humorust.html">Appendix Z: HumorRust</a></li><li class="spacer"></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></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 bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<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="light">Light (default)</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">Guide to Rustc Development</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/tree/master/src/ty.md?mode&#x3D;edit" 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 type="text/javascript">
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="the-ty-module-representing-types"><a class="header" href="#the-ty-module-representing-types">The <code>ty</code> module: representing types</a></h1>
<ul>
<li><a href="#tyty"><code>ty::Ty</code></a></li>
<li><a href="#rustc_hirty-vs-tyty"><code>rustc_hir::Ty</code> vs <code>ty::Ty</code></a></li>
<li><a href="#tyty-implementation"><code>ty::Ty</code> implementation</a></li>
<li><a href="#allocating-and-working-with-types">Allocating and working with types</a></li>
<li><a href="#tytykind-variants"><code>ty::TyKind</code> Variants</a></li>
<li><a href="#import-conventions">Import conventions</a></li>
<li><a href="#adts-representation">ADTs Representation</a></li>
<li><a href="#type-errors">Type errors</a></li>
<li><a href="#question-why-not-substitute-inside-the-adtdef">Question: Why not substitute “inside” the <code>AdtDef</code>?</a></li>
</ul>
<p>The <code>ty</code> module defines how the Rust compiler represents types internally. It also defines the
<em>typing context</em> (<code>tcx</code> or <code>TyCtxt</code>), which is the central data structure in the compiler.</p>
<h2 id="tyty"><a class="header" href="#tyty"><code>ty::Ty</code></a></h2>
<p>When we talk about how rustc represents types, we usually refer to a type called <code>Ty</code> . There are
quite a few modules and types for <code>Ty</code> in the compiler (<a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/index.html">Ty documentation</a>).</p>
<p>The specific <code>Ty</code> we are referring to is <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.Ty.html"><code>rustc_middle::ty::Ty</code></a> (and not
<a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.Ty.html"><code>rustc_hir::Ty</code></a>). The distinction is important, so we will discuss it first before going
into the details of <code>ty::Ty</code>.</p>
<h2 id="rustc_hirty-vs-tyty"><a class="header" href="#rustc_hirty-vs-tyty"><code>rustc_hir::Ty</code> vs <code>ty::Ty</code></a></h2>
<p>The HIR in rustc can be thought of as the high-level intermediate representation. It is more or less
the AST (see <a href="hir.html">this chapter</a>) as it represents the
syntax that the user wrote, and is obtained after parsing and some <em>desugaring</em>. It has a
representation of types, but in reality it reflects more of what the user wrote, that is, what they
wrote so as to represent that type.</p>
<p>In contrast, <code>ty::Ty</code> represents the semantics of a type, that is, the <em>meaning</em> of what the user
wrote. For example, <code>rustc_hir::Ty</code> would record the fact that a user used the name <code>u32</code> twice
in their program, but the <code>ty::Ty</code> would record the fact that both usages refer to the same type.</p>
<p><strong>Example: <code>fn foo(x: u32) → u32 { x }</code></strong> In this function we see that <code>u32</code> appears twice. We know
that that is the same type, i.e. the function takes an argument and returns an argument of the same
type, but from the point of view of the HIR there would be two distinct type instances because these
are occurring in two different places in the program. That is, they have two
different <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html"><code>Span</code>s</a> (locations).</p>
<p><strong>Example: <code>fn foo(x: &amp;u32) -&gt; &amp;u32</code></strong> In addition, HIR might have information left out. This type
<code>&amp;u32</code> is incomplete, since in the full rust type there is actually a lifetime, but we didn’t need
to write those lifetimes. There are also some elision rules that insert information. The result may
look like <code>fn foo&lt;'a&gt;(x: &amp;'a u32) -&gt; &amp;'a u32</code>.</p>
<p>In the HIR level, these things are not spelled out and you can say the picture is rather incomplete.
However, at the <code>ty::Ty</code> level, these details are added and it is complete. Moreover, we will have
exactly one <code>ty::Ty</code> for a given type, like <code>u32</code>, and that <code>ty::Ty</code> is used for all <code>u32</code>s in the
whole program, not a specific usage, unlike <code>rustc_hir::Ty</code>.</p>
<p>Here is a summary:</p>
<table><thead><tr><th><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.Ty.html"><code>rustc_hir::Ty</code></a></th><th><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.Ty.html"><code>ty::Ty</code></a></th></tr></thead><tbody>
<tr><td>Describe the <em>syntax</em> of a type: what the user wrote (with some desugaring).</td><td>Describe the <em>semantics</em> of a type: the meaning of what the user wrote.</td></tr>
<tr><td>Each <code>rustc_hir::Ty</code> has its own spans corresponding to the appropriate place in the program.</td><td>Doesn’t correspond to a single place in the user’s program.</td></tr>
<tr><td><code>rustc_hir::Ty</code> has generics and lifetimes; however, some of those lifetimes are special markers like <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/enum.LifetimeName.html#variant.Implicit"><code>LifetimeName::Implicit</code></a>.</td><td><code>ty::Ty</code> has the full type, including generics and lifetimes, even if the user left them out</td></tr>
<tr><td><code>fn foo(x: u32) → u32 { }</code> - Two <code>rustc_hir::Ty</code> representing each usage of <code>u32</code>. Each has its own <code>Span</code>s, etc.- <code>rustc_hir::Ty</code> doesn’t tell us that both are the same type</td><td><code>fn foo(x: u32) → u32 { }</code> - One <code>ty::Ty</code> for all instances of <code>u32</code> throughout the program.- <code>ty::Ty</code> tells us that both usages of <code>u32</code> mean the same type.</td></tr>
<tr><td><code>fn foo(x: &amp;u32) -&gt; &amp;u32)</code>- Two <code>rustc_hir::Ty</code> again.- Lifetimes for the references show up in the <code>rustc_hir::Ty</code>s using a special marker, <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/enum.LifetimeName.html#variant.Implicit"><code>LifetimeName::Implicit</code></a>.</td><td><code>fn foo(x: &amp;u32) -&gt; &amp;u32)</code>- A single <code>ty::Ty</code>.- The <code>ty::Ty</code> has the hidden lifetime param</td></tr>
</tbody></table>
<p><strong>Order</strong> HIR is built directly from the AST, so it happens before any <code>ty::Ty</code> is produced. After
HIR is built, some basic type inference and type checking is done. During the type inference, we
figure out what the <code>ty::Ty</code> of everything is and we also check if the type of something is
ambiguous. The <code>ty::Ty</code> then, is used for type checking while making sure everything has the
expected type. The <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/astconv/index.html"><code>astconv</code> module</a> is where the code responsible for converting a
<code>rustc_hir::Ty</code> into a <code>ty::Ty</code> is located. This occurs during the type-checking phase,
but also in other parts of the compiler that want to ask questions like &quot;what argument types does
this function expect?&quot;</p>
<p><strong>How semantics drive the two instances of <code>Ty</code></strong> You can think of HIR as the perspective
of the type information that assumes the least. We assume two things are distinct until they are
proven to be the same thing. In other words, we know less about them, so we should assume less about
them.</p>
<p>They are syntactically two strings: <code>&quot;u32&quot;</code> at line N column 20 and <code>&quot;u32&quot;</code> at line N column 35. We
don’t know that they are the same yet. So, in the HIR we treat them as if they are different. Later,
we determine that they semantically are the same type and that’s the <code>ty::Ty</code> we use.</p>
<p>Consider another example: <code>fn foo&lt;T&gt;(x: T) -&gt; u32</code>. Suppose that someone invokes <code>foo::&lt;u32&gt;(0)</code>.
This means that <code>T</code> and <code>u32</code> (in this invocation) actually turns out to be the same type, so we
would eventually end up with the same <code>ty::Ty</code> in the end, but we have distinct <code>rustc_hir::Ty</code>.
(This is a bit over-simplified, though, since during type checking, we would check the function
generically and would still have a <code>T</code> distinct from <code>u32</code>. Later, when doing code generation,
we would always be handling &quot;monomorphized&quot; (fully substituted) versions of each function,
and hence we would know what <code>T</code> represents (and specifically that it is <code>u32</code>).)</p>
<p>Here is one more example:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>mod a {
type X = u32;
pub fn foo(x: X) -&gt; u32 { 22 }
}
mod b {
type X = i32;
pub fn foo(x: X) -&gt; i32 { x }
}
<span class="boring">}
</span></code></pre></pre>
<p>Here the type <code>X</code> will vary depending on context, clearly. If you look at the <code>rustc_hir::Ty</code>,
you will get back that <code>X</code> is an alias in both cases (though it will be mapped via name resolution
to distinct aliases). But if you look at the <code>ty::Ty</code> signature, it will be either <code>fn(u32) -&gt; u32</code>
or <code>fn(i32) -&gt; i32</code> (with type aliases fully expanded).</p>
<h2 id="tyty-implementation"><a class="header" href="#tyty-implementation"><code>ty::Ty</code> implementation</a></h2>
<p><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.Ty.html"><code>rustc_middle::ty::Ty</code></a> is actually a type alias to <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html"><code>&amp;TyS</code></a>.
This type, which is short for &quot;Type Structure&quot;, is where the main functionality is located.
You can ignore <code>TyS</code> struct in general; you will basically never access it explicitly.
We always pass it by reference using the <code>Ty</code> alias.
The only exception is to define inherent methods on types. In particular, <code>TyS</code> has a <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#structfield.kind"><code>kind</code></a>
field of type <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html"><code>TyKind</code></a>, which represents the key type information. <code>TyKind</code> is a big enum
with variants to represent many different Rust types
(e.g. primitives, references, abstract data types, generics, lifetimes, etc).
<code>TyS</code> also has 2 more fields, <code>flags</code> and <code>outer_exclusive_binder</code>. They
are convenient hacks for efficiency and summarize information about the type that we may want to
know, but they don’t come into the picture as much here. Finally, <code>ty::TyS</code>s
are <a href="./memory.html">interned</a>, so that the <code>ty::Ty</code> can be a thin pointer-like
type. This allows us to do cheap comparisons for equality, along with the other
benefits of interning.</p>
<h2 id="allocating-and-working-with-types"><a class="header" href="#allocating-and-working-with-types">Allocating and working with types</a></h2>
<p>To allocate a new type, you can use the various <code>mk_</code> methods defined on the <code>tcx</code>. These have names
that correspond mostly to the various kinds of types. For example:</p>
<pre><code class="language-rust ignore">let array_ty = tcx.mk_array(elem_ty, len * 2);
</code></pre>
<p>These methods all return a <code>Ty&lt;'tcx&gt;</code> – note that the lifetime you get back is the lifetime of the
arena that this <code>tcx</code> has access to. Types are always canonicalized and interned (so we never
allocate exactly the same type twice).</p>
<blockquote>
<p>N.B.
Because types are interned, it is possible to compare them for equality efficiently using <code>==</code>
– however, this is almost never what you want to do unless you happen to be hashing and looking
for duplicates. This is because often in Rust there are multiple ways to represent the same type,
particularly once inference is involved. If you are going to be testing for type equality, you
probably need to start looking into the inference code to do it right.</p>
</blockquote>
<p>You can also find various common types in the <code>tcx</code> itself by accessing its fields:
<code>tcx.types.bool</code>, <code>tcx.types.char</code>, etc. (See <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.CommonTypes.html"><code>CommonTypes</code></a> for more.)</p>
<h2 id="tytykind-variants"><a class="header" href="#tytykind-variants"><code>ty::TyKind</code> Variants</a></h2>
<p>Note: <code>TyKind</code> is <strong>NOT</strong> the functional programming concept of <em>Kind</em>.</p>
<p>Whenever working with a <code>Ty</code> in the compiler, it is common to match on the kind of type:</p>
<pre><code class="language-rust ignore">fn foo(x: Ty&lt;'tcx&gt;) {
match x.kind {
...
}
}
</code></pre>
<p>The <code>kind</code> field is of type <code>TyKind&lt;'tcx&gt;</code>, which is an enum defining all of the different kinds of
types in the compiler.</p>
<blockquote>
<p>N.B. inspecting the <code>kind</code> field on types during type inference can be risky, as there may be
inference variables and other things to consider, or sometimes types are not yet known and will
become known later.</p>
</blockquote>
<p>There are a lot of related types, and we’ll cover them in time (e.g regions/lifetimes,
“substitutions”, etc).</p>
<p>There are many variants on the <code>TyKind</code> enum, which you can see by looking at its
<a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html">documentation</a>. Here is a sampling:</p>
<ul>
<li><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Adt"><strong>Algebraic Data Types (ADTs)</strong></a> An <a href="https://en.wikipedia.org/wiki/Algebraic_data_type"><em>algebraic data type</em></a> is a <code>struct</code>,
<code>enum</code> or <code>union</code>. Under the hood, <code>struct</code>, <code>enum</code> and <code>union</code> are actually implemented
the same way: they are all <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Adt"><code>ty::TyKind::Adt</code></a>. It’s basically a user defined type.
We will talk more about these later.</li>
<li><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Foreign"><strong>Foreign</strong></a> Corresponds to <code>extern type T</code>.</li>
<li><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Str"><strong>Str</strong></a> Is the type str. When the user writes <code>&amp;str</code>, <code>Str</code> is the how we represent the
<code>str</code> part of that type.</li>
<li><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Slice"><strong>Slice</strong></a> Corresponds to <code>[T]</code>.</li>
<li><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Array"><strong>Array</strong></a> Corresponds to <code>[T; n]</code>.</li>
<li><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.RawPtr"><strong>RawPtr</strong></a> Corresponds to <code>*mut T</code> or <code>*const T</code>.</li>
<li><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Ref"><strong>Ref</strong></a> <code>Ref</code> stands for safe references, <code>&amp;'a mut T</code> or <code>&amp;'a T</code>. <code>Ref</code> has some
associated parts, like <code>Ty&lt;'tcx&gt;</code> which is the type that the reference references.
<code>Region&lt;'tcx&gt;</code> is the lifetime or region of the reference and <code>Mutability</code> if the reference
is mutable or not.</li>
<li><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Param"><strong>Param</strong></a> Represents a type parameter (e.g. the <code>T</code> in <code>Vec&lt;T&gt;</code>).</li>
<li><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Error"><strong>Error</strong></a> Represents a type error somewhere so that we can print better diagnostics. We
will discuss this more later.</li>
<li><a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variants"><strong>And many more</strong>...</a></li>
</ul>
<h2 id="import-conventions"><a class="header" href="#import-conventions">Import conventions</a></h2>
<p>Although there is no hard and fast rule, the <code>ty</code> module tends to be used like so:</p>
<pre><code class="language-rust ignore">use ty::{self, Ty, TyCtxt};
</code></pre>
<p>In particular, since they are so common, the <code>Ty</code> and <code>TyCtxt</code> types are imported directly. Other
types are often referenced with an explicit <code>ty::</code> prefix (e.g. <code>ty::TraitRef&lt;'tcx&gt;</code>). But some
modules choose to import a larger or smaller set of names explicitly.</p>
<h2 id="adts-representation"><a class="header" href="#adts-representation">ADTs Representation</a></h2>
<p>Let's consider the example of a type like <code>MyStruct&lt;u32&gt;</code>, where <code>MyStruct</code> is defined like so:</p>
<pre><code class="language-rust ignore">struct MyStruct&lt;T&gt; { x: u32, y: T }
</code></pre>
<p>The type <code>MyStruct&lt;u32&gt;</code> would be an instance of <code>TyKind::Adt</code>:</p>
<pre><code class="language-rust ignore">Adt(&amp;'tcx AdtDef, SubstsRef&lt;'tcx&gt;)
// ------------ ---------------
// (1) (2)
//
// (1) represents the `MyStruct` part
// (2) represents the `&lt;u32&gt;`, or &quot;substitutions&quot; / generic arguments
</code></pre>
<p>There are two parts:</p>
<ul>
<li>The <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.AdtDef.html"><code>AdtDef</code></a> references the struct/enum/union but without the values for its type
parameters. In our example, this is the <code>MyStruct</code> part <em>without</em> the argument <code>u32</code>.
(Note that in the HIR, structs, enums and unions are represented differently, but in <code>ty::Ty</code>,
they are all represented using <code>TyKind::Adt</code>.)</li>
<li>The <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/subst/type.SubstsRef.html"><code>SubstsRef</code></a> is an interned list of values that are to be substituted for the
generic parameters. In our example of <code>MyStruct&lt;u32&gt;</code>, we would end up with a list like <code>[u32]</code>.
We’ll dig more into generics and substitutions in a little bit.</li>
</ul>
<p><strong><code>AdtDef</code> and <code>DefId</code></strong></p>
<p>For every type defined in the source code, there is a unique <code>DefId</code> (see <a href="hir.html#identifiers-in-the-hir">this
chapter</a>). This includes ADTs and generics. In the <code>MyStruct&lt;T&gt;</code>
definition we gave above, there are two <code>DefId</code>s: one for <code>MyStruct</code> and one for <code>T</code>. Notice that
the code above does not generate a new <code>DefId</code> for <code>u32</code> because it is not defined in that code (it
is only referenced).</p>
<p><code>AdtDef</code> is more or less a wrapper around <code>DefId</code> with lots of useful helper methods. There is
essentially a one-to-one relationship between <code>AdtDef</code> and <code>DefId</code>. You can get the <code>AdtDef</code> for a
<code>DefId</code> with the <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.adt_def"><code>tcx.adt_def(def_id)</code> query</a>. <code>AdtDef</code>s are all interned, as shown
by the <code>'tcx</code> lifetime.</p>
<h2 id="type-errors"><a class="header" href="#type-errors">Type errors</a></h2>
<p>There is a <code>TyKind::Error</code> that is produced when the user makes a type error. The idea is that
we would propagate this type and suppress other errors that come up due to it so as not to overwhelm
the user with cascading compiler error messages.</p>
<p>There is an <strong>important invariant</strong> for <code>TyKind::Error</code>. The compiler should
<strong>never</strong> produce <code>Error</code> unless we <strong>know</strong> that an error has already been
reported to the user. This is usually
because (a) you just reported it right there or (b) you are propagating an existing Error type (in
which case the error should've been reported when that error type was produced).</p>
<p>It's important to maintain this invariant because the whole point of the <code>Error</code> type is to suppress
other errors -- i.e., we don't report them. If we were to produce an <code>Error</code> type without actually
emitting an error to the user, then this could cause later errors to be suppressed, and the
compilation might inadvertently succeed!</p>
<p>Sometimes there is a third case. You believe that an error has been reported, but you believe it
would've been reported earlier in the compilation, not locally. In that case, you can invoke
<a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html#method.delay_span_bug"><code>delay_span_bug</code></a> This will make a note that you expect compilation to yield an error -- if however
compilation should succeed, then it will trigger a compiler bug report.</p>
<p>For added safety, it's not actually possible to produce a <code>TyKind::Error</code> value
outside of <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/index.html"><code>rustc_middle::ty</code></a>; there is a private member of
<code>TyKind::Error</code> that prevents it from being constructable elsewhere. Instead,
one should use the <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.ty_error"><code>TyCtxt::ty_error</code></a> or
<a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.ty_error_with_message"><code>TyCtxt::ty_error_with_message</code></a> methods. These methods automatically
call <code>delay_span_bug</code> before returning an interned <code>Ty</code> of kind <code>Error</code>. If you
were already planning to use <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html#method.delay_span_bug"><code>delay_span_bug</code></a>, then you can just pass the
span and message to <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.ty_error_with_message"><code>ty_error_with_message</code></a> instead to avoid
delaying a redundant span bug.</p>
<h2 id="question-why-not-substitute-inside-the-adtdef"><a class="header" href="#question-why-not-substitute-inside-the-adtdef">Question: Why not substitute “inside” the <code>AdtDef</code>?</a></h2>
<p>Recall that we represent a generic struct with <code>(AdtDef, substs)</code>. So why bother with this scheme?</p>
<p>Well, the alternate way we could have chosen to represent types would be to always create a new,
fully-substituted form of the <code>AdtDef</code> where all the types are already substituted. This seems like
less of a hassle. However, the <code>(AdtDef, substs)</code> scheme has some advantages over this.</p>
<p>First, <code>(AdtDef, substs)</code> scheme has an efficiency win:</p>
<pre><code class="language-rust ignore">struct MyStruct&lt;T&gt; {
... 100s of fields ...
}
// Want to do: MyStruct&lt;A&gt; ==&gt; MyStruct&lt;B&gt;
</code></pre>
<p>in an example like this, we can subst from <code>MyStruct&lt;A&gt;</code> to <code>MyStruct&lt;B&gt;</code> (and so on) very cheaply,
by just replacing the one reference to <code>A</code> with <code>B</code>. But if we eagerly substituted all the fields,
that could be a lot more work because we might have to go through all of the fields in the <code>AdtDef</code>
and update all of their types.</p>
<p>A bit more deeply, this corresponds to structs in Rust being <a href="https://en.wikipedia.org/wiki/Nominal_type_system"><em>nominal</em> types</a> — which
means that they are defined by their <em>name</em> (and that their contents are then indexed from the
definition of that name, and not carried along “within” the type itself).</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="part-4-intro.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" href="generics.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="part-4-intro.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" href="generics.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 type="text/javascript">
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>