From f742d8832601080df1ae56c6469da18a917e1f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 10 Sep 2023 13:15:46 +0200 Subject: [PATCH 1/8] Remove `verbose_generic_activity_with_arg` --- .../rustc_codegen_cranelift/src/driver/aot.rs | 41 +++++++------------ compiler/rustc_codegen_llvm/src/back/lto.rs | 2 +- .../rustc_data_structures/src/profiling.rs | 19 --------- .../rustc_mir_transform/src/pass_manager.rs | 5 ++- compiler/rustc_query_impl/src/plumbing.rs | 3 +- 5 files changed, 21 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index d143bcc96ef93..3e93830951c5c 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -269,7 +269,7 @@ fn module_codegen( ), ) -> OngoingModuleCodegen { let (cgu_name, mut cx, mut module, codegened_functions) = - tcx.prof.verbose_generic_activity_with_arg("codegen cgu", cgu_name.as_str()).run(|| { + tcx.prof.generic_activity_with_arg("codegen cgu", cgu_name.as_str()).run(|| { let cgu = tcx.codegen_unit(cgu_name); let mono_items = cgu.items_in_deterministic_order(tcx); @@ -322,35 +322,24 @@ fn module_codegen( }); OngoingModuleCodegen::Async(std::thread::spawn(move || { - cx.profiler.clone().verbose_generic_activity_with_arg("compile functions", &*cgu_name).run( - || { - cranelift_codegen::timing::set_thread_profiler(Box::new(super::MeasuremeProfiler( - cx.profiler.clone(), - ))); - - let mut cached_context = Context::new(); - for codegened_func in codegened_functions { - crate::base::compile_fn( - &mut cx, - &mut cached_context, - &mut module, - codegened_func, - ); - } - }, - ); + cx.profiler.clone().generic_activity_with_arg("compile functions", &*cgu_name).run(|| { + cranelift_codegen::timing::set_thread_profiler(Box::new(super::MeasuremeProfiler( + cx.profiler.clone(), + ))); + + let mut cached_context = Context::new(); + for codegened_func in codegened_functions { + crate::base::compile_fn(&mut cx, &mut cached_context, &mut module, codegened_func); + } + }); - let global_asm_object_file = cx - .profiler - .verbose_generic_activity_with_arg("compile assembly", &*cgu_name) - .run(|| { + let global_asm_object_file = + cx.profiler.generic_activity_with_arg("compile assembly", &*cgu_name).run(|| { crate::global_asm::compile_global_asm(&global_asm_config, &cgu_name, &cx.global_asm) })?; - let codegen_result = cx - .profiler - .verbose_generic_activity_with_arg("write object file", &*cgu_name) - .run(|| { + let codegen_result = + cx.profiler.generic_activity_with_arg("write object file", &*cgu_name).run(|| { emit_cgu( &global_asm_config.output_filenames, &cx.profiler, diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 5cf83b1accb16..ba263296bb454 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -605,7 +605,7 @@ pub(crate) fn run_pass_manager( module: &mut ModuleCodegen, thin: bool, ) -> Result<(), FatalError> { - let _timer = cgcx.prof.verbose_generic_activity_with_arg("LLVM_lto_optimize", &*module.name); + let _timer = cgcx.prof.generic_activity_with_arg("LLVM_lto_optimize", &*module.name); let config = cgcx.config(module.kind); // Now we have one massive module inside of llmod. Time to run the diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 3c76c2b79911a..321812fa93aec 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -223,25 +223,6 @@ impl SelfProfilerRef { VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label)) } - /// Like `verbose_generic_activity`, but with an extra arg. - pub fn verbose_generic_activity_with_arg( - &self, - event_label: &'static str, - event_arg: A, - ) -> VerboseTimingGuard<'_> - where - A: Borrow + Into, - { - let message_and_format = self - .print_verbose_generic_activities - .map(|format| (format!("{}({})", event_label, event_arg.borrow()), format)); - - VerboseTimingGuard::start( - message_and_format, - self.generic_activity_with_arg(event_label, event_arg), - ) - } - /// Start profiling a generic activity. Profiling continues until the /// TimingGuard returned from this call is dropped. #[inline(always)] diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index 057f5fe82931b..0aba1bc968539 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -121,7 +121,10 @@ fn run_passes_inner<'tcx>( validate_body(tcx, body, format!("before pass {name}")); } - tcx.sess.time(name, || pass.run_pass(tcx, body)); + tcx.sess + .prof + .generic_activity_with_arg("mir_pass", name) + .run(|| pass.run_pass(tcx, body)); if dump_enabled { dump_mir_for_pass(tcx, body, &name, true); diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index a30ea7c1ddcaf..f2fdf066d15c9 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -348,8 +348,7 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>( Q: super::QueryConfigRestored<'tcx>, Q::RestoredValue: Encodable>, { - let _timer = - qcx.profiler().verbose_generic_activity_with_arg("encode_query_results_for", query.name()); + let _timer = qcx.profiler().generic_activity_with_arg("encode_query_results_for", query.name()); assert!(query.query_state(qcx).all_inactive()); let cache = query.query_cache(qcx); From fd91dfb4949ceec2fb4306ffabff376b9ea01785 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 12 Sep 2023 13:41:42 +0200 Subject: [PATCH 2/8] cleanup leftovers of const_err lint --- .../rustc_const_eval/src/const_eval/error.rs | 25 +++---------------- .../src/const_eval/eval_queries.rs | 2 +- tests/ui/limits/issue-55878.stderr | 4 ++- tests/ui/limits/issue-56762.rs | 6 +++-- tests/ui/limits/issue-56762.stderr | 10 ++++---- 5 files changed, 16 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index f146b93ff0ccc..2d20d553ef770 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -4,7 +4,6 @@ use rustc_errors::{DiagnosticArgValue, DiagnosticMessage, IntoDiagnostic, IntoDi use rustc_middle::mir::AssertKind; use rustc_middle::ty::TyCtxt; use rustc_middle::ty::{layout::LayoutError, ConstInt}; -use rustc_span::source_map::Spanned; use rustc_span::{ErrorGuaranteed, Span, Symbol}; use super::InterpCx; @@ -132,7 +131,8 @@ where { // Special handling for certain errors match error { - // Don't emit a new diagnostic for these errors + // Don't emit a new diagnostic for these errors, they are already reported elsewhere or + // should remain silent. err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { ErrorHandled::TooGeneric } @@ -140,27 +140,8 @@ where err_inval!(Layout(LayoutError::ReferencesError(guar))) => { ErrorHandled::Reported(guar.into()) } - err_inval!(Layout(layout_error @ LayoutError::SizeOverflow(_))) => { - // We must *always* hard error on these, even if the caller wants just a lint. - // The `message` makes little sense here, this is a more serious error than the - // caller thinks anyway. - // See . - let (our_span, frames) = get_span_and_frames(); - let span = span.unwrap_or(our_span); - let mut err = - tcx.sess.create_err(Spanned { span, node: layout_error.into_diagnostic() }); - err.code(rustc_errors::error_code!(E0080)); - let Some((mut err, handler)) = err.into_diagnostic() else { - panic!("did not emit diag"); - }; - for frame in frames { - err.eager_subdiagnostic(handler, frame); - } - - ErrorHandled::Reported(handler.emit_diagnostic(&mut err).unwrap().into()) - } + // Report remaining errors. _ => { - // Report as hard error. let (our_span, frames) = get_span_and_frames(); let span = span.unwrap_or(our_span); let err = mk(span, frames); diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 9df3e4030fff6..369dc8821d646 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -372,7 +372,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( }; let alloc_id = mplace.ptr().provenance.unwrap(); - // Validation failed, report an error. This is always a hard error. + // Validation failed, report an error. if let Err(error) = validation { let (error, backtrace) = error.into_parts(); backtrace.print_backtrace(); diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr index 510b36edd8f47..f0c7210dde747 100644 --- a/tests/ui/limits/issue-55878.stderr +++ b/tests/ui/limits/issue-55878.stderr @@ -1,6 +1,8 @@ -error[E0080]: values of the type `[u8; usize::MAX]` are too big for the current architecture +error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | + = note: values of the type `[u8; usize::MAX]` are too big for the current architecture + | note: inside `std::mem::size_of::<[u8; usize::MAX]>` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL note: inside `main` diff --git a/tests/ui/limits/issue-56762.rs b/tests/ui/limits/issue-56762.rs index ed7ee4da85d4d..1c7facb045d46 100644 --- a/tests/ui/limits/issue-56762.rs +++ b/tests/ui/limits/issue-56762.rs @@ -14,8 +14,10 @@ impl TooBigArray { } static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); -//~^ ERROR values of the type `[u8; 2305843009213693951]` are too big +//~^ ERROR could not evaluate static initializer +//~| too big static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; -//~^ ERROR values of the type `[u8; 2305843009213693951]` are too big +//~^ ERROR could not evaluate static initializer +//~| too big fn main() { } diff --git a/tests/ui/limits/issue-56762.stderr b/tests/ui/limits/issue-56762.stderr index 29f2a8859eee3..3a6c3559ac195 100644 --- a/tests/ui/limits/issue-56762.stderr +++ b/tests/ui/limits/issue-56762.stderr @@ -1,14 +1,14 @@ -error[E0080]: values of the type `[u8; 2305843009213693951]` are too big for the current architecture +error[E0080]: could not evaluate static initializer --> $DIR/issue-56762.rs:16:1 | LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693951]` are too big for the current architecture -error[E0080]: values of the type `[u8; 2305843009213693951]` are too big for the current architecture - --> $DIR/issue-56762.rs:18:1 +error[E0080]: could not evaluate static initializer + --> $DIR/issue-56762.rs:19:1 | LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693951]` are too big for the current architecture error: aborting due to 2 previous errors From 60091fe92403f5a4aca1d273295668b546bf2bf2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 12 Sep 2023 20:51:00 +0200 Subject: [PATCH 3/8] add helper method for finding the one non-1-ZST field --- .../rustc_codegen_cranelift/src/vtable.rs | 19 +++------ compiler/rustc_codegen_ssa/src/mir/block.rs | 41 +++++-------------- .../src/interpret/terminator.rs | 39 ++++-------------- compiler/rustc_target/src/abi/mod.rs | 21 ++++++++++ compiler/rustc_ty_utils/src/abi.rs | 18 +++----- 5 files changed, 49 insertions(+), 89 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs index 7598c6eee03ff..41ea0b122de73 100644 --- a/compiler/rustc_codegen_cranelift/src/vtable.rs +++ b/compiler/rustc_codegen_cranelift/src/vtable.rs @@ -48,19 +48,12 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( ) -> (Pointer, Value) { let (ptr, vtable) = 'block: { if let Abi::Scalar(_) = arg.layout().abi { - 'descend_newtypes: while !arg.layout().ty.is_unsafe_ptr() && !arg.layout().ty.is_ref() { - for i in 0..arg.layout().fields.count() { - let field = arg.value_field(fx, FieldIdx::new(i)); - if !field.layout().is_1zst() { - // we found the one non-1-ZST field that is allowed - // now find *its* non-zero-sized field, or stop if it's a - // pointer - arg = field; - continue 'descend_newtypes; - } - } - - bug!("receiver has no non-zero-sized fields {:?}", arg); + while !arg.layout().ty.is_unsafe_ptr() && !arg.layout().ty.is_ref() { + let (idx, _) = arg + .layout() + .non_1zst_field(fx) + .expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type"); + arg = arg.value_field(fx, FieldIdx::new(idx)); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d78a0c4910768..d8f6b4ed836ad 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -928,21 +928,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // we get a value of a built-in pointer type. // // This is also relevant for `Pin<&mut Self>`, where we need to peel the `Pin`. - 'descend_newtypes: while !op.layout.ty.is_unsafe_ptr() - && !op.layout.ty.is_ref() - { - for i in 0..op.layout.fields.count() { - let field = op.extract_field(bx, i); - if !field.layout.is_1zst() { - // we found the one non-1-ZST field that is allowed - // now find *its* non-zero-sized field, or stop if it's a - // pointer - op = field; - continue 'descend_newtypes; - } - } - - span_bug!(span, "receiver has no non-zero-sized fields {:?}", op); + while !op.layout.ty.is_unsafe_ptr() && !op.layout.ty.is_ref() { + let (idx, _) = op.layout.non_1zst_field(bx).expect( + "not exactly one non-1-ZST field in a `DispatchFromDyn` type", + ); + op = op.extract_field(bx, idx); } // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its @@ -970,22 +960,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } Immediate(_) => { // See comment above explaining why we peel these newtypes - 'descend_newtypes: while !op.layout.ty.is_unsafe_ptr() - && !op.layout.ty.is_ref() - { - for i in 0..op.layout.fields.count() { - let field = op.extract_field(bx, i); - if !field.layout.is_1zst() { - // We found the one non-1-ZST field that is allowed. (The rules - // for `DispatchFromDyn` ensure there's exactly one such field.) - // Now find *its* non-zero-sized field, or stop if it's a - // pointer. - op = field; - continue 'descend_newtypes; - } - } - - span_bug!(span, "receiver has no non-zero-sized fields {:?}", op); + while !op.layout.ty.is_unsafe_ptr() && !op.layout.ty.is_ref() { + let (idx, _) = op.layout.non_1zst_field(bx).expect( + "not exactly one non-1-ZST field in a `DispatchFromDyn` type", + ); + op = op.extract_field(bx, idx); } // Make sure that we've actually unwrapped the rcvr down diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 7e22981542e51..e15499bc68d0a 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -269,19 +269,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match layout.ty.kind() { ty::Adt(adt_def, _) if adt_def.repr().transparent() && may_unfold(*adt_def) => { assert!(!adt_def.is_enum()); - // Find the non-1-ZST field. - let mut non_1zst_fields = (0..layout.fields.count()).filter_map(|idx| { - let field = layout.field(self, idx); - if field.is_1zst() { None } else { Some(field) } - }); - let first = non_1zst_fields.next().expect("`unfold_transparent` called on 1-ZST"); - assert!( - non_1zst_fields.next().is_none(), - "more than one non-1-ZST field in a transparent type" - ); - - // Found it! - self.unfold_transparent(first, may_unfold) + // Find the non-1-ZST field, and recurse. + let (_, field) = layout.non_1zst_field(self).unwrap(); + self.unfold_transparent(field, may_unfold) } // Not a transparent type, no further unfolding. _ => layout, @@ -797,25 +787,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { _ => { // Not there yet, search for the only non-ZST field. // (The rules for `DispatchFromDyn` ensure there's exactly one such field.) - let mut non_zst_field = None; - for i in 0..receiver.layout.fields.count() { - let field = self.project_field(&receiver, i)?; - let zst = field.layout.is_1zst(); - if !zst { - assert!( - non_zst_field.is_none(), - "multiple non-1-ZST fields in dyn receiver type {}", - receiver.layout.ty - ); - non_zst_field = Some(field); - } - } - receiver = non_zst_field.unwrap_or_else(|| { - panic!( - "no non-1-ZST fields in dyn receiver type {}", - receiver.layout.ty - ) - }); + let (idx, _) = receiver.layout.non_1zst_field(self).expect( + "not exactly one non-1-ZST field in a `DispatchFromDyn` type", + ); + receiver = self.project_field(&receiver, idx)?; } } }; diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index dd435dbb0a306..a335585dbf37c 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -144,4 +144,25 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { offset } + + /// Finds the one field that is not a 1-ZST. + /// Returns `None` if there are multiple non-1-ZST fields or only 1-ZST-fields. + pub fn non_1zst_field(&self, cx: &C) -> Option<(usize, Self)> + where + Ty: TyAbiInterface<'a, C> + Copy, + { + let mut found = None; + for field_idx in 0..self.fields.count() { + let field = self.field(cx, field_idx); + if field.is_1zst() { + continue; + } + if found.is_some() { + // More than one non-1-ZST field. + return None; + } + found = Some((field_idx, field)); + } + found + } } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 3ffe670d87ac1..16183403d67aa 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -588,19 +588,11 @@ fn make_thin_self_ptr<'tcx>( // To get the type `*mut RcBox`, we just keep unwrapping newtypes until we // get a built-in pointer type let mut fat_pointer_layout = layout; - 'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr() - && !fat_pointer_layout.ty.is_ref() - { - for i in 0..fat_pointer_layout.fields.count() { - let field_layout = fat_pointer_layout.field(cx, i); - - if !field_layout.is_1zst() { - fat_pointer_layout = field_layout; - continue 'descend_newtypes; - } - } - - bug!("receiver has no non-1-ZST fields {:?}", fat_pointer_layout); + while !fat_pointer_layout.ty.is_unsafe_ptr() && !fat_pointer_layout.ty.is_ref() { + fat_pointer_layout = fat_pointer_layout + .non_1zst_field(cx) + .expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type") + .1 } fat_pointer_layout.ty From 9624c30965d768527efd3ca5f52904fb5e763587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 13 Sep 2023 13:05:15 +0200 Subject: [PATCH 4/8] Generate MIR pass names for profiling on the fly and pass the body DefId as argument --- compiler/rustc_middle/src/mir/mod.rs | 37 +++++++++++++++++++ .../rustc_mir_transform/src/pass_manager.rs | 14 +++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c78b1e0e2f44a..68163c6392d1d 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -25,6 +25,7 @@ use rustc_target::abi::{FieldIdx, Size, VariantIdx}; use polonius_engine::Atom; pub use rustc_ast::Mutability; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::{Idx, IndexSlice, IndexVec}; @@ -35,6 +36,8 @@ use rustc_span::{Span, DUMMY_SP}; use either::Either; use std::borrow::Cow; +use std::cell::RefCell; +use std::collections::hash_map::Entry; use std::fmt::{self, Debug, Display, Formatter, Write}; use std::ops::{Index, IndexMut}; use std::{iter, mem}; @@ -97,6 +100,36 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> { } } +thread_local! { + static PASS_NAMES: RefCell> = { + RefCell::new(FxHashMap::default()) + }; +} + +/// Converts a MIR pass name into a snake case form to match the profiling naming style. +fn to_profiler_name(type_name: &'static str) -> &'static str { + PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) { + Entry::Occupied(e) => *e.get(), + Entry::Vacant(e) => { + let snake_case: String = type_name + .chars() + .flat_map(|c| { + if c.is_ascii_uppercase() { + vec!['_', c.to_ascii_lowercase()] + } else if c == '-' { + vec!['_'] + } else { + vec![c] + } + }) + .collect(); + let result = &*String::leak(format!("mir_pass{}", snake_case)); + e.insert(result); + result + } + }) +} + /// A streamlined trait that you can implement to create a pass; the /// pass will be named after the type, and it will consist of a main /// loop that goes over each available MIR and applies `run_pass`. @@ -106,6 +139,10 @@ pub trait MirPass<'tcx> { if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name } } + fn profiler_name(&self) -> &'static str { + to_profiler_name(self.name()) + } + /// Returns `true` if this pass is enabled with the current combination of compiler flags. fn is_enabled(&self, _sess: &Session) -> bool { true diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index 0aba1bc968539..5abb2f3d0412a 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -94,6 +94,8 @@ fn run_passes_inner<'tcx>( let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes; trace!(?overridden_passes); + let prof_arg = tcx.sess.prof.enabled().then(|| format!("{:?}", body.source.def_id())); + if !body.should_skip() { for pass in passes { let name = pass.name(); @@ -121,10 +123,14 @@ fn run_passes_inner<'tcx>( validate_body(tcx, body, format!("before pass {name}")); } - tcx.sess - .prof - .generic_activity_with_arg("mir_pass", name) - .run(|| pass.run_pass(tcx, body)); + if let Some(prof_arg) = &prof_arg { + tcx.sess + .prof + .generic_activity_with_arg(pass.profiler_name(), &**prof_arg) + .run(|| pass.run_pass(tcx, body)); + } else { + pass.run_pass(tcx, body); + } if dump_enabled { dump_mir_for_pass(tcx, body, &name, true); From c64e15e817abbe4a2be0143a10c7c4334fa3bdd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 13 Sep 2023 13:12:51 +0200 Subject: [PATCH 5/8] Bring back `verbose_generic_activity_with_arg` --- .../rustc_data_structures/src/profiling.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 321812fa93aec..3c76c2b79911a 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -223,6 +223,25 @@ impl SelfProfilerRef { VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label)) } + /// Like `verbose_generic_activity`, but with an extra arg. + pub fn verbose_generic_activity_with_arg( + &self, + event_label: &'static str, + event_arg: A, + ) -> VerboseTimingGuard<'_> + where + A: Borrow + Into, + { + let message_and_format = self + .print_verbose_generic_activities + .map(|format| (format!("{}({})", event_label, event_arg.borrow()), format)); + + VerboseTimingGuard::start( + message_and_format, + self.generic_activity_with_arg(event_label, event_arg), + ) + } + /// Start profiling a generic activity. Profiling continues until the /// TimingGuard returned from this call is dropped. #[inline(always)] From 9944f01c66e5c0c321a1c29455efe227e1f35aa4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 13 Sep 2023 11:09:04 +0200 Subject: [PATCH 6/8] Merge settings.css into rustdoc.css --- src/librustdoc/html/render/context.rs | 3 - src/librustdoc/html/static/css/rustdoc.css | 64 +++++++++++++++++++++ src/librustdoc/html/static/css/settings.css | 63 -------------------- src/librustdoc/html/static/js/main.js | 8 --- src/librustdoc/html/static_files.rs | 1 - src/librustdoc/html/templates/page.html | 1 - 6 files changed, 64 insertions(+), 76 deletions(-) delete mode 100644 src/librustdoc/html/static/css/settings.css diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 0bc10c5e10fbe..736b6d7ebfa52 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -714,8 +714,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { You need to enable JavaScript be able to update your settings.\ \ \ - \ \ \ @@ -724,7 +722,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { ", static_root_path = page.get_static_root_path(), - settings_css = static_files::STATIC_FILES.settings_css, settings_js = static_files::STATIC_FILES.settings_js, theme_light_css = static_files::STATIC_FILES.theme_light_css, theme_dark_css = static_files::STATIC_FILES.theme_dark_css, diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index da4da50106abb..84123f4e9d357 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -925,6 +925,70 @@ so that we can apply CSS-filters to change the arrow color in themes */ top: -5px; } +.setting-line { + margin: 1.2em 0.6em; +} + +.setting-radio input, .setting-check input { + margin-right: 0.3em; + height: 1.2rem; + width: 1.2rem; + border: 2px solid var(--settings-input-border-color); + outline: none; + -webkit-appearance: none; + cursor: pointer; +} +.setting-radio input { + border-radius: 50%; +} + +.setting-radio span, .setting-check span { + padding-bottom: 1px; +} + +.setting-radio { + margin-top: 0.1em; + margin-bottom: 0.1em; + min-width: 3.8em; + padding: 0.3em; + display: inline-flex; + align-items: center; + cursor: pointer; +} +.setting-radio + .setting-radio { + margin-left: 0.5em; +} + +.setting-check { + margin-right: 20px; + display: flex; + align-items: center; + cursor: pointer; +} + +.setting-radio input:checked { + box-shadow: inset 0 0 0 3px var(--main-background-color); + background-color: var(--settings-input-color); +} +.setting-check input:checked { + background-color: var(--settings-input-color); + border-width: 1px; + content: url('data:image/svg+xml,\ + \ + '); +} +.setting-radio input:focus, .setting-check input:focus { + box-shadow: 0 0 1px 1px var(--settings-input-color); +} +/* In here we combine both `:focus` and `:checked` properties. */ +.setting-radio input:checked:focus { + box-shadow: inset 0 0 0 3px var(--main-background-color), + 0 0 2px 2px var(--settings-input-color); +} +.setting-radio input:hover, .setting-check input:hover { + border-color: var(--settings-input-color) !important; +} + /* use larger max-width for help popover, but not for help.html */ #help.popover { max-width: 600px; diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css deleted file mode 100644 index c1324c0760e63..0000000000000 --- a/src/librustdoc/html/static/css/settings.css +++ /dev/null @@ -1,63 +0,0 @@ -.setting-line { - margin: 1.2em 0.6em; -} - -.setting-radio input, .setting-check input { - margin-right: 0.3em; - height: 1.2rem; - width: 1.2rem; - border: 2px solid var(--settings-input-border-color); - outline: none; - -webkit-appearance: none; - cursor: pointer; -} -.setting-radio input { - border-radius: 50%; -} - -.setting-radio span, .setting-check span { - padding-bottom: 1px; -} - -.setting-radio { - margin-top: 0.1em; - margin-bottom: 0.1em; - min-width: 3.8em; - padding: 0.3em; - display: inline-flex; - align-items: center; - cursor: pointer; -} -.setting-radio + .setting-radio { - margin-left: 0.5em; -} - -.setting-check { - margin-right: 20px; - display: flex; - align-items: center; - cursor: pointer; -} - -.setting-radio input:checked { - box-shadow: inset 0 0 0 3px var(--main-background-color); - background-color: var(--settings-input-color); -} -.setting-check input:checked { - background-color: var(--settings-input-color); - border-width: 1px; - content: url('data:image/svg+xml,\ - \ - '); -} -.setting-radio input:focus, .setting-check input:focus { - box-shadow: 0 0 1px 1px var(--settings-input-color); -} -/* In here we combine both `:focus` and `:checked` properties. */ -.setting-radio input:checked:focus { - box-shadow: inset 0 0 0 3px var(--main-background-color), - 0 0 2px 2px var(--settings-input-color); -} -.setting-radio input:hover, .setting-check input:hover { - border-color: var(--settings-input-color) !important; -} diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index a5ae988f34833..822d22946b42c 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -176,13 +176,6 @@ function browserSupportsHistoryApi() { return window.history && typeof window.history.pushState === "function"; } -function loadCss(cssUrl) { - const link = document.createElement("link"); - link.href = cssUrl; - link.rel = "stylesheet"; - document.getElementsByTagName("head")[0].appendChild(link); -} - function preLoadCss(cssUrl) { // https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload const link = document.createElement("link"); @@ -210,7 +203,6 @@ function preLoadCss(cssUrl) { event.preventDefault(); // Sending request for the CSS and the JS files at the same time so it will // hopefully be loaded when the JS will generate the settings content. - loadCss(getVar("static-root-path") + getVar("settings-css")); loadScript(getVar("static-root-path") + getVar("settings-js")); preLoadCss(getVar("static-root-path") + getVar("theme-light-css")); preLoadCss(getVar("static-root-path") + getVar("theme-dark-css")); diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index a27aa2b58d245..7742646f81aba 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -91,7 +91,6 @@ macro_rules! static_files { static_files! { rustdoc_css => "static/css/rustdoc.css", - settings_css => "static/css/settings.css", noscript_css => "static/css/noscript.css", normalize_css => "static/css/normalize.css", main_js => "static/js/main.js", diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 8cb43634377dc..ad63571c6d03a 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -33,7 +33,6 @@ data-channel="{{rust_channel}}" {#+ #} data-search-js="{{files.search_js}}" {#+ #} data-settings-js="{{files.settings_js}}" {#+ #} - data-settings-css="{{files.settings_css}}" {#+ #} data-theme-light-css="{{files.theme_light_css}}" {#+ #} data-theme-dark-css="{{files.theme_dark_css}}" {#+ #} data-theme-ayu-css="{{files.theme_ayu_css}}" {#+ #} From 41ee874fa9dad0765da5681092fec25247c1f64d Mon Sep 17 00:00:00 2001 From: Nikolay Arhipov Date: Wed, 13 Sep 2023 16:40:33 +0300 Subject: [PATCH 7/8] Disabled socketpair for Vita --- library/std/src/sys/unix/net.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index ade8c75a65713..48f163b6db098 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -102,7 +102,7 @@ impl Socket { } } - #[cfg(not(target_os = "vxworks"))] + #[cfg(not(any(target_os = "vxworks", target_os = "vita")))] pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> { unsafe { let mut fds = [0, 0]; @@ -133,7 +133,7 @@ impl Socket { } } - #[cfg(target_os = "vxworks")] + #[cfg(any(target_os = "vxworks", target_os = "vita"))] pub fn new_pair(_fam: c_int, _ty: c_int) -> io::Result<(Socket, Socket)> { unimplemented!() } From 7c53e87d556f7ce878a446c9db058877ceb69d10 Mon Sep 17 00:00:00 2001 From: bohan Date: Wed, 13 Sep 2023 22:54:22 +0800 Subject: [PATCH 8/8] fix: skip opt if body has tainted error --- compiler/rustc_mir_transform/src/lib.rs | 5 +++++ tests/ui/unsized/issue-115809.rs | 13 +++++++++++++ tests/ui/unsized/issue-115809.stderr | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 tests/ui/unsized/issue-115809.rs create mode 100644 tests/ui/unsized/issue-115809.stderr diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index ff4385e811697..70d4ea74d1a71 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -606,6 +606,11 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { let body = tcx.mir_drops_elaborated_and_const_checked(did).steal(); let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::NotConst); debug!("body: {:#?}", body); + + if body.tainted_by_errors.is_some() { + return body; + } + run_optimization_passes(tcx, &mut body); body diff --git a/tests/ui/unsized/issue-115809.rs b/tests/ui/unsized/issue-115809.rs new file mode 100644 index 0000000000000..ff25365ea50c0 --- /dev/null +++ b/tests/ui/unsized/issue-115809.rs @@ -0,0 +1,13 @@ +// compile-flags: --emit=link -Zmir-opt-level=2 -Zpolymorphize=on + +fn foo() { + let a: [i32; 0] = []; + match [a[..]] { + //~^ ERROR cannot move a value of type `[i32] + //~| ERROR cannot move out of type `[i32]`, a non-copy slice + [[x]] => {} + _ => (), + } +} + +fn main() {} diff --git a/tests/ui/unsized/issue-115809.stderr b/tests/ui/unsized/issue-115809.stderr new file mode 100644 index 0000000000000..a92554b79b956 --- /dev/null +++ b/tests/ui/unsized/issue-115809.stderr @@ -0,0 +1,19 @@ +error[E0161]: cannot move a value of type `[i32]` + --> $DIR/issue-115809.rs:5:12 + | +LL | match [a[..]] { + | ^^^^^ the size of `[i32]` cannot be statically determined + +error[E0508]: cannot move out of type `[i32]`, a non-copy slice + --> $DIR/issue-115809.rs:5:12 + | +LL | match [a[..]] { + | ^^^^^ + | | + | cannot move out of here + | move occurs because value has type `[i32]`, which does not implement the `Copy` trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0161, E0508. +For more information about an error, try `rustc --explain E0161`.