Skip to content

Commit 3a16db1

Browse files
committed
rustdoc: create variants list outside of template
1 parent 5f9746b commit 3a16db1

File tree

2 files changed

+60
-63
lines changed

2 files changed

+60
-63
lines changed

src/librustdoc/html/render/print_item.rs

+53-56
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
55
use rustc_hir as hir;
66
use rustc_hir::def::CtorKind;
77
use rustc_hir::def_id::DefId;
8-
use rustc_index::vec::IndexVec;
98
use rustc_middle::middle::stability;
109
use rustc_middle::span_bug;
11-
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
10+
use rustc_middle::ty::layout::LayoutError;
1211
use rustc_middle::ty::{self, Adt, TyCtxt};
1312
use rustc_span::hygiene::MacroKind;
1413
use rustc_span::symbol::{kw, sym, Symbol};
15-
use rustc_target::abi::{LayoutS, Primitive, TagEncoding, VariantIdx, Variants};
16-
use std::borrow::Borrow;
14+
use rustc_target::abi::{Primitive, TagEncoding, Variants};
1715
use std::cmp::Ordering;
1816
use std::fmt;
1917
use std::rc::Rc;
@@ -1940,9 +1938,9 @@ fn document_type_layout<'a, 'cx: 'a>(
19401938
) -> impl fmt::Display + 'a + Captures<'cx> {
19411939
#[derive(Template)]
19421940
#[template(path = "type_layout.html")]
1943-
struct TypeLayout<'a, 'cx> {
1944-
cx: &'a Context<'cx>,
1945-
ty_def_id: DefId,
1941+
struct TypeLayout<'cx> {
1942+
variants: Vec<(Symbol, TypeLayoutSize)>,
1943+
type_layout_size: Result<TypeLayoutSize, LayoutError<'cx>>,
19461944
}
19471945

19481946
#[derive(Template)]
@@ -1953,62 +1951,61 @@ fn document_type_layout<'a, 'cx: 'a>(
19531951
size: u64,
19541952
}
19551953

