Add note to docs when layout cannot be computed

This should prevent confusion about why generic types don't have layout
docs.
This commit is contained in:
Camelid 2021-04-27 17:11:58 -07:00
parent 879a914eea
commit 8b9298bbaa
2 changed files with 35 additions and 8 deletions

View File

@ -7,6 +7,7 @@ use rustc_hir as hir;
use rustc_hir::def::CtorKind;
use rustc_hir::def_id::DefId;
use rustc_middle::middle::stability;
use rustc_middle::ty::layout::LayoutError;
use rustc_middle::ty::TyCtxt;
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Symbol};
@ -1540,13 +1541,14 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
return;
}
writeln!(w, "<h2 class=\"small-section-header\">Layout</h2>");
writeln!(w, "<div class=\"docblock\">");
let tcx = cx.tcx();
let param_env = tcx.param_env(ty_def_id);
let ty = tcx.type_of(ty_def_id);
match tcx.layout_of(param_env.and(ty)) {
Ok(ty_layout) => {
writeln!(w, "<h2 class=\"small-section-header\">Layout</h2>");
writeln!(w, "<div class=\"docblock\">");
writeln!(
w,
"<div class=\"warning\"><p><strong>Note:</strong> Most layout information is \
@ -1567,11 +1569,28 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
pl = if bytes == 1 { "" } else { "s" },
);
}
writeln!(w, "</div>");
}
// Layout errors can occur with valid code, e.g. if you try to get the layout
// of a generic type such as `Vec<T>`. In case of a layout error, we just
// don't show any layout information.
Err(_) => {}
// 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<T>`.
Err(LayoutError::Unknown(_)) => {
writeln!(
w,
"<p><strong>Note:</strong> Unable to compute type layout, \
possibly due to this type having generic parameters. \
Layout can only be computed for concrete, fully-instantiated types.</p>"
);
}
// 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!(
w,
"<p><strong>Note:</strong> Encountered an error during type layout; \
the type was too big.</p>"
);
}
}
writeln!(w, "</div>");
}

View File

@ -35,9 +35,17 @@ pub struct Y(u8);
// @has - '0 bytes'
pub struct Z;
// @!has type_layout/struct.Generic.html 'Size: '
// We can't compute layout for generic types.
// @has type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters'
// @!has - 'Size: '
pub struct Generic<T>(T);
// We *can*, however, compute layout for types that are only generic over lifetimes,
// because lifetimes are a type-system construct.
// @has type_layout/struct.GenericLifetimes.html 'Size: '
// @has - ' bytes'
pub struct GenericLifetimes<'a>(&'a str);
// @has type_layout/struct.Unsized.html 'Size: '
// @has - '(unsized)'
pub struct Unsized([u8]);