diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 358d412a4d8e2..213e8db66a056 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1317,10 +1317,14 @@ declare_lint! { /// /// ### Explanation /// - /// A bare `pub` visibility may be misleading if the item is not actually - /// publicly exported from the crate. The `pub(crate)` visibility is - /// recommended to be used instead, which more clearly expresses the intent - /// that the item is only visible within its own crate. + /// The `pub` keyword both expresses an intent for an item to be publicly available, and also + /// signals to the compiler to make the item publicly accessible. The intent can only be + /// satisfied, however, if all items which contain this item are *also* publicly accessible. + /// Thus, this lint serves to identify situations where the intent does not match the reality. + /// + /// If you wish the item to be accessible elsewhere within the crate, but not outside it, the + /// `pub(crate)` visibility is recommended to be used instead. This more clearly expresses the + /// intent that the item is only visible within its own crate. /// /// This lint is "allow" by default because it will trigger for a large /// amount existing Rust code, and has some false-positives. Eventually it diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index f31b343c94704..1511e25523559 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -291,10 +291,12 @@ impl<'tcx> CodegenUnit<'tcx> { self.primary = true; } + /// The order of these items is non-determinstic. pub fn items(&self) -> &FxHashMap, (Linkage, Visibility)> { &self.items } + /// The order of these items is non-determinstic. pub fn items_mut(&mut self) -> &mut FxHashMap, (Linkage, Visibility)> { &mut self.items } diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index ecc50c3f664fd..89dadc782f2da 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -1,4 +1,5 @@ #![feature(array_windows)] +#![feature(is_sorted)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 0bacb58383dc0..015361f8ad5b7 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -126,11 +126,14 @@ struct PartitioningCx<'a, 'tcx> { } struct PlacedRootMonoItems<'tcx> { + /// The codegen units, sorted by name to make things deterministic. codegen_units: Vec>, + roots: FxHashSet>, internalization_candidates: FxHashSet>, } +// The output CGUs are sorted by name. fn partition<'tcx, I>( tcx: TyCtxt<'tcx>, mono_items: &mut I, @@ -143,6 +146,7 @@ where let _prof_timer = tcx.prof.generic_activity("cgu_partitioning"); let cx = &PartitioningCx { tcx, target_cgu_count: max_cgu_count, inlining_map }; + // In the first step, we place all regular monomorphizations into their // respective 'home' codegen unit. Regular monomorphizations are all // functions and statics defined in the local crate. @@ -225,8 +229,8 @@ where dead_code_cgu.make_code_coverage_dead_code_cgu(); } - // Finally, sort by codegen unit name, so that we get deterministic results. - codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str())); + // Ensure CGUs are sorted by name, so that we get deterministic results. + assert!(codegen_units.is_sorted_by(|a, b| Some(a.name().as_str().cmp(b.name().as_str())))); debug_dump(tcx, "FINAL", &codegen_units); @@ -301,27 +305,22 @@ where codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name)); } - let codegen_units = codegen_units.into_values().collect(); + let mut codegen_units: Vec<_> = codegen_units.into_values().collect(); + codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str())); + PlacedRootMonoItems { codegen_units, roots, internalization_candidates } } +// This function requires the CGUs to be sorted by name on input, and ensures +// they are sorted by name on return, for deterministic behaviour. fn merge_codegen_units<'tcx>( cx: &PartitioningCx<'_, 'tcx>, codegen_units: &mut Vec>, ) { assert!(cx.target_cgu_count >= 1); - // Note that at this point in time the `codegen_units` here may not be - // in a deterministic order (but we know they're deterministically the - // same set). We want this merging to produce a deterministic ordering - // of codegen units from the input. - // - // Due to basically how we've implemented the merging below (merge the - // two smallest into each other) we're sure to start off with a - // deterministic order (sorted by name). This'll mean that if two cgus - // have the same size the stable sort below will keep everything nice - // and deterministic. - codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str())); + // A sorted order here ensures merging is deterministic. + assert!(codegen_units.is_sorted_by(|a, b| Some(a.name().as_str().cmp(b.name().as_str())))); // This map keeps track of what got merged into what. let mut cgu_contents: FxHashMap> = @@ -400,6 +399,9 @@ fn merge_codegen_units<'tcx>( cgu.set_name(numbered_codegen_unit_name); } } + + // A sorted order here ensures what follows can be deterministic. + codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str())); } /// For symbol internalization, we need to know whether a symbol/mono-item is @@ -859,36 +861,46 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit _ => Visibility::Hidden, } } + fn debug_dump<'a, 'tcx: 'a>(tcx: TyCtxt<'tcx>, label: &str, cgus: &[CodegenUnit<'tcx>]) { let dump = move || { use std::fmt::Write; let num_cgus = cgus.len(); - let max = cgus.iter().map(|cgu| cgu.size_estimate()).max().unwrap(); - let min = cgus.iter().map(|cgu| cgu.size_estimate()).min().unwrap(); - let ratio = max as f64 / min as f64; + let num_items: usize = cgus.iter().map(|cgu| cgu.items().len()).sum(); + let total_size: usize = cgus.iter().map(|cgu| cgu.size_estimate()).sum(); + let max_size = cgus.iter().map(|cgu| cgu.size_estimate()).max().unwrap(); + let min_size = cgus.iter().map(|cgu| cgu.size_estimate()).min().unwrap(); + let max_min_size_ratio = max_size as f64 / min_size as f64; let s = &mut String::new(); let _ = writeln!( s, - "{label} ({num_cgus} CodegenUnits, max={max}, min={min}, max/min={ratio:.1}):" + "{label} ({num_items} items, total_size={total_size}; {num_cgus} CGUs, \ + max_size={max_size}, min_size={min_size}, max_size/min_size={max_min_size_ratio:.1}):" ); - for cgu in cgus { - let _ = - writeln!(s, "CodegenUnit {} estimated size {}:", cgu.name(), cgu.size_estimate()); + for (i, cgu) in cgus.iter().enumerate() { + let num_items = cgu.items().len(); + let _ = writeln!( + s, + "- CGU[{i}] {} ({num_items} items, size={}):", + cgu.name(), + cgu.size_estimate() + ); - for (mono_item, linkage) in cgu.items() { - let symbol_name = mono_item.symbol_name(tcx).name; + // The order of `cgu.items()` is non-deterministic; sort it by name + // to give deterministic output. + let mut items: Vec<_> = cgu.items().iter().collect(); + items.sort_by_key(|(item, _)| item.symbol_name(tcx).name); + for (item, linkage) in items { + let symbol_name = item.symbol_name(tcx).name; let symbol_hash_start = symbol_name.rfind('h'); let symbol_hash = symbol_hash_start.map_or("", |i| &symbol_name[i..]); + let size = item.size_estimate(tcx); let _ = with_no_trimmed_paths!(writeln!( s, - " - {} [{:?}] [{}] estimated size {}", - mono_item, - linkage, - symbol_hash, - mono_item.size_estimate(tcx) + " - {item} [{linkage:?}] [{symbol_hash}] (size={size})" )); } diff --git a/library/std/src/sys/windows/stdio.rs b/library/std/src/sys/windows/stdio.rs index 2e3e0859dc18e..3fcaaa508e3c8 100644 --- a/library/std/src/sys/windows/stdio.rs +++ b/library/std/src/sys/windows/stdio.rs @@ -11,6 +11,9 @@ use crate::sys::cvt; use crate::sys::handle::Handle; use core::str::utf8_char_width; +#[cfg(test)] +mod tests; + // Don't cache handles but get them fresh for every read/write. This allows us to track changes to // the value over time (such as if a process calls `SetStdHandle` while it's running). See #40490. pub struct Stdin { @@ -383,6 +386,10 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result { debug_assert!(utf16.len() <= c::c_int::MAX as usize); debug_assert!(utf8.len() <= c::c_int::MAX as usize); + if utf16.is_empty() { + return Ok(0); + } + let result = unsafe { c::WideCharToMultiByte( c::CP_UTF8, // CodePage diff --git a/library/std/src/sys/windows/stdio/tests.rs b/library/std/src/sys/windows/stdio/tests.rs new file mode 100644 index 0000000000000..1e53e0bee6369 --- /dev/null +++ b/library/std/src/sys/windows/stdio/tests.rs @@ -0,0 +1,6 @@ +use super::utf16_to_utf8; + +#[test] +fn zero_size_read() { + assert_eq!(utf16_to_utf8(&[], &mut []).unwrap(), 0); +} diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 6e573c2284e5c..eec8c4ad69f23 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1772,6 +1772,14 @@ impl Step for BookTest { /// /// This uses the `rustdoc` that sits next to `compiler`. fn run(self, builder: &Builder<'_>) { + let host = self.compiler.host; + let _guard = builder.msg( + Kind::Test, + self.compiler.stage, + &format!("book {}", self.name), + host, + host, + ); // External docs are different from local because: // - Some books need pre-processing by mdbook before being tested. // - They need to save their state to toolstate. @@ -1963,7 +1971,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> } } - builder.info(&format!("doc tests for: {}", markdown.display())); + builder.verbose(&format!("doc tests for: {}", markdown.display())); let mut cmd = builder.rustdoc_cmd(compiler); builder.add_rust_test_threads(&mut cmd); // allow for unstable options such as new editions diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh index ff17931115cd0..0807e0492c113 100755 --- a/src/etc/pre-push.sh +++ b/src/etc/pre-push.sh @@ -14,4 +14,4 @@ ROOT_DIR="$(git rev-parse --show-toplevel)" echo "Running pre-push script $ROOT_DIR/x test tidy" cd "$ROOT_DIR" -CARGOFLAGS="--locked" ./x test tidy +./x test tidy --set build.locked-deps=true diff --git a/tests/rustdoc-gui/theme-in-history.goml b/tests/rustdoc-gui/theme-in-history.goml index 8fcd0ecd3094b..42c5b5e6e69e3 100644 --- a/tests/rustdoc-gui/theme-in-history.goml +++ b/tests/rustdoc-gui/theme-in-history.goml @@ -7,7 +7,7 @@ set-local-storage: { } // We reload the page so the local storage settings are being used. reload: -assert-css: ("body", { "background-color": "rgb(53, 53, 53)" }) +assert-css: ("body", { "background-color": "#353535" }) assert-local-storage: { "rustdoc-theme": "dark" } // Now we go to the settings page. @@ -15,7 +15,7 @@ go-to: "file://" + |DOC_PATH| + "/settings.html" wait-for: "#settings" // We change the theme to "light". click: "#theme-light" -wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" }) +wait-for-css: ("body", { "background-color": "white" }) assert-local-storage: { "rustdoc-theme": "light" } // We go back in history. @@ -23,5 +23,5 @@ history-go-back: // Confirm that we're not on the settings page. assert-false: "#settings" // Check that the current theme is still "light". -assert-css: ("body", { "background-color": "rgb(255, 255, 255)" }) +assert-css: ("body", { "background-color": "white" }) assert-local-storage: { "rustdoc-theme": "light" } diff --git a/tests/ui/inline-const/elided-lifetime-being-infer-vars.rs b/tests/ui/inline-const/elided-lifetime-being-infer-vars.rs new file mode 100644 index 0000000000000..5661db4a2530d --- /dev/null +++ b/tests/ui/inline-const/elided-lifetime-being-infer-vars.rs @@ -0,0 +1,11 @@ +// check-pass + +#![feature(inline_const)] + +fn main() { + let _my_usize = const { + let a = 10_usize; + let b: &'_ usize = &a; + *b + }; +} diff --git a/triagebot.toml b/triagebot.toml index c160c83cc9590..b1f4e9c77fbd5 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -387,6 +387,10 @@ cc = [ message = "Some changes occurred in HTML/CSS themes." cc = ["@GuillaumeGomez"] +[mentions."tests/rustdoc-gui/"] +message = "Some changes occurred in GUI tests." +cc = ["@GuillaumeGomez"] + [mentions."src/librustdoc/html/static/css/themes/ayu.css"] message = "A change occurred in the Ayu theme." cc = ["@Cldfire"]