1956-
impl<'a, 'cx: 'a> TypeLayout<'a, 'cx> {
1957-
fn variants<'b: 'a>(&'b self) -> Option<&'b IndexVec<VariantIdx, LayoutS>> {
1958-
if let Variants::Multiple { variants, .. } =
1959-
self.type_layout().unwrap().layout.variants() && !variants.is_empty() {
1960-
Some(&variants)
1961-
} else {
1962-
None
1963-
}
1964-
}
1965-
fn type_layout<'b: 'a>(&'b self) -> Result<TyAndLayout<'cx>, LayoutError<'cx>> {
1966-
let tcx = self.cx.tcx();
1967-
let param_env = tcx.param_env(self.ty_def_id);
1968-
let ty = tcx.type_of(self.ty_def_id).subst_identity();
1969-
tcx.layout_of(param_env.and(ty))
1954+
display_fn(move |f| {
1955+
if !cx.shared.show_type_layout {
1956+
return Ok(());
19701957
}
1971-
fn variant_name<'b: 'a>(&'b self, index: VariantIdx) -> Symbol {
1972-
let Adt(adt, _) = self.type_layout().unwrap().ty.kind() else {
1973-
span_bug!(self.cx.tcx().def_span(self.ty_def_id), "not an adt")
1974-
};
1975-
adt.variant(index).name
1976-
}
1977-
fn tag_size<'b: 'a>(&'b self) -> u64 {
1978-
if let Variants::Multiple { variants, tag, tag_encoding, .. } =
1979-
self.type_layout().unwrap().layout.variants() && !variants.is_empty() {
1980-
if let TagEncoding::Niche { .. } = tag_encoding {
1981-
0
1982-
} else if let Primitive::Int(i, _) = tag.primitive() {
1983-
i.size().bytes()
1984-
} else {
1985-
span_bug!(self.cx.tcx().def_span(self.ty_def_id), "tag is neither niche nor int")
1986-
}
1958+
1959+
let variants = {
1960+
let tcx = cx.tcx();
1961+
let param_env = tcx.param_env(ty_def_id);
1962+
let ty = tcx.type_of(ty_def_id).subst_identity();
1963+
let type_layout = tcx.layout_of(param_env.and(ty));
1964+
if let Ok(type_layout) = type_layout &&
1965+
let Variants::Multiple { variants, tag, tag_encoding, .. } =
1966+
type_layout.layout.variants() &&
1967+
!variants.is_empty()
1968+
{
1969+
let tag_size =
1970+
if let TagEncoding::Niche { .. } = tag_encoding {
1971+
0
1972+
} else if let Primitive::Int(i, _) = tag.primitive() {
1973+
i.size().bytes()
1974+
} else {
1975+
span_bug!(cx.tcx().def_span(ty_def_id), "tag is neither niche nor int")
1976+
};
1977+
let variants = variants
1978+
.iter_enumerated()
1979+
.map(|(variant_idx, variant_layout)| {
1980+
let Adt(adt, _) = type_layout.ty.kind() else {
1981+
span_bug!(cx.tcx().def_span(ty_def_id), "not an adt")
1982+
};
1983+
let name = adt.variant(variant_idx).name;
1984+
let is_unsized = variant_layout.abi.is_unsized();
1985+
let is_uninhabited = variant_layout.abi.is_uninhabited();
1986+
let size = variant_layout.size.bytes() - tag_size;
1987+
let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size };
1988+
(name, type_layout_size)
1989+
}).collect();
1990+
variants
19871991
} else {
1988-
0
1992+
Vec::new()
19891993
}
1990-
}
1991-
fn write_size<'b: 'a>(
1992-
&'b self,
1993-
layout: &'b LayoutS,
1994-
tag_size: u64,
1995-
) -> impl fmt::Display + Captures<'cx> + Captures<'b> {
1996-
display_fn(move |f| {
1994+
};
1995+
1996+
let type_layout_size = {
1997+
let tcx = cx.tcx();
1998+
let param_env = tcx.param_env(ty_def_id);
1999+
let ty = tcx.type_of(ty_def_id).subst_identity();
2000+
tcx.layout_of(param_env.and(ty)).map(|layout| {
19972001
let is_unsized = layout.abi.is_unsized();
19982002
let is_uninhabited = layout.abi.is_uninhabited();
1999-
let size = layout.size.bytes() - tag_size;
2000-
TypeLayoutSize { is_unsized, is_uninhabited, size }.render_into(f).unwrap();
2001-
Ok(())
2003+
let size = layout.size.bytes();
2004+
TypeLayoutSize { is_unsized, is_uninhabited, size }
20022005
})
2003-
}
2004-
}
2005-
2006-
display_fn(move |f| {
2007-
if !cx.shared.show_type_layout {
2008-
return Ok(());
2009-
}
2006+
};
20102007

2011-
Ok(TypeLayout { cx, ty_def_id }.render_into(f).unwrap())
2008+
Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap())
20122009
})
20132010
}
20142011

src/librustdoc/html/templates/type_layout.html

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ <h2 id="layout" class="small-section-header"> {# #}
22
Layout<a href="#layout" class="anchor">§</a> {# #}
33
</h2> {# #}
44
<div class="docblock"> {# #}
5-
{% match self.type_layout() %}
6-
{% when Ok(ty_layout) %}
5+
{% match type_layout_size %}
6+
{% when Ok(type_layout_size) %}
77
<div class="warning"> {# #}
88
<p> {# #}
99
<strong>Note:</strong> Most layout information is <strong>completely {#+ #}
@@ -14,14 +14,14 @@ <h2 id="layout" class="small-section-header"> {# #}
1414
chapter for details on type layout guarantees. {# #}
1515
</p> {# #}
1616
</div> {# #}
17-
<p><strong>Size:</strong> {{ self.write_size(ty_layout.layout.0.borrow(), 0) | safe }}</p> {# #}
18-
{% if let Some(variants) = self.variants() %}
17+
<p><strong>Size:</strong> {{ type_layout_size|safe }}</p> {# #}
18+
{% if !variants.is_empty() %}
1919
<p><strong>Size for each variant:</strong></p> {# #}
2020
<ul> {# #}
21-
{% for (index, layout) in variants.iter_enumerated() %}
21+
{% for (name, layout_size) in variants %}
2222
<li> {# #}
23-
<code>{{ self.variant_name(index.clone()) }}</code>: {#+ #}
24-
{{ self.write_size(layout, self.tag_size()) | safe }}
23+
<code>{{ name }}</code>: {#+ #}
24+
{{ layout_size|safe }}
2525
</li> {# #}
2626
{% endfor %}
2727
</ul> {# #}

0 commit comments

Comments
 (0)