From 2b728c1f85dec11fd0e64ad89c7149e119134971 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 21 Apr 2023 10:06:31 -0700 Subject: [PATCH] rustdoc: factor `document_type_layout` into its own module --- src/librustdoc/html/render/mod.rs | 1 + src/librustdoc/html/render/print_item.rs | 79 +------------------- src/librustdoc/html/render/type_layout.rs | 87 +++++++++++++++++++++++ 3 files changed, 90 insertions(+), 77 deletions(-) create mode 100644 src/librustdoc/html/render/type_layout.rs diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1e3cd266850..a699d0b38a7 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -32,6 +32,7 @@ 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 fe227244588..b71109f1560 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -6,16 +6,14 @@ 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::{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, @@ -1932,79 +1930,6 @@ struct update syntax will not work.", }) } -fn document_type_layout<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - ty_def_id: DefId, -) -> impl fmt::Display + 'a + Captures<'cx> { - #[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, - } - - 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") - }; - let variants = 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(); - variants - } 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()) - }) -} - 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..0befc9625db --- /dev/null +++ b/src/librustdoc/html/render/type_layout.rs @@ -0,0 +1,87 @@ +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") + }; + let variants = 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(); + variants + } 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()) + }) +}