| // Populate the sidebar |
| // |
| // This is a script, and not included directly in the page, to control the total size of the book. |
| // The TOC contains an entry for each page, so if each page includes a copy of the TOC, |
| // the total size of the page becomes O(n**2). |
| class MDBookSidebarScrollbox extends HTMLElement { |
| constructor() { |
| super(); |
| } |
| connectedCallback() { |
| this.innerHTML = '<ol class="chapter"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="getting-started.html">Getting Started</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="about-this-guide.html">About this guide</a></span></li><li class="chapter-item "><li class="spacer"></li></li><li class="chapter-item "><li class="part-title">Building and debugging rustc</li></li><li class="chapter-item "><span class="chapter-link-wrapper"><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="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/quickstart.html"><strong aria-hidden="true">1.1.</strong> Quickstart</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/prerequisites.html"><strong aria-hidden="true">1.2.</strong> Prerequisites</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/suggested.html"><strong aria-hidden="true">1.3.</strong> Suggested workflows</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/build-install-distribution-artifacts.html"><strong aria-hidden="true">1.4.</strong> Distribution artifacts</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/compiler-documenting.html"><strong aria-hidden="true">1.5.</strong> Building documentation</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustdoc.html"><strong aria-hidden="true">1.6.</strong> Rustdoc overview</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/new-target.html"><strong aria-hidden="true">1.7.</strong> Adding a new target</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/optimized-build.html"><strong aria-hidden="true">1.8.</strong> Optimized build</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/intro.html"><strong aria-hidden="true">2.</strong> Testing the compiler</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/running.html"><strong aria-hidden="true">2.1.</strong> Running tests</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/docker.html"><strong aria-hidden="true">2.1.1.</strong> Testing with Docker</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/ci.html"><strong aria-hidden="true">2.1.2.</strong> Testing with CI</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/adding.html"><strong aria-hidden="true">2.2.</strong> Adding new tests</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/best-practices.html"><strong aria-hidden="true">2.3.</strong> Best practices</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/compiletest.html"><strong aria-hidden="true">2.4.</strong> Compiletest</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/ui.html"><strong aria-hidden="true">2.4.1.</strong> UI tests</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/directives.html"><strong aria-hidden="true">2.4.2.</strong> Test directives</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/minicore.html"><strong aria-hidden="true">2.4.3.</strong> Minicore</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/ecosystem.html"><strong aria-hidden="true">2.5.</strong> Ecosystem testing</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/crater.html"><strong aria-hidden="true">2.5.1.</strong> Crater</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/ecosystem-test-jobs/fuchsia.html"><strong aria-hidden="true">2.5.2.</strong> Fuchsia</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/ecosystem-test-jobs/rust-for-linux.html"><strong aria-hidden="true">2.5.3.</strong> Rust for Linux</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/codegen-backend-tests/intro.html"><strong aria-hidden="true">2.6.</strong> Codegen backend testing</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/codegen-backend-tests/cg_clif.html"><strong aria-hidden="true">2.6.1.</strong> Cranelift codegen backend</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/codegen-backend-tests/cg_gcc.html"><strong aria-hidden="true">2.6.2.</strong> GCC codegen backend</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/perf.html"><strong aria-hidden="true">2.7.</strong> Performance testing</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tests/misc.html"><strong aria-hidden="true">2.8.</strong> Misc info</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="compiler-debugging.html"><strong aria-hidden="true">3.</strong> Debugging the compiler</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="tracing.html"><strong aria-hidden="true">3.1.</strong> Using the tracing/logging instrumentation</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="profiling.html"><strong aria-hidden="true">4.</strong> Profiling the compiler</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="profiling/with-perf.html"><strong aria-hidden="true">4.1.</strong> with the linux perf tool</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="profiling/wpa-profiling.html"><strong aria-hidden="true">4.2.</strong> with Windows Performance Analyzer</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="profiling/with-rustc-perf.html"><strong aria-hidden="true">4.3.</strong> with the Rust benchmark suite</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="crates-io.html"><strong aria-hidden="true">5.</strong> crates.io dependencies</a></span></li><li class="chapter-item "><li class="part-title">Contributing to Rust</li></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="contributing.html"><strong aria-hidden="true">6.</strong> Contribution procedures</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="compiler-team.html"><strong aria-hidden="true">7.</strong> About the compiler team</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="git.html"><strong aria-hidden="true">8.</strong> Using Git</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustbot.html"><strong aria-hidden="true">9.</strong> Mastering @rustbot</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="walkthrough.html"><strong aria-hidden="true">10.</strong> Walkthrough: a typical contribution</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="implementing-new-features.html"><strong aria-hidden="true">11.</strong> Implementing new language features</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="stability-guarantees.html"><strong aria-hidden="true">12.</strong> Stability guarantees</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="stability.html"><strong aria-hidden="true">13.</strong> Stability attributes</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="stabilization-guide.html"><strong aria-hidden="true">14.</strong> Stabilizing language features</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="stabilization-report-template.html"><strong aria-hidden="true">14.1.</strong> Stabilization report template</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="feature-gates.html"><strong aria-hidden="true">15.</strong> Feature Gates</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="conventions.html"><strong aria-hidden="true">16.</strong> Coding conventions</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="bug-fix-procedure.html"><strong aria-hidden="true">17.</strong> Procedures for breaking changes</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="external-repos.html"><strong aria-hidden="true">18.</strong> Using external repositories</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="fuzzing.html"><strong aria-hidden="true">19.</strong> Fuzzing</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/about.html"><strong aria-hidden="true">20.</strong> Notification groups</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/apple.html"><strong aria-hidden="true">20.1.</strong> Apple</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/arm.html"><strong aria-hidden="true">20.2.</strong> ARM</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/emscripten.html"><strong aria-hidden="true">20.3.</strong> Emscripten</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/fuchsia.html"><strong aria-hidden="true">20.4.</strong> Fuchsia</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/loongarch.html"><strong aria-hidden="true">20.5.</strong> LoongArch</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/risc-v.html"><strong aria-hidden="true">20.6.</strong> RISC-V</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/rust-for-linux.html"><strong aria-hidden="true">20.7.</strong> Rust for Linux</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/wasi.html"><strong aria-hidden="true">20.8.</strong> WASI</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/wasm.html"><strong aria-hidden="true">20.9.</strong> WebAssembly</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/windows.html"><strong aria-hidden="true">20.10.</strong> Windows</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="notification-groups/gpu-target.html"><strong aria-hidden="true">20.11.</strong> GPU target</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="licenses.html"><strong aria-hidden="true">21.</strong> Licenses</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="guides/editions.html"><strong aria-hidden="true">22.</strong> Editions</a></span></li><li class="chapter-item "><li class="part-title">Bootstrapping</li></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/bootstrapping/intro.html"><strong aria-hidden="true">23.</strong> Prologue</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/bootstrapping/what-bootstrapping-does.html"><strong aria-hidden="true">24.</strong> What Bootstrapping does</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/bootstrapping/how-bootstrap-does-it.html"><strong aria-hidden="true">25.</strong> How Bootstrap does it</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/bootstrapping/writing-tools-in-bootstrap.html"><strong aria-hidden="true">26.</strong> Writing tools in Bootstrap</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/bootstrapping/debugging-bootstrap.html"><strong aria-hidden="true">27.</strong> Debugging bootstrap</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="building/bootstrapping/bootstrap-in-dependencies.html"><strong aria-hidden="true">28.</strong> cfg(bootstrap) in dependencies</a></span></li><li class="chapter-item "><li class="part-title">High-level Compiler Architecture</li></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="part-2-intro.html"><strong aria-hidden="true">29.</strong> Prologue</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="overview.html"><strong aria-hidden="true">30.</strong> Overview of the compiler</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="compiler-src.html"><strong aria-hidden="true">31.</strong> The compiler source code</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="query.html"><strong aria-hidden="true">32.</strong> Queries: demand-driven compilation</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="queries/query-evaluation-model-in-detail.html"><strong aria-hidden="true">32.1.</strong> The Query Evaluation Model in detail</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="queries/incremental-compilation.html"><strong aria-hidden="true">32.2.</strong> Incremental compilation</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="queries/incremental-compilation-in-detail.html"><strong aria-hidden="true">32.3.</strong> Incremental compilation in detail</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="incrcomp-debugging.html"><strong aria-hidden="true">32.4.</strong> Debugging and testing</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="queries/salsa.html"><strong aria-hidden="true">32.5.</strong> Salsa</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="memory.html"><strong aria-hidden="true">33.</strong> Memory management in rustc</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="serialization.html"><strong aria-hidden="true">34.</strong> Serialization in rustc</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="parallel-rustc.html"><strong aria-hidden="true">35.</strong> Parallel compilation</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustdoc-internals.html"><strong aria-hidden="true">36.</strong> Rustdoc internals</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustdoc-internals/search.html"><strong aria-hidden="true">36.1.</strong> Search</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustdoc-internals/rustdoc-html-test-suite.html"><strong aria-hidden="true">36.2.</strong> The rustdoc-html test suite</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustdoc-internals/rustdoc-gui-test-suite.html"><strong aria-hidden="true">36.3.</strong> The rustdoc-gui test suite</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustdoc-internals/rustdoc-json-test-suite.html"><strong aria-hidden="true">36.4.</strong> The rustdoc-json test suite</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="offload/internals.html"><strong aria-hidden="true">37.</strong> GPU offload internals</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="offload/installation.html"><strong aria-hidden="true">37.1.</strong> Installation</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="offload/usage.html"><strong aria-hidden="true">37.2.</strong> Usage</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="offload/contributing.html"><strong aria-hidden="true">37.3.</strong> Contributing</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="autodiff/internals.html"><strong aria-hidden="true">38.</strong> Autodiff internals</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="autodiff/installation.html"><strong aria-hidden="true">38.1.</strong> Installation</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="autodiff/debugging.html"><strong aria-hidden="true">38.2.</strong> How to debug</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="autodiff/flags.html"><strong aria-hidden="true">38.3.</strong> Autodiff flags</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="autodiff/type-trees.html"><strong aria-hidden="true">38.4.</strong> Type Trees</a></span></li></ol><li class="chapter-item "><li class="part-title">Source Code Representation</li></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="part-3-intro.html"><strong aria-hidden="true">39.</strong> Prologue</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="syntax-intro.html"><strong aria-hidden="true">40.</strong> Syntax and the AST</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="the-parser.html"><strong aria-hidden="true">40.1.</strong> Lexing and parsing</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="macro-expansion.html"><strong aria-hidden="true">40.2.</strong> Macro expansion</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="name-resolution.html"><strong aria-hidden="true">40.3.</strong> Name resolution</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="attributes.html"><strong aria-hidden="true">40.4.</strong> Attributes</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="test-implementation.html"><strong aria-hidden="true">40.5.</strong> #[test] implementation</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="panic-implementation.html"><strong aria-hidden="true">40.6.</strong> Panic implementation</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="ast-validation.html"><strong aria-hidden="true">40.7.</strong> AST validation</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="feature-gate-check.html"><strong aria-hidden="true">40.8.</strong> Feature gate checking</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="lang-items.html"><strong aria-hidden="true">40.9.</strong> Lang Items</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="hir.html"><strong aria-hidden="true">41.</strong> The HIR (High-level IR)</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="hir/lowering.html"><strong aria-hidden="true">41.1.</strong> Lowering AST to HIR</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="hir/attribute-parsing.html"><strong aria-hidden="true">41.2.</strong> Attribute Parsing</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="hir/debugging.html"><strong aria-hidden="true">41.3.</strong> Debugging</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="ambig-unambig-ty-and-consts.html"><strong aria-hidden="true">42.</strong> Ambig/Unambig Types and Consts</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="thir.html"><strong aria-hidden="true">43.</strong> The THIR (Typed High-level IR)</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="mir/index.html"><strong aria-hidden="true">44.</strong> The MIR (Mid-level IR)</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="mir/construction.html"><strong aria-hidden="true">44.1.</strong> MIR construction</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="mir/visitor.html"><strong aria-hidden="true">44.2.</strong> MIR visitor and traversal</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="mir/passes.html"><strong aria-hidden="true">44.3.</strong> MIR queries and passes: getting the MIR</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="asm.html"><strong aria-hidden="true">45.</strong> Inline assembly</a></span></li><li class="chapter-item "><li class="part-title">Supporting Infrastructure</li></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="cli.html"><strong aria-hidden="true">46.</strong> Command-line arguments</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustc-driver/intro.html"><strong aria-hidden="true">47.</strong> rustc_driver and rustc_interface</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustc-driver/external-rustc-drivers.html"><strong aria-hidden="true">47.1.</strong> External rustc_drivers</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustc-driver/interacting-with-the-ast.html"><strong aria-hidden="true">47.2.</strong> Example: Type checking</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="rustc-driver/getting-diagnostics.html"><strong aria-hidden="true">47.3.</strong> Example: Getting diagnostics</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="diagnostics.html"><strong aria-hidden="true">48.</strong> Errors and lints</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="diagnostics/diagnostic-structs.html"><strong aria-hidden="true">48.1.</strong> Diagnostic and subdiagnostic structs</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="diagnostics/translation.html"><strong aria-hidden="true">48.2.</strong> Translation</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="diagnostics/lintstore.html"><strong aria-hidden="true">48.3.</strong> LintStore</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="diagnostics/error-codes.html"><strong aria-hidden="true">48.4.</strong> Error codes</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="diagnostics/diagnostic-items.html"><strong aria-hidden="true">48.5.</strong> Diagnostic items</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="diagnostics/error-guaranteed.html"><strong aria-hidden="true">48.6.</strong> ErrorGuaranteed</a></span></li></ol><li class="chapter-item "><li class="part-title">Analysis</li></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="part-4-intro.html"><strong aria-hidden="true">49.</strong> Prologue</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="generic-parameters-summary.html"><strong aria-hidden="true">50.</strong> Generic parameter definitions</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="ty-module/early-binder.html"><strong aria-hidden="true">50.1.</strong> EarlyBinder and instantiating parameters</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="ty-module/binders.html"><strong aria-hidden="true">51.</strong> Binders and Higher ranked regions</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="ty-module/instantiating-binders.html"><strong aria-hidden="true">51.1.</strong> Instantiating binders</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="early-late-parameters.html"><strong aria-hidden="true">52.</strong> Early vs Late bound parameters</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="ty.html"><strong aria-hidden="true">53.</strong> The ty module: representing types</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="ty-module/generic-arguments.html"><strong aria-hidden="true">53.1.</strong> ADTs and Generic Arguments</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="ty-module/param-ty-const-regions.html"><strong aria-hidden="true">53.2.</strong> Parameter types/consts/regions</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="ty-fold.html"><strong aria-hidden="true">54.</strong> TypeFolder and TypeFoldable</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="normalization.html"><strong aria-hidden="true">55.</strong> Aliases and Normalization</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="typing-parameter-envs.html"><strong aria-hidden="true">56.</strong> Typing/Param Envs</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="type-inference.html"><strong aria-hidden="true">57.</strong> Type inference</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/resolution.html"><strong aria-hidden="true">58.</strong> Trait solving</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/hrtb.html"><strong aria-hidden="true">58.1.</strong> Higher-ranked trait bounds</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/caching.html"><strong aria-hidden="true">58.2.</strong> Caching subtleties</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/implied-bounds.html"><strong aria-hidden="true">58.3.</strong> Implied bounds</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/specialization.html"><strong aria-hidden="true">58.4.</strong> Specialization</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/chalk.html"><strong aria-hidden="true">58.5.</strong> Chalk-based trait solving</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/lowering-to-logic.html"><strong aria-hidden="true">58.5.1.</strong> Lowering to logic</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/goals-and-clauses.html"><strong aria-hidden="true">58.5.2.</strong> Goals and clauses</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/canonical-queries.html"><strong aria-hidden="true">58.5.3.</strong> Canonical queries</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/canonicalization.html"><strong aria-hidden="true">58.5.4.</strong> Canonicalization</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/trait-solving.html"><strong aria-hidden="true">58.6.</strong> Next-gen trait solving</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/invariants.html"><strong aria-hidden="true">58.6.1.</strong> Invariants of the type system</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/the-solver.html"><strong aria-hidden="true">58.6.2.</strong> The solver</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/candidate-preference.html"><strong aria-hidden="true">58.6.3.</strong> Candidate preference</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/canonicalization.html"><strong aria-hidden="true">58.6.4.</strong> Canonicalization</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/coinduction.html"><strong aria-hidden="true">58.6.5.</strong> Coinduction</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/caching.html"><strong aria-hidden="true">58.6.6.</strong> Caching</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/proof-trees.html"><strong aria-hidden="true">58.6.7.</strong> Proof trees</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/opaque-types.html"><strong aria-hidden="true">58.6.8.</strong> Opaque types</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/significant-changes.html"><strong aria-hidden="true">58.6.9.</strong> Significant changes and quirks</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="solve/sharing-crates-with-rust-analyzer.html"><strong aria-hidden="true">58.6.10.</strong> Sharing the trait solver with rust-analyzer</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/unsize.html"><strong aria-hidden="true">58.7.</strong> Unsize and CoerceUnsized traits</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="traits/separate-projection-bounds.html"><strong aria-hidden="true">58.8.</strong> Having separate Trait and Projection bounds</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="variance.html"><strong aria-hidden="true">59.</strong> Variance</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="coherence.html"><strong aria-hidden="true">60.</strong> Coherence checking</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="hir-typeck/summary.html"><strong aria-hidden="true">61.</strong> HIR Type checking</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="hir-typeck/coercions.html"><strong aria-hidden="true">61.1.</strong> Coercions</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="hir-typeck/method-lookup.html"><strong aria-hidden="true">61.2.</strong> Method lookup</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="const-generics.html"><strong aria-hidden="true">62.</strong> Const Generics</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="opaque-types-type-alias-impl-trait.html"><strong aria-hidden="true">63.</strong> Opaque types</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="opaque-types-impl-trait-inference.html"><strong aria-hidden="true">63.1.</strong> Inference details</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="return-position-impl-trait-in-trait.html"><strong aria-hidden="true">63.2.</strong> Return Position Impl Trait In Trait</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/opaque-types-region-inference-restrictions.html"><strong aria-hidden="true">63.3.</strong> Region inference restrictions</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="effects.html"><strong aria-hidden="true">64.</strong> Const traits and const condition checking</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="pat-exhaustive-checking.html"><strong aria-hidden="true">65.</strong> Pattern and exhaustiveness checking</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="unsafety-checking.html"><strong aria-hidden="true">66.</strong> Unsafety checking</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="mir/dataflow.html"><strong aria-hidden="true">67.</strong> MIR dataflow</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="mir/drop-elaboration.html"><strong aria-hidden="true">68.</strong> Drop elaboration</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check.html"><strong aria-hidden="true">69.</strong> The borrow checker</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/moves-and-initialization.html"><strong aria-hidden="true">69.1.</strong> Tracking moves and initialization</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/moves-and-initialization/move-paths.html"><strong aria-hidden="true">69.1.1.</strong> Move paths</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/type-check.html"><strong aria-hidden="true">69.2.</strong> MIR type checker</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/drop-check.html"><strong aria-hidden="true">69.3.</strong> Drop check</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/region-inference.html"><strong aria-hidden="true">69.4.</strong> Region inference</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/region-inference/constraint-propagation.html"><strong aria-hidden="true">69.4.1.</strong> Constraint propagation</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/region-inference/lifetime-parameters.html"><strong aria-hidden="true">69.4.2.</strong> Lifetime parameters</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/region-inference/member-constraints.html"><strong aria-hidden="true">69.4.3.</strong> Member constraints</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/region-inference/placeholders-and-universes.html"><strong aria-hidden="true">69.4.4.</strong> Placeholders and universes</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/region-inference/closure-constraints.html"><strong aria-hidden="true">69.4.5.</strong> Closure constraints</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/region-inference/error-reporting.html"><strong aria-hidden="true">69.4.6.</strong> Error reporting</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="borrow-check/two-phase-borrows.html"><strong aria-hidden="true">69.5.</strong> Two-phase-borrows</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="closure.html"><strong aria-hidden="true">70.</strong> Closure capture inference</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="coroutine-closures.html"><strong aria-hidden="true">71.</strong> Async closures/"coroutine-closures"</a></span></li><li class="chapter-item "><li class="part-title">MIR to binaries</li></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="part-5-intro.html"><strong aria-hidden="true">72.</strong> Prologue</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="mir/optimizations.html"><strong aria-hidden="true">73.</strong> MIR optimizations</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="mir/debugging.html"><strong aria-hidden="true">74.</strong> Debugging MIR</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="const-eval.html"><strong aria-hidden="true">75.</strong> Constant evaluation</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="const-eval/interpret.html"><strong aria-hidden="true">75.1.</strong> Interpreter</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="backend/monomorph.html"><strong aria-hidden="true">76.</strong> Monomorphization</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="backend/lowering-mir.html"><strong aria-hidden="true">77.</strong> Lowering MIR</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="backend/codegen.html"><strong aria-hidden="true">78.</strong> Code generation</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="backend/updating-llvm.html"><strong aria-hidden="true">78.1.</strong> Updating LLVM</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="backend/debugging.html"><strong aria-hidden="true">78.2.</strong> Debugging LLVM</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="backend/backend-agnostic.html"><strong aria-hidden="true">78.3.</strong> Backend Agnostic Codegen</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="backend/implicit-caller-location.html"><strong aria-hidden="true">78.4.</strong> Implicit caller location</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/intro.html"><strong aria-hidden="true">79.</strong> Debug Info</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/rust-codegen.html"><strong aria-hidden="true">79.1.</strong> Rust Codegen</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/llvm-codegen.html"><strong aria-hidden="true">79.2.</strong> LLVM Codegen</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/debugger-internals.html"><strong aria-hidden="true">79.3.</strong> Debugger Internals</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/lldb-internals.html"><strong aria-hidden="true">79.3.1.</strong> LLDB Internals</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/gdb-internals.html"><strong aria-hidden="true">79.3.2.</strong> GDB Internals</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/debugger-visualizers.html"><strong aria-hidden="true">79.4.</strong> Debugger Visualizers</a><a class="chapter-fold-toggle"><div>❱</div></a></span><ol class="section"><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/lldb-visualizers.html"><strong aria-hidden="true">79.4.1.</strong> LLDB - Python Providers</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/gdb-visualizers.html"><strong aria-hidden="true">79.4.2.</strong> GDB - Python Providers</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/natvis-visualizers.html"><strong aria-hidden="true">79.4.3.</strong> CDB - Natvis</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debuginfo/testing.html"><strong aria-hidden="true">79.5.</strong> Testing</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="debugging-support-in-rustc.html"><strong aria-hidden="true">79.6.</strong> (Lecture Notes) Debugging support in the Rust compiler</a></span></li></ol><li class="chapter-item "><span class="chapter-link-wrapper"><a href="backend/libs-and-metadata.html"><strong aria-hidden="true">80.</strong> Libraries and metadata</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="profile-guided-optimization.html"><strong aria-hidden="true">81.</strong> Profile-guided optimization</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="llvm-coverage-instrumentation.html"><strong aria-hidden="true">82.</strong> LLVM source-based code coverage</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="sanitizers.html"><strong aria-hidden="true">83.</strong> Sanitizers support</a></span></li><li class="chapter-item "><li class="spacer"></li></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="appendix/background.html">Appendix A: Background topics</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="appendix/glossary.html">Appendix B: Glossary</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="appendix/code-index.html">Appendix C: Code Index</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="appendix/compiler-lecture.html">Appendix D: Compiler Lecture Series</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="appendix/bibliography.html">Appendix E: Bibliography</a></span></li><li class="chapter-item "><span class="chapter-link-wrapper"><a href="appendix/humorust.html">Appendix Z: HumorRust</a></span></li></ol>'; |
| // Set the current, active page, and reveal it if it's hidden |
| let current_page = document.location.href.toString().split('#')[0].split('?')[0]; |
| if (current_page.endsWith('/')) { |
| current_page += 'index.html'; |
| } |
| const links = Array.prototype.slice.call(this.querySelectorAll('a')); |
| const l = links.length; |
| for (let i = 0; i < l; ++i) { |
| const link = links[i]; |
| const href = link.getAttribute('href'); |
| if (href && !href.startsWith('#') && !/^(?:[a-z+]+:)?\/\//.test(href)) { |
| link.href = path_to_root + href; |
| } |
| // The 'index' page is supposed to alias the first chapter in the book. |
| if (link.href === current_page |
| || i === 0 |
| && path_to_root === '' |
| && current_page.endsWith('/index.html')) { |
| link.classList.add('active'); |
| let parent = link.parentElement; |
| while (parent) { |
| if (parent.tagName === 'LI' && parent.classList.contains('chapter-item')) { |
| parent.classList.add('expanded'); |
| } |
| parent = parent.parentElement; |
| } |
| } |
| } |
| // Track and set sidebar scroll position |
| this.addEventListener('click', e => { |
| if (e.target.tagName === 'A') { |
| const clientRect = e.target.getBoundingClientRect(); |
| const sidebarRect = this.getBoundingClientRect(); |
| sessionStorage.setItem('sidebar-scroll-offset', clientRect.top - sidebarRect.top); |
| } |
| }, { passive: true }); |
| const sidebarScrollOffset = sessionStorage.getItem('sidebar-scroll-offset'); |
| sessionStorage.removeItem('sidebar-scroll-offset'); |
| if (sidebarScrollOffset !== null) { |
| // preserve sidebar scroll position when navigating via links within sidebar |
| const activeSection = this.querySelector('.active'); |
| if (activeSection) { |
| const clientRect = activeSection.getBoundingClientRect(); |
| const sidebarRect = this.getBoundingClientRect(); |
| const currentOffset = clientRect.top - sidebarRect.top; |
| this.scrollTop += currentOffset - parseFloat(sidebarScrollOffset); |
| } |
| } else { |
| // scroll sidebar to current active section when navigating via |
| // 'next/previous chapter' buttons |
| const activeSection = document.querySelector('#mdbook-sidebar .active'); |
| if (activeSection) { |
| activeSection.scrollIntoView({ block: 'center' }); |
| } |
| } |
| // Toggle buttons |
| const sidebarAnchorToggles = document.querySelectorAll('.chapter-fold-toggle'); |
| function toggleSection(ev) { |
| ev.currentTarget.parentElement.parentElement.classList.toggle('expanded'); |
| } |
| Array.from(sidebarAnchorToggles).forEach(el => { |
| el.addEventListener('click', toggleSection); |
| }); |
| } |
| } |
| window.customElements.define('mdbook-sidebar-scrollbox', MDBookSidebarScrollbox); |
| |
| |
| // --------------------------------------------------------------------------- |
| // Support for dynamically adding headers to the sidebar. |
| |
| (function() { |
| // This is used to detect which direction the page has scrolled since the |
| // last scroll event. |
| let lastKnownScrollPosition = 0; |
| // This is the threshold in px from the top of the screen where it will |
| // consider a header the "current" header when scrolling down. |
| const defaultDownThreshold = 150; |
| // Same as defaultDownThreshold, except when scrolling up. |
| const defaultUpThreshold = 300; |
| // The threshold is a virtual horizontal line on the screen where it |
| // considers the "current" header to be above the line. The threshold is |
| // modified dynamically to handle headers that are near the bottom of the |
| // screen, and to slightly offset the behavior when scrolling up vs down. |
| let threshold = defaultDownThreshold; |
| // This is used to disable updates while scrolling. This is needed when |
| // clicking the header in the sidebar, which triggers a scroll event. It |
| // is somewhat finicky to detect when the scroll has finished, so this |
| // uses a relatively dumb system of disabling scroll updates for a short |
| // time after the click. |
| let disableScroll = false; |
| // Array of header elements on the page. |
| let headers; |
| // Array of li elements that are initially collapsed headers in the sidebar. |
| // I'm not sure why eslint seems to have a false positive here. |
| // eslint-disable-next-line prefer-const |
| let headerToggles = []; |
| // This is a debugging tool for the threshold which you can enable in the console. |
| let thresholdDebug = false; |
| |
| // Updates the threshold based on the scroll position. |
| function updateThreshold() { |
| const scrollTop = window.pageYOffset || document.documentElement.scrollTop; |
| const windowHeight = window.innerHeight; |
| const documentHeight = document.documentElement.scrollHeight; |
| |
| // The number of pixels below the viewport, at most documentHeight. |
| // This is used to push the threshold down to the bottom of the page |
| // as the user scrolls towards the bottom. |
| const pixelsBelow = Math.max(0, documentHeight - (scrollTop + windowHeight)); |
| // The number of pixels above the viewport, at least defaultDownThreshold. |
| // Similar to pixelsBelow, this is used to push the threshold back towards |
| // the top when reaching the top of the page. |
| const pixelsAbove = Math.max(0, defaultDownThreshold - scrollTop); |
| // How much the threshold should be offset once it gets close to the |
| // bottom of the page. |
| const bottomAdd = Math.max(0, windowHeight - pixelsBelow - defaultDownThreshold); |
| let adjustedBottomAdd = bottomAdd; |
| |
| // Adjusts bottomAdd for a small document. The calculation above |
| // assumes the document is at least twice the windowheight in size. If |
| // it is less than that, then bottomAdd needs to be shrunk |
| // proportional to the difference in size. |
| if (documentHeight < windowHeight * 2) { |
| const maxPixelsBelow = documentHeight - windowHeight; |
| const t = 1 - pixelsBelow / Math.max(1, maxPixelsBelow); |
| const clamp = Math.max(0, Math.min(1, t)); |
| adjustedBottomAdd *= clamp; |
| } |
| |
| let scrollingDown = true; |
| if (scrollTop < lastKnownScrollPosition) { |
| scrollingDown = false; |
| } |
| |
| if (scrollingDown) { |
| // When scrolling down, move the threshold up towards the default |
| // downwards threshold position. If near the bottom of the page, |
| // adjustedBottomAdd will offset the threshold towards the bottom |
| // of the page. |
| const amountScrolledDown = scrollTop - lastKnownScrollPosition; |
| const adjustedDefault = defaultDownThreshold + adjustedBottomAdd; |
| threshold = Math.max(adjustedDefault, threshold - amountScrolledDown); |
| } else { |
| // When scrolling up, move the threshold down towards the default |
| // upwards threshold position. If near the bottom of the page, |
| // quickly transition the threshold back up where it normally |
| // belongs. |
| const amountScrolledUp = lastKnownScrollPosition - scrollTop; |
| const adjustedDefault = defaultUpThreshold - pixelsAbove |
| + Math.max(0, adjustedBottomAdd - defaultDownThreshold); |
| threshold = Math.min(adjustedDefault, threshold + amountScrolledUp); |
| } |
| |
| if (documentHeight <= windowHeight) { |
| threshold = 0; |
| } |
| |
| if (thresholdDebug) { |
| const id = 'mdbook-threshold-debug-data'; |
| let data = document.getElementById(id); |
| if (data === null) { |
| data = document.createElement('div'); |
| data.id = id; |
| data.style.cssText = ` |
| position: fixed; |
| top: 50px; |
| right: 10px; |
| background-color: 0xeeeeee; |
| z-index: 9999; |
| pointer-events: none; |
| `; |
| document.body.appendChild(data); |
| } |
| data.innerHTML = ` |
| <table> |
| <tr><td>documentHeight</td><td>${documentHeight.toFixed(1)}</td></tr> |
| <tr><td>windowHeight</td><td>${windowHeight.toFixed(1)}</td></tr> |
| <tr><td>scrollTop</td><td>${scrollTop.toFixed(1)}</td></tr> |
| <tr><td>pixelsAbove</td><td>${pixelsAbove.toFixed(1)}</td></tr> |
| <tr><td>pixelsBelow</td><td>${pixelsBelow.toFixed(1)}</td></tr> |
| <tr><td>bottomAdd</td><td>${bottomAdd.toFixed(1)}</td></tr> |
| <tr><td>adjustedBottomAdd</td><td>${adjustedBottomAdd.toFixed(1)}</td></tr> |
| <tr><td>scrollingDown</td><td>${scrollingDown}</td></tr> |
| <tr><td>threshold</td><td>${threshold.toFixed(1)}</td></tr> |
| </table> |
| `; |
| drawDebugLine(); |
| } |
| |
| lastKnownScrollPosition = scrollTop; |
| } |
| |
| function drawDebugLine() { |
| if (!document.body) { |
| return; |
| } |
| const id = 'mdbook-threshold-debug-line'; |
| const existingLine = document.getElementById(id); |
| if (existingLine) { |
| existingLine.remove(); |
| } |
| const line = document.createElement('div'); |
| line.id = id; |
| line.style.cssText = ` |
| position: fixed; |
| top: ${threshold}px; |
| left: 0; |
| width: 100vw; |
| height: 2px; |
| background-color: red; |
| z-index: 9999; |
| pointer-events: none; |
| `; |
| document.body.appendChild(line); |
| } |
| |
| function mdbookEnableThresholdDebug() { |
| thresholdDebug = true; |
| updateThreshold(); |
| drawDebugLine(); |
| } |
| |
| window.mdbookEnableThresholdDebug = mdbookEnableThresholdDebug; |
| |
| // Updates which headers in the sidebar should be expanded. If the current |
| // header is inside a collapsed group, then it, and all its parents should |
| // be expanded. |
| function updateHeaderExpanded(currentA) { |
| // Add expanded to all header-item li ancestors. |
| let current = currentA.parentElement; |
| while (current) { |
| if (current.tagName === 'LI' && current.classList.contains('header-item')) { |
| current.classList.add('expanded'); |
| } |
| current = current.parentElement; |
| } |
| } |
| |
| // Updates which header is marked as the "current" header in the sidebar. |
| // This is done with a virtual Y threshold, where headers at or below |
| // that line will be considered the current one. |
| function updateCurrentHeader() { |
| if (!headers || !headers.length) { |
| return; |
| } |
| |
| // Reset the classes, which will be rebuilt below. |
| const els = document.getElementsByClassName('current-header'); |
| for (const el of els) { |
| el.classList.remove('current-header'); |
| } |
| for (const toggle of headerToggles) { |
| toggle.classList.remove('expanded'); |
| } |
| |
| // Find the last header that is above the threshold. |
| let lastHeader = null; |
| for (const header of headers) { |
| const rect = header.getBoundingClientRect(); |
| if (rect.top <= threshold) { |
| lastHeader = header; |
| } else { |
| break; |
| } |
| } |
| if (lastHeader === null) { |
| lastHeader = headers[0]; |
| const rect = lastHeader.getBoundingClientRect(); |
| const windowHeight = window.innerHeight; |
| if (rect.top >= windowHeight) { |
| return; |
| } |
| } |
| |
| // Get the anchor in the summary. |
| const href = '#' + lastHeader.id; |
| const a = [...document.querySelectorAll('.header-in-summary')] |
| .find(element => element.getAttribute('href') === href); |
| if (!a) { |
| return; |
| } |
| |
| a.classList.add('current-header'); |
| |
| updateHeaderExpanded(a); |
| } |
| |
| // Updates which header is "current" based on the threshold line. |
| function reloadCurrentHeader() { |
| if (disableScroll) { |
| return; |
| } |
| updateThreshold(); |
| updateCurrentHeader(); |
| } |
| |
| |
| // When clicking on a header in the sidebar, this adjusts the threshold so |
| // that it is located next to the header. This is so that header becomes |
| // "current". |
| function headerThresholdClick(event) { |
| // See disableScroll description why this is done. |
| disableScroll = true; |
| setTimeout(() => { |
| disableScroll = false; |
| }, 100); |
| // requestAnimationFrame is used to delay the update of the "current" |
| // header until after the scroll is done, and the header is in the new |
| // position. |
| requestAnimationFrame(() => { |
| requestAnimationFrame(() => { |
| // Closest is needed because if it has child elements like <code>. |
| const a = event.target.closest('a'); |
| const href = a.getAttribute('href'); |
| const targetId = href.substring(1); |
| const targetElement = document.getElementById(targetId); |
| if (targetElement) { |
| threshold = targetElement.getBoundingClientRect().bottom; |
| updateCurrentHeader(); |
| } |
| }); |
| }); |
| } |
| |
| // Takes the nodes from the given head and copies them over to the |
| // destination, along with some filtering. |
| function filterHeader(source, dest) { |
| const clone = source.cloneNode(true); |
| clone.querySelectorAll('mark').forEach(mark => { |
| mark.replaceWith(...mark.childNodes); |
| }); |
| dest.append(...clone.childNodes); |
| } |
| |
| // Scans page for headers and adds them to the sidebar. |
| document.addEventListener('DOMContentLoaded', function() { |
| const activeSection = document.querySelector('#mdbook-sidebar .active'); |
| if (activeSection === null) { |
| return; |
| } |
| |
| const main = document.getElementsByTagName('main')[0]; |
| headers = Array.from(main.querySelectorAll('h2, h3, h4, h5, h6')) |
| .filter(h => h.id !== '' && h.children.length && h.children[0].tagName === 'A'); |
| |
| if (headers.length === 0) { |
| return; |
| } |
| |
| // Build a tree of headers in the sidebar. |
| |
| const stack = []; |
| |
| const firstLevel = parseInt(headers[0].tagName.charAt(1)); |
| for (let i = 1; i < firstLevel; i++) { |
| const ol = document.createElement('ol'); |
| ol.classList.add('section'); |
| if (stack.length > 0) { |
| stack[stack.length - 1].ol.appendChild(ol); |
| } |
| stack.push({level: i + 1, ol: ol}); |
| } |
| |
| // The level where it will start folding deeply nested headers. |
| const foldLevel = 3; |
| |
| for (let i = 0; i < headers.length; i++) { |
| const header = headers[i]; |
| const level = parseInt(header.tagName.charAt(1)); |
| |
| const currentLevel = stack[stack.length - 1].level; |
| if (level > currentLevel) { |
| // Begin nesting to this level. |
| for (let nextLevel = currentLevel + 1; nextLevel <= level; nextLevel++) { |
| const ol = document.createElement('ol'); |
| ol.classList.add('section'); |
| const last = stack[stack.length - 1]; |
| const lastChild = last.ol.lastChild; |
| // Handle the case where jumping more than one nesting |
| // level, which doesn't have a list item to place this new |
| // list inside of. |
| if (lastChild) { |
| lastChild.appendChild(ol); |
| } else { |
| last.ol.appendChild(ol); |
| } |
| stack.push({level: nextLevel, ol: ol}); |
| } |
| } else if (level < currentLevel) { |
| while (stack.length > 1 && stack[stack.length - 1].level > level) { |
| stack.pop(); |
| } |
| } |
| |
| const li = document.createElement('li'); |
| li.classList.add('header-item'); |
| li.classList.add('expanded'); |
| if (level < foldLevel) { |
| li.classList.add('expanded'); |
| } |
| const span = document.createElement('span'); |
| span.classList.add('chapter-link-wrapper'); |
| const a = document.createElement('a'); |
| span.appendChild(a); |
| a.href = '#' + header.id; |
| a.classList.add('header-in-summary'); |
| filterHeader(header.children[0], a); |
| a.addEventListener('click', headerThresholdClick); |
| const nextHeader = headers[i + 1]; |
| if (nextHeader !== undefined) { |
| const nextLevel = parseInt(nextHeader.tagName.charAt(1)); |
| if (nextLevel > level && level >= foldLevel) { |
| const toggle = document.createElement('a'); |
| toggle.classList.add('chapter-fold-toggle'); |
| toggle.classList.add('header-toggle'); |
| toggle.addEventListener('click', () => { |
| li.classList.toggle('expanded'); |
| }); |
| const toggleDiv = document.createElement('div'); |
| toggleDiv.textContent = '❱'; |
| toggle.appendChild(toggleDiv); |
| span.appendChild(toggle); |
| headerToggles.push(li); |
| } |
| } |
| li.appendChild(span); |
| |
| const currentParent = stack[stack.length - 1]; |
| currentParent.ol.appendChild(li); |
| } |
| |
| const onThisPage = document.createElement('div'); |
| onThisPage.classList.add('on-this-page'); |
| onThisPage.append(stack[0].ol); |
| const activeItemSpan = activeSection.parentElement; |
| activeItemSpan.after(onThisPage); |
| }); |
| |
| document.addEventListener('DOMContentLoaded', reloadCurrentHeader); |
| document.addEventListener('scroll', reloadCurrentHeader, { passive: true }); |
| })(); |
| |