diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index 4c7822acdf7..02baa395c3c 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -73,34 +73,6 @@ impl<'a, 'tcx> HashStable> for ty::subst::GenericArg<'t } } -impl<'a, 'tcx> HashStable> for ty::subst::GenericArgKind<'tcx> { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - match self { - // WARNING: We dedup cache the `HashStable` results for `List` - // while ignoring types and freely transmute - // between `List>` and `List>`. - // See `fn mk_type_list` for more details. - // - // We therefore hash types without adding a hash for their discriminant. - // - // In order to make it very unlikely for the sequence of bytes being hashed for - // a `GenericArgKind::Type` to be the same as the sequence of bytes being - // hashed for one of the other variants, we hash some very high number instead - // of their actual discriminant since `TyKind` should never start with anything - // that high. - ty::subst::GenericArgKind::Type(ty) => ty.hash_stable(hcx, hasher), - ty::subst::GenericArgKind::Const(ct) => { - 0xF3u8.hash_stable(hcx, hasher); - ct.hash_stable(hcx, hasher); - } - ty::subst::GenericArgKind::Lifetime(lt) => { - 0xF5u8.hash_stable(hcx, hasher); - lt.hash_stable(hcx, hasher); - } - } - } -} - // AllocIds get resolved to whatever they point to (to be stable) impl<'a> HashStable> for mir::interpret::AllocId { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 5315aa155a8..888b3a50b77 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -738,7 +738,9 @@ pub trait PrettyPrinter<'tcx>: } } ty::Placeholder(placeholder) => match placeholder.bound.kind { - ty::BoundTyKind::Anon => p!(write("Placeholder({:?})", placeholder)), + ty::BoundTyKind::Anon => { + self.pretty_print_placeholder_var(placeholder.universe, placeholder.bound.var)? + } ty::BoundTyKind::Param(_, name) => p!(write("{}", name)), }, ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { @@ -1172,6 +1174,18 @@ pub trait PrettyPrinter<'tcx>: } } + fn pretty_print_placeholder_var( + &mut self, + ui: ty::UniverseIndex, + var: ty::BoundVar, + ) -> Result<(), Self::Error> { + if ui == ty::UniverseIndex::ROOT { + write!(self, "!{}", var.index()) + } else { + write!(self, "!{}_{}", ui.index(), var.index()) + } + } + fn ty_infer_name(&self, _: ty::TyVid) -> Option { None } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 73c9c86f76a..a439211ca33 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -47,7 +47,7 @@ const TYPE_TAG: usize = 0b00; const REGION_TAG: usize = 0b01; const CONST_TAG: usize = 0b10; -#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)] pub enum GenericArgKind<'tcx> { Lifetime(ty::Region<'tcx>), Type(Ty<'tcx>), diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 7a2420a6d94..7d04aead8bc 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -507,12 +507,12 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // // Const-prop runs unconditionally, but doesn't mutate the MIR at mir-opt-level=0. &const_debuginfo::ConstDebugInfo, - &o1(simplify_branches::SimplifyConstConditionPassName::AfterConstProp), + &o1(simplify_branches::SimplifyConstCondition::AfterConstProp), &early_otherwise_branch::EarlyOtherwiseBranch, &simplify_comparison_integral::SimplifyComparisonIntegral, &dead_store_elimination::DeadStoreElimination, &dest_prop::DestinationPropagation, - &o1(simplify_branches::SimplifyConstConditionPassName::Final), + &o1(simplify_branches::SimplifyConstCondition::Final), &o1(remove_noop_landing_pads::RemoveNoopLandingPads), &o1(simplify::SimplifyCfg::Final), &nrvo::RenameReturnPlace, diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index ddaf86a9e73..c65a7ec6783 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -2,18 +2,16 @@ use crate::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -pub enum SimplifyConstConditionPassName { +pub enum SimplifyConstCondition { AfterConstProp, Final, } /// A pass that replaces a branch with a goto when its condition is known. -impl<'tcx> MirPass<'tcx> for SimplifyConstConditionPassName { +impl<'tcx> MirPass<'tcx> for SimplifyConstCondition { fn name(&self) -> &'static str { match self { - SimplifyConstConditionPassName::AfterConstProp => { - "SimplifyConstCondition-after-const-prop" - } - SimplifyConstConditionPassName::Final => "SimplifyConstCondition-final", + SimplifyConstCondition::AfterConstProp => "SimplifyConstCondition-after-const-prop", + SimplifyConstCondition::Final => "SimplifyConstCondition-final", } } diff --git a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs index ebd74012dcd..9bcd56bed00 100644 --- a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs @@ -3,6 +3,7 @@ use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); + base.cpu = "M68020".into(); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 62e699eefd7..4c1f2dd0e53 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -203,6 +203,10 @@ pub enum TyKind { /// `for<'a, T> &'a (): Trait` and then convert the introduced bound variables /// back to inference variables in a new inference context when inside of the query. /// + /// It is conventional to render anonymous bound types like `^N` or `^D_N`, + /// where `N` is the bound variable's anonymous index into the binder, and + /// `D` is the debruijn index, or totally omitted if the debruijn index is zero. + /// /// See the `rustc-dev-guide` for more details about /// [higher-ranked trait bounds][1] and [canonical queries][2]. /// @@ -212,6 +216,12 @@ pub enum TyKind { /// A placeholder type, used during higher ranked subtyping to instantiate /// bound variables. + /// + /// It is conventional to render anonymous placeholer types like `!N` or `!U_N`, + /// where `N` is the placeholder variable's anonymous index (which corresponds + /// to the bound variable's index from the binder from which it was instantiated), + /// and `U` is the universe index in which it is instantiated, or totally omitted + /// if the universe index is zero. Placeholder(I::PlaceholderType), /// A type variable used during type checking. diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index ad48315fd70..f83c8f83cc9 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -7,7 +7,7 @@ use core::fmt::{self, Debug, Display, Formatter}; use core::marker::PhantomData; #[cfg(not(no_global_oom_handling))] use core::marker::Unsize; -use core::mem; +use core::mem::{self, SizedTypeProperties}; use core::ops::{Deref, DerefMut}; use core::ptr::Pointee; use core::ptr::{self, NonNull}; @@ -202,9 +202,7 @@ impl WithHeader { let ptr = if layout.size() == 0 { // Some paranoia checking, mostly so that the ThinBox tests are // more able to catch issues. - debug_assert!( - value_offset == 0 && mem::size_of::() == 0 && mem::size_of::() == 0 - ); + debug_assert!(value_offset == 0 && T::IS_ZST && H::IS_ZST); layout.dangling() } else { let ptr = alloc::alloc(layout); @@ -249,9 +247,7 @@ impl WithHeader { alloc::dealloc(self.ptr.as_ptr().sub(value_offset), layout); } else { debug_assert!( - value_offset == 0 - && mem::size_of::() == 0 - && self.value_layout.size() == 0 + value_offset == 0 && H::IS_ZST && self.value_layout.size() == 0 ); } } diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index e3ca6eb7833..3091efabd68 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -112,9 +112,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> { let unyielded_ptr = this.iter.as_slice().as_ptr(); // ZSTs have no identity, so we don't need to move them around. - let needs_move = mem::size_of::() != 0; - - if needs_move { + if !T::IS_ZST { let start_ptr = source_vec.as_mut_ptr().add(start); // memmove back unyielded elements diff --git a/library/alloc/src/vec/drain_filter.rs b/library/alloc/src/vec/drain_filter.rs index 8c03f1692d9..650f9213890 100644 --- a/library/alloc/src/vec/drain_filter.rs +++ b/library/alloc/src/vec/drain_filter.rs @@ -1,5 +1,5 @@ use crate::alloc::{Allocator, Global}; -use core::mem::{self, ManuallyDrop}; +use core::mem::{ManuallyDrop, SizedTypeProperties}; use core::ptr; use core::slice; @@ -96,9 +96,7 @@ where unsafe { // ZSTs have no identity, so we don't need to move them around. - let needs_move = mem::size_of::() != 0; - - if needs_move && this.idx < this.old_len && this.del > 0 { + if !T::IS_ZST && this.idx < this.old_len && this.del > 0 { let ptr = this.vec.as_mut_ptr(); let src = ptr.add(this.idx); let dst = src.sub(this.del); diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index b73e35f1e91..b1ca872b845 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -73,7 +73,7 @@ macro_rules! iterator { // Unsafe because the offset must not exceed `self.len()`. #[inline(always)] unsafe fn post_inc_start(&mut self, offset: usize) -> * $raw_mut T { - if mem::size_of::() == 0 { + if T::IS_ZST { zst_shrink!(self, offset); self.ptr.as_ptr() } else { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 463184acaa1..a5f08fdac11 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -32,6 +32,7 @@ mod context; mod print_item; mod sidebar; mod span_map; +mod type_layout; mod write_shared; pub(crate) use self::context::*; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 9a968e48b27..3e71d41ec96 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -6,16 +6,14 @@ use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; use rustc_middle::middle::stability; -use rustc_middle::span_bug; -use rustc_middle::ty::layout::LayoutError; -use rustc_middle::ty::{self, Adt, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_target::abi::{LayoutS, Primitive, TagEncoding, Variants}; use std::cmp::Ordering; use std::fmt; use std::rc::Rc; +use super::type_layout::document_type_layout; use super::{ collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference, item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls, @@ -1933,118 +1931,6 @@ fn document_non_exhaustive<'a>(item: &'a clean::Item) -> impl fmt::Display + 'a }) } -fn document_type_layout<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - ty_def_id: DefId, -) -> impl fmt::Display + 'a + Captures<'cx> { - fn write_size_of_layout(mut w: impl fmt::Write, layout: &LayoutS, tag_size: u64) { - if layout.abi.is_unsized() { - write!(w, "(unsized)").unwrap(); - } else { - let size = layout.size.bytes() - tag_size; - write!(w, "{size} byte{pl}", pl = if size == 1 { "" } else { "s" }).unwrap(); - if layout.abi.is_uninhabited() { - write!( - w, - " (uninhabited)" - ).unwrap(); - } - } - } - - display_fn(move |mut f| { - if !cx.shared.show_type_layout { - return Ok(()); - } - - writeln!( - f, - "

\ - Layout§

" - )?; - writeln!(f, "
")?; - - let tcx = cx.tcx(); - let param_env = tcx.param_env(ty_def_id); - let ty = tcx.type_of(ty_def_id).subst_identity(); - match tcx.layout_of(param_env.and(ty)) { - Ok(ty_layout) => { - writeln!( - f, - "

Note: Most layout information is \ - completely unstable and may even differ between compilations. \ - The only exception is types with certain repr(...) attributes. \ - Please see the Rust Reference’s \ - “Type Layout” \ - chapter for details on type layout guarantees.

" - )?; - f.write_str("

Size: ")?; - write_size_of_layout(&mut f, &ty_layout.layout.0, 0); - writeln!(f, "

")?; - if let Variants::Multiple { variants, tag, tag_encoding, .. } = - &ty_layout.layout.variants() - { - if !variants.is_empty() { - f.write_str( - "

Size for each variant:

\ -
    ", - )?; - - let Adt(adt, _) = ty_layout.ty.kind() else { - span_bug!(tcx.def_span(ty_def_id), "not an adt") - }; - - let tag_size = if let TagEncoding::Niche { .. } = tag_encoding { - 0 - } else if let Primitive::Int(i, _) = tag.primitive() { - i.size().bytes() - } else { - span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int") - }; - - for (index, layout) in variants.iter_enumerated() { - let name = adt.variant(index).name; - write!(&mut f, "
  • {name}: ")?; - write_size_of_layout(&mut f, layout, tag_size); - writeln!(&mut f, "
  • ")?; - } - f.write_str("
")?; - } - } - } - // This kind of layout error can occur with valid code, e.g. if you try to - // get the layout of a generic type such as `Vec`. - Err(LayoutError::Unknown(_)) => { - writeln!( - f, - "

Note: Unable to compute type layout, \ - possibly due to this type having generic parameters. \ - Layout can only be computed for concrete, fully-instantiated types.

" - )?; - } - // This kind of error probably can't happen with valid code, but we don't - // want to panic and prevent the docs from building, so we just let the - // user know that we couldn't compute the layout. - Err(LayoutError::SizeOverflow(_)) => { - writeln!( - f, - "

Note: Encountered an error during type layout; \ - the type was too big.

" - )?; - } - Err(LayoutError::NormalizationFailure(_, _)) => { - writeln!( - f, - "

Note: Encountered an error during type layout; \ - the type failed to be normalized.

" - )?; - } - } - - writeln!(f, "
") - }) -} - fn pluralize(count: usize) -> &'static str { if count > 1 { "s" } else { "" } } diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs new file mode 100644 index 00000000000..22aec623335 --- /dev/null +++ b/src/librustdoc/html/render/type_layout.rs @@ -0,0 +1,86 @@ +use askama::Template; + +use rustc_data_structures::captures::Captures; +use rustc_hir::def_id::DefId; +use rustc_middle::span_bug; +use rustc_middle::ty::layout::LayoutError; +use rustc_middle::ty::Adt; +use rustc_span::symbol::Symbol; +use rustc_target::abi::{Primitive, TagEncoding, Variants}; + +use std::fmt; + +use crate::html::format::display_fn; +use crate::html::render::Context; + +#[derive(Template)] +#[template(path = "type_layout.html")] +struct TypeLayout<'cx> { + variants: Vec<(Symbol, TypeLayoutSize)>, + type_layout_size: Result>, +} + +#[derive(Template)] +#[template(path = "type_layout_size.html")] +struct TypeLayoutSize { + is_unsized: bool, + is_uninhabited: bool, + size: u64, +} + +pub(crate) fn document_type_layout<'a, 'cx: 'a>( + cx: &'a Context<'cx>, + ty_def_id: DefId, +) -> impl fmt::Display + 'a + Captures<'cx> { + display_fn(move |f| { + if !cx.shared.show_type_layout { + return Ok(()); + } + + let tcx = cx.tcx(); + let param_env = tcx.param_env(ty_def_id); + let ty = tcx.type_of(ty_def_id).subst_identity(); + let type_layout = tcx.layout_of(param_env.and(ty)); + + let variants = + if let Ok(type_layout) = type_layout && + let Variants::Multiple { variants, tag, tag_encoding, .. } = + type_layout.layout.variants() && + !variants.is_empty() + { + let tag_size = + if let TagEncoding::Niche { .. } = tag_encoding { + 0 + } else if let Primitive::Int(i, _) = tag.primitive() { + i.size().bytes() + } else { + span_bug!(cx.tcx().def_span(ty_def_id), "tag is neither niche nor int") + }; + variants + .iter_enumerated() + .map(|(variant_idx, variant_layout)| { + let Adt(adt, _) = type_layout.ty.kind() else { + span_bug!(cx.tcx().def_span(ty_def_id), "not an adt") + }; + let name = adt.variant(variant_idx).name; + let is_unsized = variant_layout.abi.is_unsized(); + let is_uninhabited = variant_layout.abi.is_uninhabited(); + let size = variant_layout.size.bytes() - tag_size; + let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size }; + (name, type_layout_size) + }) + .collect() + } else { + Vec::new() + }; + + let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| { + let is_unsized = layout.abi.is_unsized(); + let is_uninhabited = layout.abi.is_uninhabited(); + let size = layout.size.bytes(); + TypeLayoutSize { is_unsized, is_uninhabited, size } + }); + + Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap()) + }) +} diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 93d657fd605..bccf675c14b 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -375,10 +375,7 @@ function preLoadCss(cssUrl) { function handleEscape(ev) { searchState.clearInputTimeout(); - switchDisplayedElement(null); - if (browserSupportsHistoryApi()) { - history.replaceState(null, "", getNakedUrl() + window.location.hash); - } + searchState.hideResults(); ev.preventDefault(); searchState.defocus(); window.hideAllModals(true); // true = reset focus for tooltips @@ -533,9 +530,11 @@ function preLoadCss(cssUrl) { // ignored are included in the attribute `data-ignore-extern-crates`. const script = document .querySelector("script[data-ignore-extern-crates]"); - const ignoreExternCrates = script ? script.getAttribute("data-ignore-extern-crates") : ""; + const ignoreExternCrates = new Set( + (script ? script.getAttribute("data-ignore-extern-crates") : "").split(",") + ); for (const lib of libs) { - if (lib === window.currentCrate || ignoreExternCrates.indexOf(lib) !== -1) { + if (lib === window.currentCrate || ignoreExternCrates.has(lib)) { continue; } const structs = imp[lib]; diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 929dae81c8d..3dc4f2149b8 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2412,10 +2412,6 @@ function initSearch(rawSearchIndex) { const searchAfter500ms = () => { searchState.clearInputTimeout(); if (searchState.input.value.length === 0) { - if (browserSupportsHistoryApi()) { - history.replaceState(null, window.currentCrate + " - Rust", - getNakedUrl() + window.location.hash); - } searchState.hideResults(); } else { searchState.timeout = setTimeout(search, 500); diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index 9aa75517330..d999f3b36fd 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -52,12 +52,12 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { const files = document.createElement("div"); files.className = "files"; if (elem[FILES_OFFSET]) { + const w = window.location.href.split("#")[0]; for (const file_text of elem[FILES_OFFSET]) { const file = document.createElement("a"); file.innerText = file_text; file.href = rootPath + "src/" + fullPath + file_text + ".html"; file.addEventListener("click", closeSidebarIfMobile); - const w = window.location.href.split("#")[0]; if (!hasFoundFile && w === file.href) { file.className = "selected"; dirEntry.open = true; diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html new file mode 100644 index 00000000000..58b220c7428 --- /dev/null +++ b/src/librustdoc/html/templates/type_layout.html @@ -0,0 +1,53 @@ +

{# #} + Layout§ {# #} +

{# #} +
{# #} + {% match type_layout_size %} + {% when Ok(type_layout_size) %} +
{# #} +

{# #} + Note: Most layout information is completely {#+ #} + unstable and may even differ between compilations. {#+ #} + The only exception is types with certain repr(...) {#+ #} + attributes. Please see the Rust Reference’s {#+ #} + “Type Layout” {#+ #} + chapter for details on type layout guarantees. {# #} +

{# #} +
{# #} +

Size: {{ type_layout_size|safe }}

{# #} + {% if !variants.is_empty() %} +

{# #} + Size for each variant: {# #} +

{# #} +
    {# #} + {% for (name, layout_size) in variants %} +
  • {# #} + {{ name }}: {#+ #} + {{ layout_size|safe }} +
  • {# #} + {% endfor %} +
{# #} + {% endif %} + {# This kind of layout error can occur with valid code, e.g. if you try to + get the layout of a generic type such as `Vec`. #} + {% when Err(LayoutError::Unknown(_)) %} +

{# #} + Note: Unable to compute type layout, {#+ #} + possibly due to this type having generic parameters. {#+ #} + Layout can only be computed for concrete, fully-instantiated types. {# #} +

{# #} + {# This kind of error probably can't happen with valid code, but we don't + want to panic and prevent the docs from building, so we just let the + user know that we couldn't compute the layout. #} + {% when Err(LayoutError::SizeOverflow(_)) %} +

{# #} + Note: Encountered an error during type layout; {#+ #} + the type was too big. {# #} +

{# #} + {% when Err(LayoutError::NormalizationFailure(_, _)) %} +

{# #} + Note: Encountered an error during type layout; {#+ #} + the type failed to be normalized. {# #} +

{# #} + {% endmatch %} +
{# #} diff --git a/src/librustdoc/html/templates/type_layout_size.html b/src/librustdoc/html/templates/type_layout_size.html new file mode 100644 index 00000000000..9c2b39edc9f --- /dev/null +++ b/src/librustdoc/html/templates/type_layout_size.html @@ -0,0 +1,12 @@ +{% if is_unsized %} + (unsized) +{% else %} + {% if size == 1 %} + 1 byte + {% else %} + {{ size +}} bytes + {% endif %} + {% if is_uninhabited %} + {# +#} (uninhabited) + {% endif %} +{% endif %}