From 74e3d9903695236bbff39edcfc1516671c1632a1 Mon Sep 17 00:00:00 2001 From: Andrew Pollack Date: Mon, 19 Sep 2022 21:43:21 +0000 Subject: [PATCH 01/13] Adding needs-unwind to nicer-assert-messages compiler ui tests --- .../ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs | 1 + .../rfc-2011-nicer-assert-messages/all-not-available-cases.rs | 1 + .../assert-without-captures-does-not-create-unnecessary-code.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs index f538ec643902e..b8b6f0846bb44 100644 --- a/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs +++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs @@ -2,6 +2,7 @@ // ignore-tidy-linelength // only-x86_64 // run-pass +// needs-unwind Asserting on contents of error message #![allow(path_statements, unused_allocation)] #![feature(box_syntax, core_intrinsics, generic_assert, generic_assert_internals)] diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs index 86697c58fbcf1..d46f396ee2970 100644 --- a/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs +++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs @@ -2,6 +2,7 @@ // ignore-tidy-linelength // only-x86_64 // run-pass +// needs-unwind Asserting on contents of error message #![feature(core_intrinsics, generic_assert, generic_assert_internals)] diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs index 06c4993ec30d6..1f5a29ab524f2 100644 --- a/src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs +++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs @@ -1,6 +1,7 @@ // aux-build:common.rs // only-x86_64 // run-pass +// needs-unwind Asserting on contents of error message #![feature(core_intrinsics, generic_assert, generic_assert_internals)] From 3a4dc6130307bdaa92b5cd8aae514bdbd999e323 Mon Sep 17 00:00:00 2001 From: Andrew Pollack Date: Mon, 19 Sep 2022 21:00:10 +0000 Subject: [PATCH 02/13] Adding ignore fuchsia tests for Backtrace, ErrorKind cases --- src/test/ui/backtrace.rs | 1 + .../ui/panics/issue-47429-short-backtraces.legacy.run.stderr | 2 +- src/test/ui/panics/issue-47429-short-backtraces.rs | 1 + src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr | 2 +- src/test/ui/panics/runtime-switch.legacy.run.stderr | 2 +- src/test/ui/panics/runtime-switch.rs | 1 + src/test/ui/panics/runtime-switch.v0.run.stderr | 2 +- src/test/ui/process/process-spawn-nonexistent.rs | 1 + src/test/ui/runtime/backtrace-debuginfo.rs | 1 + src/test/ui/std-backtrace.rs | 1 + 10 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/test/ui/backtrace.rs b/src/test/ui/backtrace.rs index e2ac43fffc9ef..dd73dd9886a3b 100644 --- a/src/test/ui/backtrace.rs +++ b/src/test/ui/backtrace.rs @@ -4,6 +4,7 @@ // ignore-openbsd no support for libbacktrace without filename // ignore-sgx no processes // ignore-msvc see #62897 and `backtrace-debuginfo.rs` test +// ignore-fuchsia Backtraces not symbolized // compile-flags:-g // compile-flags:-Cstrip=none diff --git a/src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr b/src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr index b6223b93764f4..ac4ed8225bd82 100644 --- a/src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr +++ b/src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:22:5 +thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:23:5 stack backtrace: 0: std::panicking::begin_panic 1: issue_47429_short_backtraces::main diff --git a/src/test/ui/panics/issue-47429-short-backtraces.rs b/src/test/ui/panics/issue-47429-short-backtraces.rs index f338ace6bb0d1..58d0fa62c34e9 100644 --- a/src/test/ui/panics/issue-47429-short-backtraces.rs +++ b/src/test/ui/panics/issue-47429-short-backtraces.rs @@ -12,6 +12,7 @@ // ignore-wasm no panic or subprocess support // ignore-emscripten no panic or subprocess support // ignore-sgx no subprocess support +// ignore-fuchsia Backtraces not symbolized // NOTE(eddyb) output differs between symbol mangling schemes // revisions: legacy v0 diff --git a/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr b/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr index c2bea44924983..65401fe1c3d80 100644 --- a/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr +++ b/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:22:5 +thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:23:5 stack backtrace: 0: std::panicking::begin_panic::<&str> 1: issue_47429_short_backtraces::main diff --git a/src/test/ui/panics/runtime-switch.legacy.run.stderr b/src/test/ui/panics/runtime-switch.legacy.run.stderr index f282f18839c64..0f76551630cca 100644 --- a/src/test/ui/panics/runtime-switch.legacy.run.stderr +++ b/src/test/ui/panics/runtime-switch.legacy.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at 'explicit panic', $DIR/runtime-switch.rs:25:5 +thread 'main' panicked at 'explicit panic', $DIR/runtime-switch.rs:26:5 stack backtrace: 0: std::panicking::begin_panic 1: runtime_switch::main diff --git a/src/test/ui/panics/runtime-switch.rs b/src/test/ui/panics/runtime-switch.rs index 37ef961e2d019..882340e495c15 100644 --- a/src/test/ui/panics/runtime-switch.rs +++ b/src/test/ui/panics/runtime-switch.rs @@ -12,6 +12,7 @@ // ignore-wasm no panic or subprocess support // ignore-emscripten no panic or subprocess support // ignore-sgx no subprocess support +// ignore-fuchsia Backtrace not symbolized // NOTE(eddyb) output differs between symbol mangling schemes // revisions: legacy v0 diff --git a/src/test/ui/panics/runtime-switch.v0.run.stderr b/src/test/ui/panics/runtime-switch.v0.run.stderr index 7ce9722e5edf1..a4ae441317dac 100644 --- a/src/test/ui/panics/runtime-switch.v0.run.stderr +++ b/src/test/ui/panics/runtime-switch.v0.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at 'explicit panic', $DIR/runtime-switch.rs:25:5 +thread 'main' panicked at 'explicit panic', $DIR/runtime-switch.rs:26:5 stack backtrace: 0: std::panicking::begin_panic::<&str> 1: runtime_switch::main diff --git a/src/test/ui/process/process-spawn-nonexistent.rs b/src/test/ui/process/process-spawn-nonexistent.rs index a513722639adb..9dd608986df16 100644 --- a/src/test/ui/process/process-spawn-nonexistent.rs +++ b/src/test/ui/process/process-spawn-nonexistent.rs @@ -1,6 +1,7 @@ // run-pass // ignore-emscripten no processes // ignore-sgx no processes +// ignore-fuchsia ErrorKind not translated use std::io::ErrorKind; use std::process::Command; diff --git a/src/test/ui/runtime/backtrace-debuginfo.rs b/src/test/ui/runtime/backtrace-debuginfo.rs index 7c9f1a7f2f49b..8b5466b6cfa0b 100644 --- a/src/test/ui/runtime/backtrace-debuginfo.rs +++ b/src/test/ui/runtime/backtrace-debuginfo.rs @@ -12,6 +12,7 @@ // ignore-pretty issue #37195 // ignore-emscripten spawning processes is not supported // ignore-sgx no processes +// ignore-fuchsia Backtrace not symbolized, trace different line alignment use std::env; diff --git a/src/test/ui/std-backtrace.rs b/src/test/ui/std-backtrace.rs index 3f8306baf8a21..59574b471dda4 100644 --- a/src/test/ui/std-backtrace.rs +++ b/src/test/ui/std-backtrace.rs @@ -4,6 +4,7 @@ // ignore-openbsd no support for libbacktrace without filename // ignore-sgx no processes // ignore-msvc see #62897 and `backtrace-debuginfo.rs` test +// ignore-fuchsia Backtraces not symbolized // compile-flags:-g // compile-flags:-Cstrip=none From 5343dc7c99f8c3d64658e4c7011dd871b2033e3d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 20 Sep 2022 16:46:06 +0200 Subject: [PATCH 03/13] Generate sidebar elements for the "All items" page --- src/librustdoc/html/render/context.rs | 24 +++++--- src/librustdoc/html/render/mod.rs | 88 +++++++++++++++++++++------ 2 files changed, 86 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 62def4a94e8dc..22a6fcd316aa0 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -17,8 +17,8 @@ use super::print_item::{full_path, item_path, print_item}; use super::search_index::build_index; use super::write_shared::write_shared; use super::{ - collect_spans_and_sources, print_sidebar, scrape_examples_help, AllTypes, LinkFromSrc, NameDoc, - StylePath, BASIC_KEYWORDS, + collect_spans_and_sources, print_sidebar, scrape_examples_help, sidebar_module_like, AllTypes, + LinkFromSrc, NameDoc, StylePath, BASIC_KEYWORDS, }; use crate::clean::{self, types::ExternalLocation, ExternalCrate}; @@ -597,16 +597,24 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { keywords: BASIC_KEYWORDS, resource_suffix: &shared.resource_suffix, }; - let sidebar = if shared.cache.crate_version.is_some() { - format!("

