diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 2510ce7146022..c59d56862ab16 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -769,6 +769,7 @@ fn test_unstable_options_tracking_hash() { ); tracked!(codegen_backend, Some("abc".to_string())); tracked!(crate_attr, vec!["abc".to_string()]); + tracked!(cross_crate_inline_threshold, Some(200)); tracked!(debug_info_for_profiling, true); tracked!(debug_macros, true); tracked!(dep_info_omit_d_target, true); diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index b189e79df5646..b11e9e882a792 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1273,6 +1273,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { self.root.tables.optimized_mir.get(self, id).is_some() } + fn cross_crate_inlinable(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> bool { + self.root + .tables + .cross_crate_inlinable + .get(self, id) + .map(|v| v.decode((self, tcx.sess))) + .unwrap_or(false) + } + fn get_fn_has_self_parameter(self, id: DefIndex, sess: &'a Session) -> bool { self.root .tables diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index f27eee0d79a53..f451c521ba953 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -287,6 +287,7 @@ provide! { tcx, def_id, other, cdata, item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) } is_mir_available => { cdata.is_item_mir_available(def_id.index) } is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) } + cross_crate_inlinable => { cdata.cross_crate_inlinable(tcx, def_id.index) } dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) } is_private_dep => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a4ba943275e4c..81323a55aa364 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1046,7 +1046,7 @@ fn should_encode_mir( || (tcx.sess.opts.output_types.should_codegen() && reachable_set.contains(&def_id) && (generics.requires_monomorphization(tcx) - || tcx.codegen_fn_attrs(def_id).requests_inline())); + || tcx.cross_crate_inlinable(def_id))); // The function has a `const` modifier or is in a `#[const_trait]`. let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id()) || tcx.is_const_default_method(def_id.to_def_id()); @@ -1612,6 +1612,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EntryBuilder::encode_mir({:?})", def_id); if encode_opt { record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); + record!(self.tables.cross_crate_inlinable[def_id.to_def_id()] <- self.tcx.cross_crate_inlinable(def_id)); record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()] <- tcx.closure_saved_names_of_captured_variables(def_id)); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 42764af52c43f..26e1e6430e035 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -427,6 +427,7 @@ define_tables! { object_lifetime_default: Table>, optimized_mir: Table>>, mir_for_ctfe: Table>>, + cross_crate_inlinable: Table>, closure_saved_names_of_captured_variables: Table>>, mir_generator_witnesses: Table>>, promoted_mir: Table>>>, diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index bb1320942b077..01aea68147fe6 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -299,6 +299,29 @@ impl FixedSizeEncoding for bool { } } +impl FixedSizeEncoding for Option { + type ByteArray = [u8; 1]; + + #[inline] + fn from_bytes(b: &[u8; 1]) -> Self { + match b[0] { + 0 => Some(false), + 1 => Some(true), + _ => None, + } + } + + #[inline] + fn write_to_bytes(self, b: &mut [u8; 1]) { + debug_assert!(!self.is_default()); + b[0] = match self { + Some(false) => 0, + Some(true) => 1, + None => 2, + }; + } +} + impl FixedSizeEncoding for UnusedGenericParams { type ByteArray = [u8; 4]; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 340c5a769dbc4..940ab190ffc02 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2202,6 +2202,11 @@ rustc_queries! { query generics_require_sized_self(def_id: DefId) -> bool { desc { "check whether the item has a `where Self: Sized` bound" } } + + query cross_crate_inlinable(def_id: DefId) -> bool { + desc { "whether the item should be made inlinable across crates" } + separate_provide_extern + } } rustc_query_append! { define_callbacks! } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 0a425be52ffb5..0b308d5dec14f 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -245,16 +245,15 @@ impl<'tcx> InstanceDef<'tcx> { // drops of `Option::None` before LTO. We also respect the intent of // `#[inline]` on `Drop::drop` implementations. return ty.ty_adt_def().map_or(true, |adt_def| { - adt_def.destructor(tcx).map_or_else( - || adt_def.is_enum(), - |dtor| tcx.codegen_fn_attrs(dtor.did).requests_inline(), - ) + adt_def + .destructor(tcx) + .map_or_else(|| adt_def.is_enum(), |dtor| tcx.cross_crate_inlinable(dtor.did)) }); } if let ty::InstanceDef::ThreadLocalShim(..) = *self { return false; } - tcx.codegen_fn_attrs(self.def_id()).requests_inline() + tcx.cross_crate_inlinable(self.def_id()) } pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool { diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs new file mode 100644 index 0000000000000..f916a04dc1d48 --- /dev/null +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -0,0 +1,101 @@ +use rustc_attr::InlineAttr; +use rustc_hir::def_id::LocalDefId; +use rustc_middle::query::Providers; +use rustc_middle::ty::TyCtxt; +use rustc_session::config::OptLevel; + +pub fn provide(providers: &mut Providers) { + providers.cross_crate_inlinable = cross_crate_inlinable; +} + +fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { + if tcx.sess.opts.incremental.is_some() { + return false; + } + + match tcx.codegen_fn_attrs(def_id).inline { + InlineAttr::Never => return false, + InlineAttr::Hint | InlineAttr::Always => return true, + _ => {} + } + + if matches!(tcx.sess.opts.optimize, OptLevel::No | OptLevel::Default) { + return false; + } + + match tcx.hir().body_const_context(def_id) { + Some(rustc_hir::ConstContext::ConstFn) | None => {} + _ => return false, + } + + if tcx.lang_items().iter().any(|(_, lang_def_id)| lang_def_id == def_id.into()) { + return false; + } + + let mir = tcx.optimized_mir(def_id); + let mut checker = CostChecker { tcx, cost: 0, callee_body: mir }; + checker.visit_body(mir); + checker.cost <= tcx.sess.opts.unstable_opts.cross_crate_inline_threshold.unwrap_or(100) +} + +use rustc_middle::mir::visit::Visitor; +use rustc_middle::mir::*; + +const INSTR_COST: usize = 5; +const CALL_PENALTY: usize = 25; +const LANDINGPAD_PENALTY: usize = 50; +const RESUME_PENALTY: usize = 45; + +struct CostChecker<'b, 'tcx> { + tcx: TyCtxt<'tcx>, + cost: usize, + callee_body: &'b Body<'tcx>, +} + +impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { + fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) { + // Don't count StorageLive/StorageDead in the inlining cost. + match statement.kind { + StatementKind::StorageLive(_) + | StatementKind::StorageDead(_) + | StatementKind::Deinit(_) + | StatementKind::Nop => {} + _ => self.cost += INSTR_COST, + } + } + + fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, _: Location) { + let tcx = self.tcx; + match terminator.kind { + TerminatorKind::Drop { ref place, unwind, .. } => { + let ty = place.ty(self.callee_body, tcx).ty; + if !ty.is_trivially_pure_clone_copy() { + self.cost += CALL_PENALTY; + if let UnwindAction::Cleanup(_) = unwind { + self.cost += LANDINGPAD_PENALTY; + } + } + } + TerminatorKind::Call { unwind, .. } => { + self.cost += CALL_PENALTY; + if let UnwindAction::Cleanup(_) = unwind { + self.cost += LANDINGPAD_PENALTY; + } + } + TerminatorKind::Assert { unwind, .. } => { + self.cost += CALL_PENALTY; + if let UnwindAction::Cleanup(_) = unwind { + self.cost += LANDINGPAD_PENALTY; + } + } + TerminatorKind::UnwindResume => self.cost += RESUME_PENALTY, + TerminatorKind::InlineAsm { unwind, .. } => { + self.cost += INSTR_COST; + if let UnwindAction::Cleanup(_) = unwind { + self.cost += LANDINGPAD_PENALTY; + } + } + _ => self.cost += INSTR_COST, + } + } +} diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 32dfb7439053e..6eaf2f15ebca6 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -170,7 +170,13 @@ impl<'tcx> Inliner<'tcx> { callsite: &CallSite<'tcx>, ) -> Result, &'static str> { let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id()); - self.check_codegen_attributes(callsite, callee_attrs)?; + let cross_crate_inlinable = if callsite.callee.def_id().is_local() { + // Avoid a query cycle, cross_crate_inlinable is based on optimized_mir + callee_attrs.requests_inline() + } else { + self.tcx.cross_crate_inlinable(callsite.callee.def_id()) + }; + self.check_codegen_attributes(callsite, callee_attrs, cross_crate_inlinable)?; let terminator = caller_body[callsite.block].terminator.as_ref().unwrap(); let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() }; @@ -185,7 +191,7 @@ impl<'tcx> Inliner<'tcx> { self.check_mir_is_available(caller_body, &callsite.callee)?; let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?; - self.check_mir_body(callsite, callee_body, callee_attrs)?; + self.check_mir_body(callsite, callee_body, callee_attrs, cross_crate_inlinable)?; if !self.tcx.consider_optimizing(|| { format!("Inline {:?} into {:?}", callsite.callee, caller_body.source) @@ -401,6 +407,7 @@ impl<'tcx> Inliner<'tcx> { &self, callsite: &CallSite<'tcx>, callee_attrs: &CodegenFnAttrs, + cross_crate_inlinable: bool, ) -> Result<(), &'static str> { if let InlineAttr::Never = callee_attrs.inline { return Err("never inline hint"); @@ -414,7 +421,7 @@ impl<'tcx> Inliner<'tcx> { .non_erasable_generics(self.tcx, callsite.callee.def_id()) .next() .is_some(); - if !is_generic && !callee_attrs.requests_inline() { + if !is_generic && !cross_crate_inlinable { return Err("not exported"); } @@ -456,10 +463,11 @@ impl<'tcx> Inliner<'tcx> { callsite: &CallSite<'tcx>, callee_body: &Body<'tcx>, callee_attrs: &CodegenFnAttrs, + cross_crate_inlinable: bool, ) -> Result<(), &'static str> { let tcx = self.tcx; - let mut threshold = if callee_attrs.requests_inline() { + let mut threshold = if cross_crate_inlinable { self.tcx.sess.opts.unstable_opts.inline_mir_hint_threshold.unwrap_or(100) } else { self.tcx.sess.opts.unstable_opts.inline_mir_threshold.unwrap_or(50) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index c0a09b7a76127..69a46f3b2d8fc 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -62,6 +62,7 @@ mod const_prop; mod const_prop_lint; mod copy_prop; mod coverage; +mod cross_crate_inline; mod ctfe_limit; mod dataflow_const_prop; mod dead_store_elimination; @@ -123,6 +124,7 @@ pub fn provide(providers: &mut Providers) { coverage::query::provide(providers); ffi_unwind_calls::provide(providers); shim::provide(providers); + cross_crate_inline::provide(providers); *providers = Providers { mir_keys, mir_const, diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 1239d6d91ac68..97c9d9ee34c97 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -21,8 +21,8 @@ use rustc_target::spec::abi::Abi; // Returns true if the given item must be inlined because it may be // monomorphized or it was marked with `#[inline]`. This will only return // true for functions. -fn item_might_be_inlined(tcx: TyCtxt<'_>, item: &hir::Item<'_>, attrs: &CodegenFnAttrs) -> bool { - if attrs.requests_inline() { +fn item_might_be_inlined(tcx: TyCtxt<'_>, item: &hir::Item<'_>, inlinable: bool) -> bool { + if inlinable { return true; } @@ -41,9 +41,9 @@ fn method_might_be_inlined( impl_item: &hir::ImplItem<'_>, impl_src: LocalDefId, ) -> bool { - let codegen_fn_attrs = tcx.codegen_fn_attrs(impl_item.hir_id().owner.to_def_id()); + let inlinable = tcx.cross_crate_inlinable(impl_item.hir_id().owner.to_def_id()); let generics = tcx.generics_of(impl_item.owner_id); - if codegen_fn_attrs.requests_inline() || generics.requires_monomorphization(tcx) { + if inlinable || generics.requires_monomorphization(tcx) { return true; } if let hir::ImplItemKind::Fn(method_sig, _) = &impl_item.kind { @@ -52,7 +52,7 @@ fn method_might_be_inlined( } } match tcx.hir().find_by_def_id(impl_src) { - Some(Node::Item(item)) => item_might_be_inlined(tcx, &item, codegen_fn_attrs), + Some(Node::Item(item)) => item_might_be_inlined(tcx, &item, inlinable), Some(..) | None => span_bug!(impl_item.span, "impl did is not an item"), } } @@ -149,7 +149,7 @@ impl<'tcx> ReachableContext<'tcx> { match self.tcx.hir().find_by_def_id(def_id) { Some(Node::Item(item)) => match item.kind { hir::ItemKind::Fn(..) => { - item_might_be_inlined(self.tcx, &item, self.tcx.codegen_fn_attrs(def_id)) + item_might_be_inlined(self.tcx, &item, self.tcx.cross_crate_inlinable(def_id)) } _ => false, }, @@ -227,7 +227,7 @@ impl<'tcx> ReachableContext<'tcx> { if item_might_be_inlined( self.tcx, &item, - self.tcx.codegen_fn_attrs(item.owner_id), + self.tcx.cross_crate_inlinable(item.owner_id), ) { self.visit_nested_body(body); } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c1424db600eff..33658c22427e3 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1441,6 +1441,8 @@ options! { "combine CGUs into a single one"), crate_attr: Vec = (Vec::new(), parse_string_push, [TRACKED], "inject the given attribute in the crate"), + cross_crate_inline_threshold: Option = (None, parse_opt_number, [TRACKED], + "threshold to allow cross crate inlining of functions"), debug_info_for_profiling: bool = (false, parse_bool, [TRACKED], "emit discriminators and other data necessary for AutoFDO"), debug_macros: bool = (false, parse_bool, [TRACKED], diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 01b03de6acb5e..625b67a79ad09 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -530,6 +530,7 @@ fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> { // ensure that the code generation related to these panics is minimal as there's // only one location which panics rather than a bunch throughout the module. #[cfg(not(no_global_oom_handling))] +#[inline(never)] fn capacity_overflow() -> ! { panic!("capacity overflow"); } diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff index ec5f5c1f1fc6e..b2b84c5ae696a 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff @@ -66,7 +66,7 @@ } + } + -+ alloc15 (size: 8, align: 4) { ++ alloc14 (size: 8, align: 4) { + 02 00 00 00 05 20 00 00 │ ..... .. } diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff index 9bf8637ec7654..186ec3527cbf6 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff @@ -66,7 +66,7 @@ } + } + -+ alloc15 (size: 16, align: 8) { ++ alloc14 (size: 16, align: 8) { + 02 00 00 00 00 00 00 00 05 20 00 00 00 00 00 00 │ ......... ...... } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff index 7dc6d21a9076e..099b9823b993c 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff @@ -66,7 +66,7 @@ } + } + -+ alloc14 (size: 8, align: 4) { ++ alloc15 (size: 8, align: 4) { + 05 20 00 00 01 00 00 00 │ . ...... } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff index 0b000876a8660..766b46118247c 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff @@ -66,7 +66,7 @@ } + } + -+ alloc14 (size: 16, align: 8) { ++ alloc15 (size: 16, align: 8) { + 05 20 00 00 00 00 00 00 01 00 00 00 00 00 00 00 │ . .............. } diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-abort.diff index a538756ba2d04..298a608489937 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-abort.diff @@ -7,104 +7,104 @@ debug upper => _3; let mut _0: std::result::Result<(), std::fmt::Error>; let _4: bool; - let mut _5: &std::fmt::Formatter<'_>; - let mut _7: std::option::Option; - let mut _8: &std::fmt::Formatter<'_>; - let mut _9: isize; - let mut _11: &mut std::fmt::Formatter<'_>; - let mut _12: &T; - let mut _13: core::num::flt2dec::Sign; - let mut _14: u32; - let mut _15: u32; - let mut _16: usize; - let mut _17: bool; - let mut _18: &mut std::fmt::Formatter<'_>; - let mut _19: &T; - let mut _20: core::num::flt2dec::Sign; - let mut _21: bool; + let mut _6: std::option::Option; + let mut _7: isize; + let mut _9: &mut std::fmt::Formatter<'_>; + let mut _10: &T; + let mut _11: core::num::flt2dec::Sign; + let mut _12: u32; + let mut _13: u32; + let mut _14: usize; + let mut _15: bool; + let mut _16: &mut std::fmt::Formatter<'_>; + let mut _17: &T; + let mut _18: core::num::flt2dec::Sign; + let mut _19: bool; scope 1 { debug force_sign => _4; - let _6: core::num::flt2dec::Sign; + let _5: core::num::flt2dec::Sign; scope 2 { - debug sign => _6; + debug sign => _5; scope 3 { - debug precision => _10; - let _10: usize; + debug precision => _8; + let _8: usize; + scope 5 (inlined Formatter::<'_>::precision) { + debug self => _1; + } } } } + scope 4 (inlined Formatter::<'_>::sign_plus) { + debug self => _1; + let mut _20: u32; + let mut _21: u32; + } bb0: { StorageLive(_4); + StorageLive(_20); + StorageLive(_21); + _21 = ((*_1).0: u32); + _20 = BitAnd(move _21, const 1_u32); + StorageDead(_21); + _4 = Ne(move _20, const 0_u32); + StorageDead(_20); StorageLive(_5); - _5 = &(*_1); - _4 = Formatter::<'_>::sign_plus(move _5) -> [return: bb1, unwind unreachable]; + switchInt(_4) -> [0: bb2, otherwise: bb1]; } bb1: { - StorageDead(_5); - StorageLive(_6); - switchInt(_4) -> [0: bb3, otherwise: bb2]; +- _5 = MinusPlus; ++ _5 = const MinusPlus; + goto -> bb3; } bb2: { -- _6 = MinusPlus; -+ _6 = const MinusPlus; - goto -> bb4; +- _5 = Minus; ++ _5 = const Minus; + goto -> bb3; } bb3: { -- _6 = Minus; -+ _6 = const Minus; - goto -> bb4; + StorageLive(_6); + _6 = ((*_1).4: std::option::Option); + _7 = discriminant(_6); + switchInt(move _7) -> [1: bb4, otherwise: bb6]; } bb4: { - StorageLive(_7); - StorageLive(_8); - _8 = &(*_1); - _7 = Formatter::<'_>::precision(move _8) -> [return: bb5, unwind unreachable]; + _8 = ((_6 as Some).0: usize); + StorageLive(_11); + _11 = _5; + StorageLive(_12); + StorageLive(_13); + _13 = _8 as u32 (IntToInt); + _12 = Add(move _13, const 1_u32); + StorageDead(_13); + _0 = float_to_exponential_common_exact::(_1, _2, move _11, move _12, _3) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_8); - _9 = discriminant(_7); - switchInt(move _9) -> [1: bb6, otherwise: bb8]; + StorageDead(_12); + StorageDead(_11); + goto -> bb8; } bb6: { - _10 = ((_7 as Some).0: usize); - StorageLive(_13); - _13 = _6; - StorageLive(_14); - StorageLive(_15); - _15 = _10 as u32 (IntToInt); - _14 = Add(move _15, const 1_u32); - StorageDead(_15); - _0 = float_to_exponential_common_exact::(_1, _2, move _13, move _14, _3) -> [return: bb7, unwind unreachable]; + StorageLive(_18); + _18 = _5; + _0 = float_to_exponential_common_shortest::(_1, _2, move _18, _3) -> [return: bb7, unwind unreachable]; } bb7: { - StorageDead(_14); - StorageDead(_13); - goto -> bb10; + StorageDead(_18); + goto -> bb8; } bb8: { - StorageLive(_20); - _20 = _6; - _0 = float_to_exponential_common_shortest::(_1, _2, move _20, _3) -> [return: bb9, unwind unreachable]; - } - - bb9: { - StorageDead(_20); - goto -> bb10; - } - - bb10: { - StorageDead(_6); + StorageDead(_5); StorageDead(_4); - StorageDead(_7); + StorageDead(_6); return; } } diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff index 8a3dcfab44bd2..037f4f7cfac25 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff @@ -7,104 +7,104 @@ debug upper => _3; let mut _0: std::result::Result<(), std::fmt::Error>; let _4: bool; - let mut _5: &std::fmt::Formatter<'_>; - let mut _7: std::option::Option; - let mut _8: &std::fmt::Formatter<'_>; - let mut _9: isize; - let mut _11: &mut std::fmt::Formatter<'_>; - let mut _12: &T; - let mut _13: core::num::flt2dec::Sign; - let mut _14: u32; - let mut _15: u32; - let mut _16: usize; - let mut _17: bool; - let mut _18: &mut std::fmt::Formatter<'_>; - let mut _19: &T; - let mut _20: core::num::flt2dec::Sign; - let mut _21: bool; + let mut _6: std::option::Option; + let mut _7: isize; + let mut _9: &mut std::fmt::Formatter<'_>; + let mut _10: &T; + let mut _11: core::num::flt2dec::Sign; + let mut _12: u32; + let mut _13: u32; + let mut _14: usize; + let mut _15: bool; + let mut _16: &mut std::fmt::Formatter<'_>; + let mut _17: &T; + let mut _18: core::num::flt2dec::Sign; + let mut _19: bool; scope 1 { debug force_sign => _4; - let _6: core::num::flt2dec::Sign; + let _5: core::num::flt2dec::Sign; scope 2 { - debug sign => _6; + debug sign => _5; scope 3 { - debug precision => _10; - let _10: usize; + debug precision => _8; + let _8: usize; + scope 5 (inlined Formatter::<'_>::precision) { + debug self => _1; + } } } } + scope 4 (inlined Formatter::<'_>::sign_plus) { + debug self => _1; + let mut _20: u32; + let mut _21: u32; + } bb0: { StorageLive(_4); + StorageLive(_20); + StorageLive(_21); + _21 = ((*_1).0: u32); + _20 = BitAnd(move _21, const 1_u32); + StorageDead(_21); + _4 = Ne(move _20, const 0_u32); + StorageDead(_20); StorageLive(_5); - _5 = &(*_1); - _4 = Formatter::<'_>::sign_plus(move _5) -> [return: bb1, unwind continue]; + switchInt(_4) -> [0: bb2, otherwise: bb1]; } bb1: { - StorageDead(_5); - StorageLive(_6); - switchInt(_4) -> [0: bb3, otherwise: bb2]; +- _5 = MinusPlus; ++ _5 = const MinusPlus; + goto -> bb3; } bb2: { -- _6 = MinusPlus; -+ _6 = const MinusPlus; - goto -> bb4; +- _5 = Minus; ++ _5 = const Minus; + goto -> bb3; } bb3: { -- _6 = Minus; -+ _6 = const Minus; - goto -> bb4; + StorageLive(_6); + _6 = ((*_1).4: std::option::Option); + _7 = discriminant(_6); + switchInt(move _7) -> [1: bb4, otherwise: bb6]; } bb4: { - StorageLive(_7); - StorageLive(_8); - _8 = &(*_1); - _7 = Formatter::<'_>::precision(move _8) -> [return: bb5, unwind continue]; + _8 = ((_6 as Some).0: usize); + StorageLive(_11); + _11 = _5; + StorageLive(_12); + StorageLive(_13); + _13 = _8 as u32 (IntToInt); + _12 = Add(move _13, const 1_u32); + StorageDead(_13); + _0 = float_to_exponential_common_exact::(_1, _2, move _11, move _12, _3) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_8); - _9 = discriminant(_7); - switchInt(move _9) -> [1: bb6, otherwise: bb8]; + StorageDead(_12); + StorageDead(_11); + goto -> bb8; } bb6: { - _10 = ((_7 as Some).0: usize); - StorageLive(_13); - _13 = _6; - StorageLive(_14); - StorageLive(_15); - _15 = _10 as u32 (IntToInt); - _14 = Add(move _15, const 1_u32); - StorageDead(_15); - _0 = float_to_exponential_common_exact::(_1, _2, move _13, move _14, _3) -> [return: bb7, unwind continue]; + StorageLive(_18); + _18 = _5; + _0 = float_to_exponential_common_shortest::(_1, _2, move _18, _3) -> [return: bb7, unwind continue]; } bb7: { - StorageDead(_14); - StorageDead(_13); - goto -> bb10; + StorageDead(_18); + goto -> bb8; } bb8: { - StorageLive(_20); - _20 = _6; - _0 = float_to_exponential_common_shortest::(_1, _2, move _20, _3) -> [return: bb9, unwind continue]; - } - - bb9: { - StorageDead(_20); - goto -> bb10; - } - - bb10: { - StorageDead(_6); + StorageDead(_5); StorageDead(_4); - StorageDead(_7); + StorageDead(_6); return; } } diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff index 4fcd49994f0d7..b8d41ef0949e7 100644 --- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff @@ -12,12 +12,53 @@ + scope 3 (inlined std::ptr::drop_in_place::> - shim(Some(Vec))) { + let mut _6: &mut std::vec::Vec; + let mut _7: (); ++ scope 4 (inlined as Drop>::drop) { ++ debug self => _6; ++ let mut _8: *mut [A]; ++ let mut _9: *mut A; ++ let mut _10: usize; ++ scope 5 { ++ scope 6 (inlined Vec::::as_mut_ptr) { ++ debug self => _6; ++ let mut _11: &alloc::raw_vec::RawVec; ++ scope 7 (inlined alloc::raw_vec::RawVec::::ptr) { ++ debug self => _11; ++ let mut _13: std::ptr::NonNull; ++ scope 8 (inlined Unique::::as_ptr) { ++ debug ((self: Unique).0: std::ptr::NonNull) => _13; ++ debug ((self: Unique).1: std::marker::PhantomData) => const ZeroSized: PhantomData; ++ scope 9 (inlined NonNull::::as_ptr) { ++ debug self => _13; ++ let mut _12: *const A; ++ } ++ } ++ } ++ } ++ scope 10 (inlined slice_from_raw_parts_mut::) { ++ debug data => _9; ++ debug len => _10; ++ let mut _14: *mut (); ++ scope 11 (inlined ptr::mut_ptr::::cast::<()>) { ++ debug self => _9; ++ } ++ scope 12 (inlined std::ptr::from_raw_parts_mut::<[A]>) { ++ debug data_address => _14; ++ debug metadata => _10; ++ let mut _15: std::ptr::metadata::PtrRepr<[A]>; ++ let mut _16: std::ptr::metadata::PtrComponents<[A]>; ++ let mut _17: *const (); ++ scope 13 { ++ } ++ } ++ } ++ } ++ } + } } scope 2 { -+ scope 4 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { -+ let mut _8: isize; -+ let mut _9: isize; ++ scope 14 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { ++ let mut _18: isize; ++ let mut _19: isize; + } } @@ -29,7 +70,35 @@ + StorageLive(_6); + StorageLive(_7); + _6 = &mut (*_4); -+ _7 = as Drop>::drop(move _6) -> [return: bb2, unwind unreachable]; ++ StorageLive(_8); ++ StorageLive(_9); ++ StorageLive(_11); ++ StorageLive(_13); ++ _13 = ((((*_6).0: alloc::raw_vec::RawVec).0: std::ptr::Unique).0: std::ptr::NonNull); ++ StorageLive(_12); ++ _12 = (_13.0: *const A); ++ _9 = move _12 as *mut A (PtrToPtr); ++ StorageDead(_12); ++ StorageDead(_13); ++ StorageDead(_11); ++ StorageLive(_10); ++ _10 = ((*_6).1: usize); ++ StorageLive(_14); ++ _14 = _9 as *mut () (PtrToPtr); ++ StorageLive(_15); ++ StorageLive(_16); ++ StorageLive(_17); ++ _17 = _14 as *const () (PointerCoercion(MutToConstPointer)); ++ _16 = ptr::metadata::PtrComponents::<[A]> { data_address: move _17, metadata: _10 }; ++ StorageDead(_17); ++ _15 = ptr::metadata::PtrRepr::<[A]> { const_ptr: move _16 }; ++ StorageDead(_16); ++ _8 = (_15.1: *mut [A]); ++ StorageDead(_15); ++ StorageDead(_14); ++ StorageDead(_10); ++ StorageDead(_9); ++ _7 = std::ptr::drop_in_place::<[A]>(move _8) -> [return: bb2, unwind unreachable]; } bb1: { @@ -40,19 +109,20 @@ StorageLive(_5); _5 = _2; - _0 = std::ptr::drop_in_place::>(move _5) -> [return: bb2, unwind unreachable]; -+ StorageLive(_8); -+ StorageLive(_9); -+ _8 = discriminant((*_5)); -+ switchInt(move _8) -> [0: bb3, otherwise: bb4]; ++ StorageLive(_18); ++ StorageLive(_19); ++ _18 = discriminant((*_5)); ++ switchInt(move _18) -> [0: bb3, otherwise: bb4]; } bb2: { ++ StorageDead(_8); + drop(((*_4).0: alloc::raw_vec::RawVec)) -> [return: bb1, unwind unreachable]; + } + + bb3: { -+ StorageDead(_9); -+ StorageDead(_8); ++ StorageDead(_19); ++ StorageDead(_18); StorageDead(_5); return; + } diff --git a/tests/ui/hygiene/panic-location.run.stderr b/tests/ui/hygiene/panic-location.run.stderr index 5ed0d9fcf1ef1..1fd61084130a9 100644 --- a/tests/ui/hygiene/panic-location.run.stderr +++ b/tests/ui/hygiene/panic-location.run.stderr @@ -1,3 +1,3 @@ -thread 'main' panicked at library/alloc/src/raw_vec.rs:534:5: +thread 'main' panicked at library/alloc/src/raw_vec.rs:535:5: capacity overflow note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/tests/ui/process/println-with-broken-pipe.run.stderr b/tests/ui/process/println-with-broken-pipe.run.stderr index a334c0ad20473..b1a18f52bd8e1 100644 --- a/tests/ui/process/println-with-broken-pipe.run.stderr +++ b/tests/ui/process/println-with-broken-pipe.run.stderr @@ -1,3 +1,3 @@ -thread 'main' panicked at library/std/src/io/stdio.rs:LL:CC: +thread 'main' panicked at $SRC_DIR/std/src/io/stdio.rs:LL:COL: failed printing to stdout: Broken pipe (os error 32) note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace