diff options
Diffstat (limited to 'src/librustdoc/html')
| -rw-r--r-- | src/librustdoc/html/render/context.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/render/print_item.rs | 78 | ||||
| -rw-r--r-- | src/librustdoc/html/static/main.js | 36 | ||||
| -rw-r--r-- | src/librustdoc/html/static/search.js | 74 | ||||
| -rw-r--r-- | src/librustdoc/html/static/source-script.js | 9 | ||||
| -rw-r--r-- | src/librustdoc/html/static/storage.js | 14 |
6 files changed, 142 insertions, 73 deletions
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 4e17dc8d3a7..666d9dfc3e9 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -91,6 +91,8 @@ crate struct SharedContext<'tcx> { crate include_sources: bool, /// The local file sources we've emitted and their respective url-paths. crate local_sources: FxHashMap<PathBuf, String>, + /// Show the memory layout of types in the docs. + pub(super) show_type_layout: bool, /// Whether the collapsed pass ran collapsed: bool, /// The base-URL of the issue tracker for when an item has been tagged with @@ -373,6 +375,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { generate_search_filter, unstable_features, generate_redirect_map, + show_type_layout, .. } = options; @@ -446,6 +449,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { all: RefCell::new(AllTypes::new()), errors: receiver, redirections: if generate_redirect_map { Some(Default::default()) } else { None }, + show_type_layout, }; // Add the default themes to the `Vec` of stylepaths diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 7ccc313cc59..f0ca24b8f02 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -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}; @@ -830,11 +831,12 @@ fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::T document(w, cx, it, None); + let def_id = it.def_id.expect_real(); // Render any items associated directly to this alias, as otherwise they // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) + render_assoc_items(w, cx, it, def_id, AssocItemRender::All); } fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) { @@ -846,6 +848,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni }); document(w, cx, it, None); + let mut fields = s .fields .iter() @@ -880,7 +883,9 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni document(w, cx, field, Some(it)); } } - render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) + let def_id = it.def_id.expect_real(); + render_assoc_items(w, cx, it, def_id, AssocItemRender::All); + document_type_layout(w, cx, def_id); } fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) { @@ -940,6 +945,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum }); document(w, cx, it, None); + if !e.variants.is_empty() { write!( w, @@ -1014,7 +1020,9 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum render_stability_since(w, variant, it, cx.tcx()); } } - render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) + let def_id = it.def_id.expect_real(); + render_assoc_items(w, cx, it, def_id, AssocItemRender::All); + document_type_layout(w, cx, def_id); } fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) { @@ -1114,6 +1122,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St }); document(w, cx, it, None); + let mut fields = s .fields .iter() @@ -1152,7 +1161,9 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St } } } - render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) + let def_id = it.def_id.expect_real(); + render_assoc_items(w, cx, it, def_id, AssocItemRender::All); + document_type_layout(w, cx, def_id); } fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) { @@ -1522,3 +1533,62 @@ fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) { w.write_str("</div></details>"); } } + +fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { + if !cx.shared.show_type_layout { + 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, + "<div class=\"warning\"><p><strong>Note:</strong> Most layout information is \ + completely unstable and may be different between compiler versions and platforms. \ + The only exception is types with certain <code>repr(...)</code> attributes. \ + Please see the Rust Reference’s \ + <a href=\"https://doc.rust-lang.org/reference/type-layout.html\">“Type Layout”</a> \ + chapter for details on type layout guarantees.</p></div>" + ); + if ty_layout.layout.abi.is_unsized() { + writeln!(w, "<p><strong>Size:</strong> (unsized)</p>"); + } else { + let bytes = ty_layout.layout.size.bytes(); + writeln!( + w, + "<p><strong>Size:</strong> {size} byte{pl}</p>", + size = bytes, + pl = if bytes == 1 { "" } else { "s" }, + ); + } + } + // 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>"); +} diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index dc65e14ab37..04dc25341f4 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -448,14 +448,14 @@ function hideThemeButtonState() { } function getHelpElement(build) { - if (build !== false) { + if (build) { buildHelperPopup(); } return document.getElementById("help"); } function displayHelp(display, ev, help) { - if (display === true) { + if (display) { help = help ? help : getHelpElement(true); if (hasClass(help, "hidden")) { ev.preventDefault(); @@ -466,7 +466,7 @@ function hideThemeButtonState() { // No need to build the help popup if we want to hide it in case it hasn't been // built yet... help = help ? help : getHelpElement(false); - if (help && hasClass(help, "hidden") === false) { + if (help && !hasClass(help, "hidden")) { ev.preventDefault(); addClass(help, "hidden"); removeClass(document.body, "blur"); @@ -477,9 +477,9 @@ function hideThemeButtonState() { function handleEscape(ev) { var help = getHelpElement(false); var search = searchState.outputElement(); - if (hasClass(help, "hidden") === false) { + if (!hasClass(help, "hidden")) { displayHelp(false, ev, help); - } else if (hasClass(search, "hidden") === false) { + } else if (!hasClass(search, "hidden")) { searchState.clearInputTimeout(); ev.preventDefault(); searchState.hideResults(search); @@ -491,7 +491,7 @@ function hideThemeButtonState() { var disableShortcuts = getSettingValue("disable-shortcuts") === "true"; function handleShortcut(ev) { // Don't interfere with browser shortcuts - if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts === true) { + if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts) { return; } @@ -908,11 +908,11 @@ function hideThemeButtonState() { function implHider(addOrRemove, fullHide) { return function(n) { var shouldHide = - fullHide === true || - hasClass(n, "method") === true || - hasClass(n, "associatedconstant") === true; - if (shouldHide === true || hasClass(n, "type") === true) { - if (shouldHide === true) { + fullHide || + hasClass(n, "method") || + hasClass(n, "associatedconstant"); + if (shouldHide || hasClass(n, "type")) { + if (shouldHide) { if (addOrRemove) { addClass(n, "hidden-by-impl-hider"); } else { @@ -934,7 +934,7 @@ function hideThemeButtonState() { var relatedDoc; var action = mode; - if (hasClass(toggle.parentNode, "impl") === false) { + if (!hasClass(toggle.parentNode, "impl")) { relatedDoc = toggle.parentNode.nextElementSibling; if (hasClass(relatedDoc, "item-info")) { relatedDoc = relatedDoc.nextElementSibling; @@ -964,11 +964,11 @@ function hideThemeButtonState() { relatedDoc = parentElem; var docblock = relatedDoc.nextElementSibling; - while (hasClass(relatedDoc, "impl-items") === false) { + while (!hasClass(relatedDoc, "impl-items")) { relatedDoc = relatedDoc.nextElementSibling; } - if (!relatedDoc && hasClass(docblock, "docblock") === false) { + if (!relatedDoc && !hasClass(docblock, "docblock")) { return; } @@ -987,7 +987,7 @@ function hideThemeButtonState() { if (action === "show") { removeClass(relatedDoc, "fns-now-collapsed"); // Stability/deprecation/portability information is never hidden. - if (hasClass(docblock, "item-info") === false) { + if (!hasClass(docblock, "item-info")) { removeClass(docblock, "hidden-by-usual-hider"); } onEachLazy(toggle.childNodes, adjustToggle(false, dontApplyBlockRule)); @@ -996,7 +996,7 @@ function hideThemeButtonState() { addClass(relatedDoc, "fns-now-collapsed"); // Stability/deprecation/portability information should be shown even when detailed // info is hidden. - if (hasClass(docblock, "item-info") === false) { + if (!hasClass(docblock, "item-info")) { addClass(docblock, "hidden-by-usual-hider"); } onEachLazy(toggle.childNodes, adjustToggle(true, dontApplyBlockRule)); @@ -1045,7 +1045,7 @@ function hideThemeButtonState() { }); } - if (hideMethodDocs === true) { + if (hideMethodDocs) { onEachLazy(document.getElementsByClassName("method"), function(e) { var toggle = e.parentNode; if (toggle) { @@ -1132,7 +1132,7 @@ function hideThemeButtonState() { if (sidebar_menu) { sidebar_menu.onclick = function() { var sidebar = document.getElementsByClassName("sidebar")[0]; - if (hasClass(sidebar, "mobile") === true) { + if (hasClass(sidebar, "mobile")) { hideSidebar(); } else { showSidebar(); diff --git a/src/librustdoc/html/static/search.js b/src/librustdoc/html/static/search.js index 9fab435de49..b4f9d7b3740 100644 --- a/src/librustdoc/html/static/search.js +++ b/src/librustdoc/html/static/search.js @@ -146,23 +146,21 @@ window.initSearch = function(rawSearchIndex) { removeEmptyStringsFromArray(split); - function transformResults(results, isType) { + function transformResults(results) { var out = []; for (var i = 0, len = results.length; i < len; ++i) { if (results[i].id > -1) { var obj = searchIndex[results[i].id]; obj.lev = results[i].lev; - if (isType !== true || obj.type) { - var res = buildHrefAndPath(obj); - obj.displayPath = pathSplitter(res[0]); - obj.fullPath = obj.displayPath + obj.name; - // To be sure than it some items aren't considered as duplicate. - obj.fullPath += "|" + obj.ty; - obj.href = res[1]; - out.push(obj); - if (out.length >= MAX_RESULTS) { - break; - } + var res = buildHrefAndPath(obj); + obj.displayPath = pathSplitter(res[0]); + obj.fullPath = obj.displayPath + obj.name; + // To be sure than it some items aren't considered as duplicate. + obj.fullPath += "|" + obj.ty; + obj.href = res[1]; + out.push(obj); + if (out.length >= MAX_RESULTS) { + break; } } } @@ -266,9 +264,7 @@ window.initSearch = function(rawSearchIndex) { path = result.item.path.toLowerCase(), parent = result.item.parent; - if (isType !== true && - validateResult(name, path, split, parent) === false) - { + if (!isType && !validateResult(name, path, split, parent)) { result.id = -1; } } @@ -352,7 +348,7 @@ window.initSearch = function(rawSearchIndex) { var lev_distance = MAX_LEV_DISTANCE + 1; var len, x, firstGeneric; if (obj[NAME] === val.name) { - if (literalSearch === true) { + if (literalSearch) { if (val.generics && val.generics.length !== 0) { if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length >= val.generics.length) { @@ -373,7 +369,7 @@ window.initSearch = function(rawSearchIndex) { break; } } - if (allFound === true) { + if (allFound) { return true; } } else { @@ -394,7 +390,7 @@ window.initSearch = function(rawSearchIndex) { } } // Names didn't match so let's check if one of the generic types could. - if (literalSearch === true) { + if (literalSearch) { if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { return obj[GENERICS_DATA].some( function(name) { @@ -429,12 +425,12 @@ window.initSearch = function(rawSearchIndex) { var length = obj.type[INPUTS_DATA].length; for (var i = 0; i < length; i++) { var tmp = obj.type[INPUTS_DATA][i]; - if (typePassesFilter(typeFilter, tmp[1]) === false) { + if (!typePassesFilter(typeFilter, tmp[1])) { continue; } tmp = checkType(tmp, val, literalSearch); - if (literalSearch === true) { - if (tmp === true) { + if (literalSearch) { + if (tmp) { return true; } continue; @@ -445,7 +441,7 @@ window.initSearch = function(rawSearchIndex) { } } } - return literalSearch === true ? false : lev_distance; + return literalSearch ? false : lev_distance; } function checkReturned(obj, val, literalSearch, typeFilter) { @@ -458,12 +454,12 @@ window.initSearch = function(rawSearchIndex) { } for (var x = 0, len = ret.length; x < len; ++x) { var tmp = ret[x]; - if (typePassesFilter(typeFilter, tmp[1]) === false) { + if (!typePassesFilter(typeFilter, tmp[1])) { continue; } tmp = checkType(tmp, val, literalSearch); - if (literalSearch === true) { - if (tmp === true) { + if (literalSearch) { + if (tmp) { return true; } continue; @@ -474,7 +470,7 @@ window.initSearch = function(rawSearchIndex) { } } } - return literalSearch === true ? false : lev_distance; + return literalSearch ? false : lev_distance; } function checkPath(contains, lastElem, ty) { @@ -507,7 +503,7 @@ window.initSearch = function(rawSearchIndex) { } lev_total += lev; } - if (aborted === false) { + if (!aborted) { ret_lev = Math.min(ret_lev, Math.round(lev_total / clength)); } } @@ -634,14 +630,14 @@ window.initSearch = function(rawSearchIndex) { dontValidate: true, }; } - if (in_args === true && results_in_args[fullId] === undefined) { + if (in_args && results_in_args[fullId] === undefined) { results_in_args[fullId] = { id: i, index: -1, dontValidate: true, }; } - if (returned === true && results_returned[fullId] === undefined) { + if (returned && results_returned[fullId] === undefined) { results_returned[fullId] = { id: i, index: -1, @@ -676,7 +672,7 @@ window.initSearch = function(rawSearchIndex) { fullId = ty.id; returned = checkReturned(ty, output, true, NO_TYPE_FILTER); - if (output.name === "*" || returned === true) { + if (output.name === "*" || returned) { in_args = false; var is_module = false; @@ -684,26 +680,26 @@ window.initSearch = function(rawSearchIndex) { is_module = true; } else { var allFound = true; - for (it = 0, len = inputs.length; allFound === true && it < len; it++) { + for (it = 0, len = inputs.length; allFound && it < len; it++) { allFound = checkType(type, inputs[it], true); } in_args = allFound; } - if (in_args === true) { + if (in_args) { results_in_args[fullId] = { id: i, index: -1, dontValidate: true, }; } - if (returned === true) { + if (returned) { results_returned[fullId] = { id: i, index: -1, dontValidate: true, }; } - if (is_module === true) { + if (is_module) { results[fullId] = { id: i, index: -1, @@ -763,10 +759,10 @@ window.initSearch = function(rawSearchIndex) { } } if ((lev = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) { - if (typePassesFilter(typeFilter, ty.ty) === false) { - lev = MAX_LEV_DISTANCE + 1; - } else { + if (typePassesFilter(typeFilter, ty.ty)) { lev += 1; + } else { + lev = MAX_LEV_DISTANCE + 1; } } in_args = findArg(ty, valGenerics, false, typeFilter); @@ -821,7 +817,7 @@ window.initSearch = function(rawSearchIndex) { var ret = { "in_args": sortResults(results_in_args, true), "returned": sortResults(results_returned, true), - "others": sortResults(results), + "others": sortResults(results, false), }; handleAliases(ret, query, filterCrates); return ret; @@ -1263,7 +1259,7 @@ window.initSearch = function(rawSearchIndex) { if (query.query.length === 0) { return; } - if (forced !== true && query.id === currentResults) { + if (!forced && query.id === currentResults) { if (query.query.length > 0) { searchState.putBackSearch(searchState.input); } diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js index 42b54e4cc1e..81df5411896 100644 --- a/src/librustdoc/html/static/source-script.js +++ b/src/librustdoc/html/static/source-script.js @@ -44,7 +44,7 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { if (elem.dirs) { for (i = 0, len = elem.dirs.length; i < len; ++i) { if (createDirEntry(elem.dirs[i], folders, fullPath, currentFile, - hasFoundFile) === true) { + hasFoundFile)) { addClass(name, "expand"); hasFoundFile = true; } @@ -59,8 +59,7 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { var file = document.createElement("a"); file.innerText = elem.files[i]; file.href = window.rootPath + "src/" + fullPath + elem.files[i] + ".html"; - if (hasFoundFile === false && - currentFile === fullPath + elem.files[i]) { + if (!hasFoundFile && currentFile === fullPath + elem.files[i]) { file.className = "selected"; addClass(name, "expand"); hasFoundFile = true; @@ -72,7 +71,7 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { children.appendChild(files); parent.appendChild(name); parent.appendChild(children); - return hasFoundFile === true && currentFile.startsWith(fullPath); + return hasFoundFile && currentFile.startsWith(fullPath); } function toggleSidebar() { @@ -116,7 +115,7 @@ function createSidebarToggle() { // This function is called from "source-files.js", generated in `html/render/mod.rs`. // eslint-disable-next-line no-unused-vars function createSourceSidebar() { - if (window.rootPath.endsWith("/") === false) { + if (!window.rootPath.endsWith("/")) { window.rootPath += "/"; } var main = document.getElementById("main"); diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index 2ed87fdedae..208afd2e732 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -59,15 +59,15 @@ function onEach(arr, func, reversed) { if (arr && arr.length > 0 && func) { var length = arr.length; var i; - if (reversed !== true) { - for (i = 0; i < length; ++i) { - if (func(arr[i]) === true) { + if (reversed) { + for (i = length - 1; i >= 0; --i) { + if (func(arr[i])) { return true; } } } else { - for (i = length - 1; i >= 0; --i) { - if (func(arr[i]) === true) { + for (i = 0; i < length; ++i) { + if (func(arr[i])) { return true; } } @@ -111,7 +111,7 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) { // If this new value comes from a system setting or from the previously // saved theme, no need to save it. - if (saveTheme === true) { + if (saveTheme) { updateLocalStorage("rustdoc-theme", newTheme); } @@ -131,7 +131,7 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) { return true; } }); - if (found === true) { + if (found) { styleElem.href = newHref; } } |