Crate {}

", crate_name) - } else { - String::new() - }; let all = shared.all.replace(AllTypes::new()); + let mut sidebar = Buffer::html(); + if shared.cache.crate_version.is_some() { + write!(sidebar, "

Crate {}

", crate_name) + }; + + let mut items = Buffer::html(); + sidebar_module_like(&mut items, all.item_sections()); + if !items.is_empty() { + sidebar.push_str("
"); + sidebar.push_buffer(items); + sidebar.push_str("
"); + } + let v = layout::render( &shared.layout, &page, - sidebar, + sidebar.into_inner(), |buf: &mut Buffer| all.print(buf), &shared.style_files, ); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index ced0ebdbb864a..fbe905fb0336e 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -290,9 +290,56 @@ impl AllTypes { }; } } -} -impl AllTypes { + fn item_sections(&self) -> FxHashSet { + let mut sections = FxHashSet::default(); + + if !self.structs.is_empty() { + sections.insert(ItemSection::Structs); + } + if !self.enums.is_empty() { + sections.insert(ItemSection::Enums); + } + if !self.unions.is_empty() { + sections.insert(ItemSection::Unions); + } + if !self.primitives.is_empty() { + sections.insert(ItemSection::PrimitiveTypes); + } + if !self.traits.is_empty() { + sections.insert(ItemSection::Traits); + } + if !self.macros.is_empty() { + sections.insert(ItemSection::Macros); + } + if !self.functions.is_empty() { + sections.insert(ItemSection::Functions); + } + if !self.typedefs.is_empty() { + sections.insert(ItemSection::TypeDefinitions); + } + if !self.opaque_tys.is_empty() { + sections.insert(ItemSection::OpaqueTypes); + } + if !self.statics.is_empty() { + sections.insert(ItemSection::Statics); + } + if !self.constants.is_empty() { + sections.insert(ItemSection::Constants); + } + if !self.attributes.is_empty() { + sections.insert(ItemSection::AttributeMacros); + } + if !self.derives.is_empty() { + sections.insert(ItemSection::DeriveMacros); + } + if !self.trait_aliases.is_empty() { + sections.insert(ItemSection::TraitAliases); + } + + sections + } + fn print(self, f: &mut Buffer) { fn print_entries(f: &mut Buffer, e: &FxHashSet, title: &str) { if !e.is_empty() { @@ -2468,7 +2515,7 @@ fn sidebar_enum(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, e: &clean: } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -enum ItemSection { +pub(crate) enum ItemSection { Reexports, PrimitiveTypes, Modules, @@ -2620,25 +2667,11 @@ fn item_ty_to_section(ty: ItemType) -> ItemSection { } } -fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) { +pub(crate) fn sidebar_module_like(buf: &mut Buffer, item_sections_in_use: FxHashSet) { use std::fmt::Write as _; let mut sidebar = String::new(); - let item_sections_in_use: FxHashSet<_> = items - .iter() - .filter(|it| { - !it.is_stripped() - && it - .name - .or_else(|| { - if let clean::ImportItem(ref i) = *it.kind && - let clean::ImportKind::Simple(s) = i.kind { Some(s) } else { None } - }) - .is_some() - }) - .map(|it| item_ty_to_section(it.type_())) - .collect(); for &sec in ItemSection::ALL.iter().filter(|sec| item_sections_in_use.contains(sec)) { let _ = write!(sidebar, "
  • {}
  • ", sec.id(), sec.name()); } @@ -2656,6 +2689,25 @@ fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) { } } +fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) { + let item_sections_in_use: FxHashSet<_> = items + .iter() + .filter(|it| { + !it.is_stripped() + && it + .name + .or_else(|| { + if let clean::ImportItem(ref i) = *it.kind && + let clean::ImportKind::Simple(s) = i.kind { Some(s) } else { None } + }) + .is_some() + }) + .map(|it| item_ty_to_section(it.type_())) + .collect(); + + sidebar_module_like(buf, item_sections_in_use); +} + fn sidebar_foreign_type(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item) { let mut sidebar = Buffer::new(); sidebar_assoc_items(cx, &mut sidebar, it); From 4a3109e8b7a30f18ef8a98308b5e9adadf2e40a9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 20 Sep 2022 17:10:38 +0200 Subject: [PATCH 04/13] Add test for sidebar elements in the "All types" page --- src/test/rustdoc/sidebar-all-page.rs | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/test/rustdoc/sidebar-all-page.rs diff --git a/src/test/rustdoc/sidebar-all-page.rs b/src/test/rustdoc/sidebar-all-page.rs new file mode 100644 index 0000000000000..e74b981de6444 --- /dev/null +++ b/src/test/rustdoc/sidebar-all-page.rs @@ -0,0 +1,35 @@ +#![crate_name = "foo"] + +#![feature(rustdoc_internals)] + +// @has 'foo/all.html' +// @has - '//*[@class="sidebar-elems"]//li' 'Structs' +// @has - '//*[@class="sidebar-elems"]//li' 'Enums' +// @has - '//*[@class="sidebar-elems"]//li' 'Unions' +// @has - '//*[@class="sidebar-elems"]//li' 'Functions' +// @has - '//*[@class="sidebar-elems"]//li' 'Traits' +// @has - '//*[@class="sidebar-elems"]//li' 'Macros' +// @has - '//*[@class="sidebar-elems"]//li' 'Type Definitions' +// @has - '//*[@class="sidebar-elems"]//li' 'Constants' +// @has - '//*[@class="sidebar-elems"]//li' 'Statics' +// @has - '//*[@class="sidebar-elems"]//li' 'Primitive Types' + +pub struct Foo; +pub enum Enum { + A, +} +pub union Bar { + a: u8, + b: u16, +} +pub fn foo() {} +pub trait Trait {} +#[macro_export] +macro_rules! foo { + () => {} +} +pub type Type = u8; +pub const FOO: u8 = 0; +pub static BAR: u8 = 0; +#[doc(primitive = "u8")] +mod u8 {} From c291d2adecbf13685ed321d7699ba7bb0b60806a Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Tue, 20 Sep 2022 11:12:03 -0500 Subject: [PATCH 05/13] Clarify Path::extension() semantics in docs abstract State up-front and center what shape the returned extension will have, without making the user read through the description and examples. Rationale: Various frameworks and libraries for different platforms have their different conventions as to whether an "extension" is ".ext" or just "ext" and anyone that's had to deal with this ambiguity in the past is always double- or triple-checking to make sure the function call returns an extension that matches the expected semantics. Offer the answer to this important question right off the bat instead of making them dig to find it. --- library/std/src/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 5dfeb517a1996..4f9dff1ef0353 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2401,7 +2401,7 @@ impl Path { self.file_name().map(split_file_at_dot).and_then(|(before, _after)| Some(before)) } - /// Extracts the extension of [`self.file_name`], if possible. + /// Extracts the extension (without the leading dot) of [`self.file_name`], if possible. /// /// The extension is: /// From 83e6128b577649384ef4bd137223bcffe5c8a5b0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 20 Sep 2022 16:39:39 +0000 Subject: [PATCH 06/13] Better binder treatment --- .../src/infer/error_reporting/mod.rs | 2 +- src/test/ui/suggestions/issue-101984.rs | 27 +++++++++++++++++++ src/test/ui/suggestions/issue-101984.stderr | 14 ++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/issue-101984.rs create mode 100644 src/test/ui/suggestions/issue-101984.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 546ab82bc238a..18255a5089c8d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2765,7 +2765,7 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { where T: relate::Relate<'tcx>, { - Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?)) + Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } fn consts( diff --git a/src/test/ui/suggestions/issue-101984.rs b/src/test/ui/suggestions/issue-101984.rs new file mode 100644 index 0000000000000..5f7ecb77e0ed4 --- /dev/null +++ b/src/test/ui/suggestions/issue-101984.rs @@ -0,0 +1,27 @@ +use std::marker::PhantomData; + +type Component = fn(&()); + +struct Wrapper { + router: Router<(Component, Box)>, +} + +struct Match(PhantomData); + +struct Router(PhantomData); + +impl Router { + pub fn at(&self) -> Result, ()> { + todo!() + } +} + +impl Wrapper { + fn at(&self, path: &str) -> Result<(Component, Box), ()> { + let (cmp, router) = self.router.at()?; + //~^ ERROR mismatched types + todo!() + } +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-101984.stderr b/src/test/ui/suggestions/issue-101984.stderr new file mode 100644 index 0000000000000..c744c62d11f9b --- /dev/null +++ b/src/test/ui/suggestions/issue-101984.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/issue-101984.rs:21:13 + | +LL | let (cmp, router) = self.router.at()?; + | ^^^^^^^^^^^^^ ----------------- this expression has type `Match<&(for<'r> fn(&'r ()), Box)>` + | | + | expected struct `Match`, found tuple + | + = note: expected struct `Match<&(for<'r> fn(&'r ()), Box)>` + found tuple `(_, _)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From d355b0e1848e41621f55e9e71e63f6383d1df7d5 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 20 Sep 2022 12:07:35 -0700 Subject: [PATCH 07/13] rustdoc: remove unnecessary `max-width` on headers This code was added in 003b2bc1c65251ec2fc80b78ed91c43fb35402ec to prevent these headers from overlapping `.out-of-band` side items. That stopped being a problem when 3f92ff34b5a2fe8dd1a32aa27d437519e63782f0 switched rustdoc over to using `float`, rather than `position: absolute`, to implement this. --- src/librustdoc/html/static/css/rustdoc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index f458a4f59ae82..eac6e474870a6 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -684,7 +684,6 @@ h2.location a { } .method > .code-header, .trait-impl > .code-header { - max-width: calc(100% - 41px); display: block; } From 592ae2073b7498adf3948d53017907bbbb0c00d1 Mon Sep 17 00:00:00 2001 From: Andrew Pollack Date: Tue, 20 Sep 2022 19:46:27 +0000 Subject: [PATCH 08/13] Adding needs-unwind to tests involving changing memory size of Futures/Closures --- src/test/ui/async-await/async-fn-size-moved-locals.rs | 1 + src/test/ui/async-await/async-fn-size-uninit-locals.rs | 1 + src/test/ui/generator/size-moved-locals.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/test/ui/async-await/async-fn-size-moved-locals.rs b/src/test/ui/async-await/async-fn-size-moved-locals.rs index 15566256600df..9e3794b0484e7 100644 --- a/src/test/ui/async-await/async-fn-size-moved-locals.rs +++ b/src/test/ui/async-await/async-fn-size-moved-locals.rs @@ -8,6 +8,7 @@ // See issue #59123 for a full explanation. // ignore-emscripten (sizes don't match) +// needs-unwind Size of Futures change on panic=abort // run-pass // edition:2018 diff --git a/src/test/ui/async-await/async-fn-size-uninit-locals.rs b/src/test/ui/async-await/async-fn-size-uninit-locals.rs index 28b3280fed5f6..5461726935457 100644 --- a/src/test/ui/async-await/async-fn-size-uninit-locals.rs +++ b/src/test/ui/async-await/async-fn-size-uninit-locals.rs @@ -5,6 +5,7 @@ // being reflected in the size. // ignore-emscripten (sizes don't match) +// needs-unwind Size of Futures change on panic=abort // run-pass // edition:2018 diff --git a/src/test/ui/generator/size-moved-locals.rs b/src/test/ui/generator/size-moved-locals.rs index 3c756a86fc5a5..601a314182876 100644 --- a/src/test/ui/generator/size-moved-locals.rs +++ b/src/test/ui/generator/size-moved-locals.rs @@ -12,6 +12,7 @@ // edition:2018 // ignore-wasm32 issue #62807 // ignore-asmjs issue #62807 +// needs-unwind Size of Closures change on panic=abort #![feature(generators, generator_trait)] From 27a420f251d8efe5674176cda77032a859eddfb5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 20 Sep 2022 23:23:03 +0200 Subject: [PATCH 09/13] Unify generation of section on "All items" page with all other pages --- src/librustdoc/html/render/mod.rs | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index fbe905fb0336e..7e5e4df43d291 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -341,15 +341,15 @@ impl AllTypes { } fn print(self, f: &mut Buffer) { - fn print_entries(f: &mut Buffer, e: &FxHashSet, title: &str) { + fn print_entries(f: &mut Buffer, e: &FxHashSet, kind: ItemSection) { if !e.is_empty() { let mut e: Vec<&ItemEntry> = e.iter().collect(); e.sort(); write!( f, - "

    {}

      ", - title.replace(' ', "-"), // IDs cannot contain whitespaces. - title + "

      {title}

        ", + id = kind.id(), + title = kind.name(), ); for s in e.iter() { @@ -367,20 +367,20 @@ impl AllTypes { ); // Note: print_entries does not escape the title, because we know the current set of titles // doesn't require escaping. - print_entries(f, &self.structs, "Structs"); - print_entries(f, &self.enums, "Enums"); - print_entries(f, &self.unions, "Unions"); - print_entries(f, &self.primitives, "Primitives"); - print_entries(f, &self.traits, "Traits"); - print_entries(f, &self.macros, "Macros"); - print_entries(f, &self.attributes, "Attribute Macros"); - print_entries(f, &self.derives, "Derive Macros"); - print_entries(f, &self.functions, "Functions"); - print_entries(f, &self.typedefs, "Typedefs"); - print_entries(f, &self.trait_aliases, "Trait Aliases"); - print_entries(f, &self.opaque_tys, "Opaque Types"); - print_entries(f, &self.statics, "Statics"); - print_entries(f, &self.constants, "Constants"); + print_entries(f, &self.structs, ItemSection::Structs); + print_entries(f, &self.enums, ItemSection::Enums); + print_entries(f, &self.unions, ItemSection::Unions); + print_entries(f, &self.primitives, ItemSection::PrimitiveTypes); + print_entries(f, &self.traits, ItemSection::Traits); + print_entries(f, &self.macros, ItemSection::Macros); + print_entries(f, &self.attributes, ItemSection::AttributeMacros); + print_entries(f, &self.derives, ItemSection::DeriveMacros); + print_entries(f, &self.functions, ItemSection::Functions); + print_entries(f, &self.typedefs, ItemSection::TypeDefinitions); + print_entries(f, &self.trait_aliases, ItemSection::TraitAliases); + print_entries(f, &self.opaque_tys, ItemSection::OpaqueTypes); + print_entries(f, &self.statics, ItemSection::Statics); + print_entries(f, &self.constants, ItemSection::Constants); } } From ad52e325c650556ca9d7476fb0d0e23e45d2b9ae Mon Sep 17 00:00:00 2001 From: Andrew Pollack Date: Tue, 20 Sep 2022 21:37:08 +0000 Subject: [PATCH 10/13] Adding ignore fuchsia tests for execvp --- src/test/ui/command/command-exec.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/command/command-exec.rs b/src/test/ui/command/command-exec.rs index 0af87214f9523..032dad1840d47 100644 --- a/src/test/ui/command/command-exec.rs +++ b/src/test/ui/command/command-exec.rs @@ -5,6 +5,7 @@ // ignore-pretty issue #37199 // ignore-emscripten no processes // ignore-sgx no processes +// ignore-fuchsia no execvp syscall provided #![feature(process_exec)] From b7dc9341b5a57e120470f8bb0e4831bffab63c89 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 20 Sep 2022 14:29:14 +1000 Subject: [PATCH 11/13] Wrap some long comment lines. --- compiler/rustc_metadata/src/rmeta/encoder.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 5a60ea794edd8..2bc958df4a74c 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -261,10 +261,10 @@ impl<'a, 'tcx> Encodable> for Span { // This allows us to avoid loading the dependencies of proc-macro crates: all of // the information we need to decode `Span`s is stored in the proc-macro crate. let (tag, metadata_index) = if source_file.is_imported() && !s.is_proc_macro { - // To simplify deserialization, we 'rebase' this span onto the crate it originally came from - // (the crate that 'owns' the file it references. These rebased 'lo' and 'hi' values - // are relative to the source map information for the 'foreign' crate whose CrateNum - // we write into the metadata. This allows `imported_source_files` to binary + // To simplify deserialization, we 'rebase' this span onto the crate it originally came + // from (the crate that 'owns' the file it references. These rebased 'lo' and 'hi' + // values are relative to the source map information for the 'foreign' crate whose + // CrateNum we write into the metadata. This allows `imported_source_files` to binary // search through the 'foreign' crate's source map information, using the // deserialized 'lo' and 'hi' values directly. // @@ -672,12 +672,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let exported_symbols_bytes = self.position() - i; // Encode the hygiene data, - // IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The process - // of encoding other items (e.g. `optimized_mir`) may cause us to load - // data from the incremental cache. If this causes us to deserialize a `Span`, - // then we may load additional `SyntaxContext`s into the global `HygieneData`. - // Therefore, we need to encode the hygiene data last to ensure that we encode - // any `SyntaxContext`s that might be used. + // IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The + // process of encoding other items (e.g. `optimized_mir`) may cause us to load data from + // the incremental cache. If this causes us to deserialize a `Span`, then we may load + // additional `SyntaxContext`s into the global `HygieneData`. Therefore, we need to encode + // the hygiene data last to ensure that we encode any `SyntaxContext`s that might be used. i = self.position(); let (syntax_contexts, expn_data, expn_hashes) = self.encode_hygiene(); let hygiene_bytes = self.position() - i; From e7467132ef44bbd3be7805bd518b778e79adacd1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 20 Sep 2022 17:04:55 -0700 Subject: [PATCH 12/13] Update books --- src/doc/book | 2 +- src/doc/embedded-book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/doc/book b/src/doc/book index 0a5421ceb2383..f1e5ad844d0c6 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 0a5421ceb238357b3634fb75234eba4d1dad643c +Subproject commit f1e5ad844d0c61738006cdef26227beeb136948e diff --git a/src/doc/embedded-book b/src/doc/embedded-book index befe684087431..4ce51cb7441a6 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit befe6840874311635c417cf731377f07234ee373 +Subproject commit 4ce51cb7441a6f02b5bf9b07b2eb755c21ab7954 diff --git a/src/doc/nomicon b/src/doc/nomicon index d880e6ac2acf1..f53bfa0569292 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit d880e6ac2acf133dce640da24b9fb692844f02d4 +Subproject commit f53bfa056929217870a5d2df1366d2e7ba35096d diff --git a/src/doc/reference b/src/doc/reference index f62e93c28323e..a7cdac33ca735 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit f62e93c28323ed9637d0a205a0c256498674a509 +Subproject commit a7cdac33ca7356ad49d5c2b5e2c5010889b33eee diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 03301f8ae55fa..767a6bd9727a5 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 03301f8ae55fa6f20f7ea152a517598e6db2cdb7 +Subproject commit 767a6bd9727a596d7cfdbaeee475e65b2670ea3a diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 04892c1a6fc14..f587d6e7cddea 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 04892c1a6fc145602ac7367945fda9d4ee83c9fb +Subproject commit f587d6e7cddeaa3cf0a33ec1e368df1a408fa0aa From a7b35b5618da9c557a8d318aa7839a96fecb4d05 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 20 Sep 2022 16:08:25 +1000 Subject: [PATCH 13/13] Overhaul `-Zmeta-stats` output. It's now much more like the `-Zhir-stats` output. - Each line is preceded with `meta-stats`, which makes the provenance clearer and allows filtering of the output. - Sections are now sorted in reverse order of size. - Column headings avoid the need to repeat the word "bytes" on every line. - Long numbers now have `_` separators for easier reading. - Consistent use of '-' within section labels, rather than a mix of '-', '_', and ' '. The code itself is shorter and easier to read thanks to: - the `stat` macro, which encapsulates each section's encoding, avoids some boilerplate, and removes the need for some low-value comments; - the `stats` vector, which replaces dozens of local variables. --- compiler/rustc_metadata/src/rmeta/encoder.rs | 344 ++++++++----------- 1 file changed, 142 insertions(+), 202 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 2bc958df4a74c..67c28461ce5cf 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -28,6 +28,7 @@ use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt}; +use rustc_middle::util::common::to_readable_str; use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder}; use rustc_session::config::CrateType; use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib}; @@ -554,78 +555,56 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_crate_root(&mut self) -> LazyValue { let tcx = self.tcx; - let mut i = 0; - let preamble_bytes = self.position() - i; - - // Encode the crate deps - i = self.position(); - let crate_deps = self.encode_crate_deps(); - let dylib_dependency_formats = self.encode_dylib_dependency_formats(); - let dep_bytes = self.position() - i; - - // Encode the lib features. - i = self.position(); - let lib_features = self.encode_lib_features(); - let lib_feature_bytes = self.position() - i; - - // Encode the stability implications. - i = self.position(); - let stability_implications = self.encode_stability_implications(); - let stability_implications_bytes = self.position() - i; - - // Encode the language items. - i = self.position(); - let lang_items = self.encode_lang_items(); - let lang_items_missing = self.encode_lang_items_missing(); - let lang_item_bytes = self.position() - i; - - // Encode the diagnostic items. - i = self.position(); - let diagnostic_items = self.encode_diagnostic_items(); - let diagnostic_item_bytes = self.position() - i; - - // Encode the native libraries used - i = self.position(); - let native_libraries = self.encode_native_libraries(); - let native_lib_bytes = self.position() - i; - - i = self.position(); - let foreign_modules = self.encode_foreign_modules(); - let foreign_modules_bytes = self.position() - i; - - // Encode DefPathTable - i = self.position(); - self.encode_def_path_table(); - let def_path_table_bytes = self.position() - i; + let mut stats: Vec<(&'static str, usize)> = Vec::with_capacity(32); + + macro_rules! stat { + ($label:literal, $f:expr) => {{ + let orig_pos = self.position(); + let res = $f(); + stats.push(($label, self.position() - orig_pos)); + res + }}; + } + + // We have already encoded some things. Get their combined size from the current position. + stats.push(("preamble", self.position())); + + let (crate_deps, dylib_dependency_formats) = + stat!("dep", || (self.encode_crate_deps(), self.encode_dylib_dependency_formats())); + + let lib_features = stat!("lib-features", || self.encode_lib_features()); + + let stability_implications = + stat!("stability-implications", || self.encode_stability_implications()); + + let (lang_items, lang_items_missing) = stat!("lang-items", || { + (self.encode_lang_items(), self.encode_lang_items_missing()) + }); + + let diagnostic_items = stat!("diagnostic-items", || self.encode_diagnostic_items()); + + let native_libraries = stat!("native-libs", || self.encode_native_libraries()); + + let foreign_modules = stat!("foreign-modules", || self.encode_foreign_modules()); + + _ = stat!("def-path-table", || self.encode_def_path_table()); // Encode the def IDs of traits, for rustdoc and diagnostics. - i = self.position(); - let traits = self.encode_traits(); - let traits_bytes = self.position() - i; + let traits = stat!("traits", || self.encode_traits()); // Encode the def IDs of impls, for coherence checking. - i = self.position(); - let impls = self.encode_impls(); - let impls_bytes = self.position() - i; - - i = self.position(); - let incoherent_impls = self.encode_incoherent_impls(); - let incoherent_impls_bytes = self.position() - i; - - // Encode MIR. - i = self.position(); - self.encode_mir(); - let mir_bytes = self.position() - i; - - // Encode the items. - i = self.position(); - self.encode_def_ids(); - self.encode_info_for_items(); - let item_bytes = self.position() - i; - - // Encode the allocation index - i = self.position(); - let interpret_alloc_index = { + let impls = stat!("impls", || self.encode_impls()); + + let incoherent_impls = stat!("incoherent-impls", || self.encode_incoherent_impls()); + + _ = stat!("mir", || self.encode_mir()); + + _ = stat!("items", || { + self.encode_def_ids(); + self.encode_info_for_items(); + }); + + let interpret_alloc_index = stat!("interpret-alloc-index", || { let mut interpret_alloc_index = Vec::new(); let mut n = 0; trace!("beginning to encode alloc ids"); @@ -646,125 +625,90 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { n = new_n; } self.lazy_array(interpret_alloc_index) - }; - let interpret_alloc_index_bytes = self.position() - i; + }); - // Encode the proc macro data. This affects 'tables', - // so we need to do this before we encode the tables. - // This overwrites def_keys, so it must happen after encode_def_path_table. - i = self.position(); - let proc_macro_data = self.encode_proc_macros(); - let proc_macro_data_bytes = self.position() - i; + // Encode the proc macro data. This affects `tables`, so we need to do this before we + // encode the tables. This overwrites def_keys, so it must happen after + // encode_def_path_table. + let proc_macro_data = stat!("proc-macro-data", || self.encode_proc_macros()); - i = self.position(); - let tables = self.tables.encode(&mut self.opaque); - let tables_bytes = self.position() - i; + let tables = stat!("tables", || self.tables.encode(&mut self.opaque)); - i = self.position(); - let debugger_visualizers = self.encode_debugger_visualizers(); - let debugger_visualizers_bytes = self.position() - i; + let debugger_visualizers = + stat!("debugger-visualizers", || self.encode_debugger_visualizers()); // Encode exported symbols info. This is prefetched in `encode_metadata` so we encode // this as late as possible to give the prefetching as much time as possible to complete. - i = self.position(); - let exported_symbols = tcx.exported_symbols(LOCAL_CRATE); - let exported_symbols = self.encode_exported_symbols(&exported_symbols); - let exported_symbols_bytes = self.position() - i; + let exported_symbols = stat!("exported-symbols", || { + self.encode_exported_symbols(&tcx.exported_symbols(LOCAL_CRATE)) + }); - // Encode the hygiene data, + // Encode the hygiene data. // IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The // process of encoding other items (e.g. `optimized_mir`) may cause us to load data from // the incremental cache. If this causes us to deserialize a `Span`, then we may load // additional `SyntaxContext`s into the global `HygieneData`. Therefore, we need to encode // the hygiene data last to ensure that we encode any `SyntaxContext`s that might be used. - i = self.position(); - let (syntax_contexts, expn_data, expn_hashes) = self.encode_hygiene(); - let hygiene_bytes = self.position() - i; - - i = self.position(); - let def_path_hash_map = self.encode_def_path_hash_map(); - let def_path_hash_map_bytes = self.position() - i; - - // Encode source_map. This needs to be done last, - // since encoding `Span`s tells us which `SourceFiles` we actually - // need to encode. - i = self.position(); - let source_map = self.encode_source_map(); - let source_map_bytes = self.position() - i; - - i = self.position(); - let attrs = tcx.hir().krate_attrs(); - let has_default_lib_allocator = tcx.sess.contains_name(&attrs, sym::default_lib_allocator); - let root = self.lazy(CrateRoot { - name: tcx.crate_name(LOCAL_CRATE), - extra_filename: tcx.sess.opts.cg.extra_filename.clone(), - triple: tcx.sess.opts.target_triple.clone(), - hash: tcx.crate_hash(LOCAL_CRATE), - stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(), - required_panic_strategy: tcx.required_panic_strategy(LOCAL_CRATE), - panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop, - edition: tcx.sess.edition(), - has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE), - has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE), - has_default_lib_allocator, - proc_macro_data, - debugger_visualizers, - compiler_builtins: tcx.sess.contains_name(&attrs, sym::compiler_builtins), - needs_allocator: tcx.sess.contains_name(&attrs, sym::needs_allocator), - needs_panic_runtime: tcx.sess.contains_name(&attrs, sym::needs_panic_runtime), - no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins), - panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime), - profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime), - symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(), - - crate_deps, - dylib_dependency_formats, - lib_features, - stability_implications, - lang_items, - diagnostic_items, - lang_items_missing, - native_libraries, - foreign_modules, - source_map, - traits, - impls, - incoherent_impls, - exported_symbols, - interpret_alloc_index, - tables, - syntax_contexts, - expn_data, - expn_hashes, - def_path_hash_map, + let (syntax_contexts, expn_data, expn_hashes) = stat!("hygiene", || self.encode_hygiene()); + + let def_path_hash_map = stat!("def-path-hash-map", || self.encode_def_path_hash_map()); + + // Encode source_map. This needs to be done last, because encoding `Span`s tells us which + // `SourceFiles` we actually need to encode. + let source_map = stat!("source-map", || self.encode_source_map()); + + let root = stat!("final", || { + let attrs = tcx.hir().krate_attrs(); + self.lazy(CrateRoot { + name: tcx.crate_name(LOCAL_CRATE), + extra_filename: tcx.sess.opts.cg.extra_filename.clone(), + triple: tcx.sess.opts.target_triple.clone(), + hash: tcx.crate_hash(LOCAL_CRATE), + stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(), + required_panic_strategy: tcx.required_panic_strategy(LOCAL_CRATE), + panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop, + edition: tcx.sess.edition(), + has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE), + has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE), + has_default_lib_allocator: tcx + .sess + .contains_name(&attrs, sym::default_lib_allocator), + proc_macro_data, + debugger_visualizers, + compiler_builtins: tcx.sess.contains_name(&attrs, sym::compiler_builtins), + needs_allocator: tcx.sess.contains_name(&attrs, sym::needs_allocator), + needs_panic_runtime: tcx.sess.contains_name(&attrs, sym::needs_panic_runtime), + no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins), + panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime), + profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime), + symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(), + + crate_deps, + dylib_dependency_formats, + lib_features, + stability_implications, + lang_items, + diagnostic_items, + lang_items_missing, + native_libraries, + foreign_modules, + source_map, + traits, + impls, + incoherent_impls, + exported_symbols, + interpret_alloc_index, + tables, + syntax_contexts, + expn_data, + expn_hashes, + def_path_hash_map, + }) }); - let final_bytes = self.position() - i; let total_bytes = self.position(); - let computed_total_bytes = preamble_bytes - + dep_bytes - + lib_feature_bytes - + stability_implications_bytes - + lang_item_bytes - + diagnostic_item_bytes - + native_lib_bytes - + foreign_modules_bytes - + def_path_table_bytes - + traits_bytes - + impls_bytes - + incoherent_impls_bytes - + mir_bytes - + item_bytes - + interpret_alloc_index_bytes - + proc_macro_data_bytes - + tables_bytes - + debugger_visualizers_bytes - + exported_symbols_bytes - + hygiene_bytes - + def_path_hash_map_bytes - + source_map_bytes - + final_bytes; + let computed_total_bytes: usize = stats.iter().map(|(_, size)| size).sum(); assert_eq!(total_bytes, computed_total_bytes); if tcx.sess.meta_stats() { @@ -782,42 +726,38 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } assert_eq!(self.opaque.file().stream_position().unwrap(), pos_before_rewind); + stats.sort_by_key(|&(_, usize)| usize); + + let prefix = "meta-stats"; let perc = |bytes| (bytes * 100) as f64 / total_bytes as f64; - let p = |label, bytes| { - eprintln!("{:>21}: {:>8} bytes ({:4.1}%)", label, bytes, perc(bytes)); - }; - eprintln!(""); + eprintln!("{} METADATA STATS", prefix); + eprintln!("{} {:<23}{:>10}", prefix, "Section", "Size"); + eprintln!( + "{} ----------------------------------------------------------------", + prefix + ); + for (label, size) in stats { + eprintln!( + "{} {:<23}{:>10} ({:4.1}%)", + prefix, + label, + to_readable_str(size), + perc(size) + ); + } + eprintln!( + "{} ----------------------------------------------------------------", + prefix + ); eprintln!( - "{} metadata bytes, of which {} bytes ({:.1}%) are zero", - total_bytes, - zero_bytes, + "{} {:<23}{:>10} (of which {:.1}% are zero bytes)", + prefix, + "Total", + to_readable_str(total_bytes), perc(zero_bytes) ); - p("preamble", preamble_bytes); - p("dep", dep_bytes); - p("lib feature", lib_feature_bytes); - p("stability_implications", stability_implications_bytes); - p("lang item", lang_item_bytes); - p("diagnostic item", diagnostic_item_bytes); - p("native lib", native_lib_bytes); - p("foreign modules", foreign_modules_bytes); - p("def-path table", def_path_table_bytes); - p("traits", traits_bytes); - p("impls", impls_bytes); - p("incoherent_impls", incoherent_impls_bytes); - p("mir", mir_bytes); - p("item", item_bytes); - p("interpret_alloc_index", interpret_alloc_index_bytes); - p("proc-macro-data", proc_macro_data_bytes); - p("tables", tables_bytes); - p("debugger visualizers", debugger_visualizers_bytes); - p("exported symbols", exported_symbols_bytes); - p("hygiene", hygiene_bytes); - p("def-path hashes", def_path_hash_map_bytes); - p("source_map", source_map_bytes); - p("final", final_bytes); - eprintln!(""); + eprintln!("{}", prefix); } root