diff --git a/Cargo.lock b/Cargo.lock index ef6b0a5959f8c..4eafda94037c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,12 @@ dependencies = [ "rand_xorshift", ] +[[package]] +name = "allocator-api2" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4f263788a35611fba42eb41ff811c5d0360c58b97402570312a350736e2542e" + [[package]] name = "ammonia" version = "3.2.0" @@ -1522,6 +1528,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" dependencies = [ "ahash 0.8.2", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +dependencies = [ + "allocator-api2", "compiler_builtins", "rustc-std-workspace-alloc", "rustc-std-workspace-core", @@ -4633,7 +4648,7 @@ dependencies = [ "core", "dlmalloc", "fortanix-sgx-abi", - "hashbrown 0.13.1", + "hashbrown 0.14.0", "hermit-abi 0.3.0", "libc", "miniz_oxide", diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index f11c1c77f9cfc..73f9deb3143a7 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -57,48 +57,54 @@ pub trait LayoutCalculator { // run and bias niches to the right and then check which one is closer to one of the struct's // edges. if let Some(layout) = &layout { - if let Some(niche) = layout.largest_niche { - let head_space = niche.offset.bytes(); - let niche_length = niche.value.size(dl).bytes(); - let tail_space = layout.size.bytes() - head_space - niche_length; - - // This may end up doing redundant work if the niche is already in the last field - // (e.g. a trailing bool) and there is tail padding. But it's non-trivial to get - // the unpadded size so we try anyway. - if fields.len() > 1 && head_space != 0 && tail_space > 0 { - let alt_layout = univariant(self, dl, fields, repr, kind, NicheBias::End) - .expect("alt layout should always work"); - let niche = alt_layout - .largest_niche - .expect("alt layout should have a niche like the regular one"); - let alt_head_space = niche.offset.bytes(); - let alt_niche_len = niche.value.size(dl).bytes(); - let alt_tail_space = alt_layout.size.bytes() - alt_head_space - alt_niche_len; - - debug_assert_eq!(layout.size.bytes(), alt_layout.size.bytes()); - - let prefer_alt_layout = - alt_head_space > head_space && alt_head_space > tail_space; - - debug!( - "sz: {}, default_niche_at: {}+{}, default_tail_space: {}, alt_niche_at/head_space: {}+{}, alt_tail: {}, num_fields: {}, better: {}\n\ - layout: {}\n\ - alt_layout: {}\n", - layout.size.bytes(), - head_space, - niche_length, - tail_space, - alt_head_space, - alt_niche_len, - alt_tail_space, - layout.fields.count(), - prefer_alt_layout, - format_field_niches(&layout, &fields, &dl), - format_field_niches(&alt_layout, &fields, &dl), - ); - - if prefer_alt_layout { - return Some(alt_layout); + // Don't try to calculate an end-biased layout for unsizable structs, + // otherwise we could end up with different layouts for + // Foo and Foo which would break unsizing + if !matches!(kind, StructKind::MaybeUnsized) { + if let Some(niche) = layout.largest_niche { + let head_space = niche.offset.bytes(); + let niche_length = niche.value.size(dl).bytes(); + let tail_space = layout.size.bytes() - head_space - niche_length; + + // This may end up doing redundant work if the niche is already in the last field + // (e.g. a trailing bool) and there is tail padding. But it's non-trivial to get + // the unpadded size so we try anyway. + if fields.len() > 1 && head_space != 0 && tail_space > 0 { + let alt_layout = univariant(self, dl, fields, repr, kind, NicheBias::End) + .expect("alt layout should always work"); + let niche = alt_layout + .largest_niche + .expect("alt layout should have a niche like the regular one"); + let alt_head_space = niche.offset.bytes(); + let alt_niche_len = niche.value.size(dl).bytes(); + let alt_tail_space = + alt_layout.size.bytes() - alt_head_space - alt_niche_len; + + debug_assert_eq!(layout.size.bytes(), alt_layout.size.bytes()); + + let prefer_alt_layout = + alt_head_space > head_space && alt_head_space > tail_space; + + debug!( + "sz: {}, default_niche_at: {}+{}, default_tail_space: {}, alt_niche_at/head_space: {}+{}, alt_tail: {}, num_fields: {}, better: {}\n\ + layout: {}\n\ + alt_layout: {}\n", + layout.size.bytes(), + head_space, + niche_length, + tail_space, + alt_head_space, + alt_niche_len, + alt_tail_space, + layout.fields.count(), + prefer_alt_layout, + format_field_niches(&layout, &fields, &dl), + format_field_niches(&alt_layout, &fields, &dl), + ); + + if prefer_alt_layout { + return Some(alt_layout); + } } } } @@ -828,6 +834,7 @@ fn univariant( if optimize && fields.len() > 1 { let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() }; let optimizing = &mut inverse_memory_index.raw[..end]; + let fields_excluding_tail = &fields.raw[..end]; // If `-Z randomize-layout` was enabled for the type definition we can shuffle // the field ordering to try and catch some code making assumptions about layouts @@ -844,8 +851,11 @@ fn univariant( } // Otherwise we just leave things alone and actually optimize the type's fields } else { - let max_field_align = fields.iter().map(|f| f.align().abi.bytes()).max().unwrap_or(1); - let largest_niche_size = fields + // To allow unsizing `&Foo` -> `&Foo`, the layout of the struct must + // not depend on the layout of the tail. + let max_field_align = + fields_excluding_tail.iter().map(|f| f.align().abi.bytes()).max().unwrap_or(1); + let largest_niche_size = fields_excluding_tail .iter() .filter_map(|f| f.largest_niche()) .map(|n| n.available(dl)) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 04ed276787652..a0979bbda5452 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -364,7 +364,12 @@ impl<'a> AstValidator<'a> { self.err_handler().emit_err(errors::BoundInContext { span, ctx }); } - fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) { + fn check_foreign_ty_genericless( + &self, + generics: &Generics, + before_where_clause: &TyAliasWhereClause, + after_where_clause: &TyAliasWhereClause, + ) { let cannot_have = |span, descr, remove_descr| { self.err_handler().emit_err(errors::ExternTypesCannotHave { span, @@ -378,9 +383,14 @@ impl<'a> AstValidator<'a> { cannot_have(generics.span, "generic parameters", "generic parameters"); } - if !generics.where_clause.predicates.is_empty() { - cannot_have(where_span, "`where` clauses", "`where` clause"); - } + let check_where_clause = |where_clause: &TyAliasWhereClause| { + if let TyAliasWhereClause(true, where_clause_span) = where_clause { + cannot_have(*where_clause_span, "`where` clauses", "`where` clause"); + } + }; + + check_where_clause(before_where_clause); + check_where_clause(after_where_clause); } fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option) { @@ -1039,7 +1049,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_defaultness(fi.span, *defaultness); self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span)); self.check_type_no_bounds(bounds, "`extern` blocks"); - self.check_foreign_ty_genericless(generics, where_clauses.0.1); + self.check_foreign_ty_genericless(generics, &where_clauses.0, &where_clauses.1); self.check_foreign_item_ascii_only(fi.ident); } ForeignItemKind::Static(_, _, body) => { diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index a561496b02639..b5d5071dc0536 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -61,7 +61,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn infer_opaque_types( &self, infcx: &InferCtxt<'tcx>, - opaque_ty_decls: FxIndexMap, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, + opaque_ty_decls: FxIndexMap, OpaqueHiddenType<'tcx>>, ) -> FxIndexMap> { let mut result: FxIndexMap> = FxIndexMap::default(); @@ -72,7 +72,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { .collect(); debug!(?member_constraints); - for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls { + for (opaque_type_key, concrete_type) in opaque_ty_decls { let substs = opaque_type_key.substs; debug!(?concrete_type, ?substs); @@ -143,7 +143,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { let ty = infcx.infer_opaque_definition_from_instantiation( opaque_type_key, universal_concrete_type, - origin, ); // Sometimes two opaque types are the same only after we remap the generic parameters // back to the opaque type definition. E.g. we may have `OpaqueType` mapped to `(X, Y)` @@ -215,7 +214,6 @@ pub trait InferCtxtExt<'tcx> { &self, opaque_type_key: OpaqueTypeKey<'tcx>, instantiated_ty: OpaqueHiddenType<'tcx>, - origin: OpaqueTyOrigin, ) -> Ty<'tcx>; } @@ -248,109 +246,115 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { &self, opaque_type_key: OpaqueTypeKey<'tcx>, instantiated_ty: OpaqueHiddenType<'tcx>, - origin: OpaqueTyOrigin, ) -> Ty<'tcx> { if let Some(e) = self.tainted_by_errors() { return self.tcx.ty_error(e); } + if let Err(guar) = + check_opaque_type_parameter_valid(self.tcx, opaque_type_key, instantiated_ty.span) + { + return self.tcx.ty_error(guar); + } + let definition_ty = instantiated_ty .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false) .ty; - if let Err(guar) = check_opaque_type_parameter_valid( + // `definition_ty` does not live in of the current inference context, + // so lets make sure that we don't accidentally misuse our current `infcx`. + match check_opaque_type_well_formed( self.tcx, - opaque_type_key, - origin, + self.next_trait_solver(), + opaque_type_key.def_id, instantiated_ty.span, + definition_ty, ) { - return self.tcx.ty_error(guar); + Ok(hidden_ty) => hidden_ty, + Err(guar) => self.tcx.ty_error(guar), } + } +} - // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs` - // on stable and we'd break that. - let OpaqueTyOrigin::TyAlias { .. } = origin else { - return definition_ty; - }; - let def_id = opaque_type_key.def_id; - // This logic duplicates most of `check_opaque_meets_bounds`. - // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely. - let param_env = self.tcx.param_env(def_id); - // HACK This bubble is required for this tests to pass: - // nested-return-type2-tait2.rs - // nested-return-type2-tait3.rs - // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error` - // and prepopulate this `InferCtxt` with known opaque values, rather than - // using the `Bind` anchor here. For now it's fine. - let infcx = self - .tcx - .infer_ctxt() - .with_opaque_type_inference(if self.next_trait_solver() { - DefiningAnchor::Bind(def_id) - } else { - DefiningAnchor::Bubble - }) - .build(); - let ocx = ObligationCtxt::new(&infcx); - // Require the hidden type to be well-formed with only the generics of the opaque type. - // Defining use functions may have more bounds than the opaque type, which is ok, as long as the - // hidden type is well formed even without those bounds. - let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())); - - let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id); +/// This logic duplicates most of `check_opaque_meets_bounds`. +/// FIXME(oli-obk): Also do region checks here and then consider removing +/// `check_opaque_meets_bounds` entirely. +fn check_opaque_type_well_formed<'tcx>( + tcx: TyCtxt<'tcx>, + next_trait_solver: bool, + def_id: LocalDefId, + definition_span: Span, + definition_ty: Ty<'tcx>, +) -> Result, ErrorGuaranteed> { + // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs` + // on stable and we'd break that. + let opaque_ty_hir = tcx.hir().expect_item(def_id); + let OpaqueTyOrigin::TyAlias { .. } = opaque_ty_hir.expect_opaque_ty().origin else { + return Ok(definition_ty); + }; + let param_env = tcx.param_env(def_id); + // HACK This bubble is required for this tests to pass: + // nested-return-type2-tait2.rs + // nested-return-type2-tait3.rs + // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error` + // and prepopulate this `InferCtxt` with known opaque values, rather than + // using the `Bind` anchor here. For now it's fine. + let infcx = tcx + .infer_ctxt() + .with_next_trait_solver(next_trait_solver) + .with_opaque_type_inference(if next_trait_solver { + DefiningAnchor::Bind(def_id) + } else { + DefiningAnchor::Bubble + }) + .build(); + let ocx = ObligationCtxt::new(&infcx); + let identity_substs = InternalSubsts::identity_for_item(tcx, def_id); - // Require that the hidden type actually fulfills all the bounds of the opaque type, even without - // the bounds that the function supplies. - let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs); - if let Err(err) = ocx.eq( - &ObligationCause::misc(instantiated_ty.span, def_id), - param_env, - opaque_ty, - definition_ty, - ) { + // Require that the hidden type actually fulfills all the bounds of the opaque type, even without + // the bounds that the function supplies. + let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), identity_substs); + ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty) + .map_err(|err| { infcx .err_ctxt() .report_mismatched_types( - &ObligationCause::misc(instantiated_ty.span, def_id), + &ObligationCause::misc(definition_span, def_id), opaque_ty, definition_ty, err, ) - .emit(); - } + .emit() + })?; - ocx.register_obligation(Obligation::misc( - infcx.tcx, - instantiated_ty.span, - def_id, - param_env, - predicate, - )); + // Require the hidden type to be well-formed with only the generics of the opaque type. + // Defining use functions may have more bounds than the opaque type, which is ok, as long as the + // hidden type is well formed even without those bounds. + let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())); + ocx.register_obligation(Obligation::misc(tcx, definition_span, def_id, param_env, predicate)); - // Check that all obligations are satisfied by the implementation's - // version. - let errors = ocx.select_all_or_error(); + // Check that all obligations are satisfied by the implementation's + // version. + let errors = ocx.select_all_or_error(); - // This is still required for many(half of the tests in ui/type-alias-impl-trait) - // tests to pass - let _ = infcx.take_opaque_types(); + // This is still required for many(half of the tests in ui/type-alias-impl-trait) + // tests to pass + let _ = infcx.take_opaque_types(); - if errors.is_empty() { - definition_ty - } else { - let reported = infcx.err_ctxt().report_fulfillment_errors(&errors); - self.tcx.ty_error(reported) - } + if errors.is_empty() { + Ok(definition_ty) + } else { + Err(infcx.err_ctxt().report_fulfillment_errors(&errors)) } } fn check_opaque_type_parameter_valid( tcx: TyCtxt<'_>, opaque_type_key: OpaqueTypeKey<'_>, - origin: OpaqueTyOrigin, span: Span, ) -> Result<(), ErrorGuaranteed> { - match origin { + let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id); + match opaque_ty_hir.expect_opaque_ty().origin { // No need to check return position impl trait (RPIT) // because for type and const parameters they are correct // by construction: we convert diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 00fd3762fa773..6697e1aff7dd0 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -7,7 +7,6 @@ use std::{fmt, iter, mem}; use either::Either; -use hir::OpaqueTyOrigin; use rustc_data_structures::frozen::Frozen; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::ErrorGuaranteed; @@ -28,6 +27,7 @@ use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::AssertKind; use rustc_middle::mir::*; use rustc_middle::traits::query::NoSolution; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::subst::{SubstsRef, UserSubsts}; @@ -241,7 +241,7 @@ pub(crate) fn type_check<'mir, 'tcx>( hidden_type.ty = infcx.tcx.ty_error(reported); } - (opaque_type_key, (hidden_type, decl.origin)) + (opaque_type_key, hidden_type) }) .collect(); @@ -878,8 +878,7 @@ struct BorrowCheckContext<'a, 'tcx> { pub(crate) struct MirTypeckResults<'tcx> { pub(crate) constraints: MirTypeckRegionConstraints<'tcx>, pub(crate) universal_region_relations: Frozen>, - pub(crate) opaque_type_values: - FxIndexMap, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, + pub(crate) opaque_type_values: FxIndexMap, OpaqueHiddenType<'tcx>>, } /// A collection of region constraints that must be satisfied for the @@ -1053,15 +1052,28 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::OpaqueType, CustomTypeOp::new( |ocx| { - for (key, hidden_ty) in renumbered_opaques { - ocx.register_infer_ok_obligations( - ocx.infcx.register_hidden_type_in_new_solver( - key, - param_env, - hidden_ty.ty, - )?, + let mut obligations = Vec::new(); + for (opaque_type_key, hidden_ty) in renumbered_opaques { + let cause = ObligationCause::dummy(); + ocx.infcx.insert_hidden_type( + opaque_type_key, + &cause, + param_env, + hidden_ty.ty, + true, + &mut obligations, + )?; + + ocx.infcx.add_item_bounds_for_hidden_type( + opaque_type_key, + cause, + param_env, + hidden_ty.ty, + &mut obligations, ); } + + ocx.register_obligations(obligations); Ok(()) }, "register pre-defined opaques", diff --git a/compiler/rustc_codegen_cranelift/patches/0023-coretests-Ignore-failing-tests.patch b/compiler/rustc_codegen_cranelift/patches/0023-coretests-Ignore-failing-tests.patch index f2cb82751f082..385f5a8a2e039 100644 --- a/compiler/rustc_codegen_cranelift/patches/0023-coretests-Ignore-failing-tests.patch +++ b/compiler/rustc_codegen_cranelift/patches/0023-coretests-Ignore-failing-tests.patch @@ -10,42 +10,6 @@ Subject: [PATCH] [core] Ignore failing tests library/core/tests/time.rs | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) -diff --git a/array.rs b/array.rs -index 4bc44e9..8e3c7a4 100644 ---- a/array.rs -+++ b/array.rs -@@ -242,6 +242,7 @@ fn iterator_drops() { - assert_eq!(i.get(), 5); - } - -+/* - // This test does not work on targets without panic=unwind support. - // To work around this problem, test is marked is should_panic, so it will - // be automagically skipped on unsuitable targets, such as -@@ -283,6 +284,7 @@ fn array_default_impl_avoids_leaks_on_panic() { - assert_eq!(COUNTER.load(Relaxed), 0); - panic!("test succeeded") - } -+*/ - - #[test] - fn empty_array_is_always_default() { -@@ -304,6 +304,7 @@ fn array_map() { - assert_eq!(b, [1, 2, 3]); - } - -+/* - // See note on above test for why `should_panic` is used. - #[test] - #[should_panic(expected = "test succeeded")] -@@ -332,6 +333,7 @@ fn array_map_drop_safety() { - assert_eq!(DROPPED.load(Ordering::SeqCst), num_to_create); - panic!("test succeeded") - } -+*/ - - #[test] - fn cell_allows_array_cycle() { diff --git a/atomic.rs b/atomic.rs index 13b12db..96fe4b9 100644 --- a/atomic.rs diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 166454d3ae74c..fa67a1b331011 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1385,7 +1385,7 @@ fn vcall_visibility_metadata<'ll, 'tcx>( let trait_def_id = trait_ref_self.def_id(); let trait_vis = cx.tcx.visibility(trait_def_id); - let cgus = cx.sess().codegen_units(); + let cgus = cx.sess().codegen_units().as_usize(); let single_cgu = cgus == 1; let lto = cx.sess().lto(); diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 9be69e560e888..109e9959aeac8 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -646,10 +646,10 @@ fn produce_final_output_artifacts( // rlib. let needs_crate_object = crate_output.outputs.contains_key(&OutputType::Exe); - let keep_numbered_bitcode = user_wants_bitcode && sess.codegen_units() > 1; + let keep_numbered_bitcode = user_wants_bitcode && sess.codegen_units().as_usize() > 1; let keep_numbered_objects = - needs_crate_object || (user_wants_objects && sess.codegen_units() > 1); + needs_crate_object || (user_wants_objects && sess.codegen_units().as_usize() > 1); for module in compiled_modules.modules.iter() { if let Some(ref path) = module.object { @@ -1923,7 +1923,7 @@ impl OngoingCodegen { // FIXME: time_llvm_passes support - does this use a global context or // something? - if sess.codegen_units() == 1 && sess.opts.unstable_opts.time_llvm_passes { + if sess.codegen_units().as_usize() == 1 && sess.opts.unstable_opts.time_llvm_passes { self.backend.print_pass_timings() } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 5b75205442ba1..2f1c78197275d 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -430,6 +430,13 @@ fn run_compiler( sess.code_stats.print_type_sizes(); } + if sess.opts.unstable_opts.print_vtable_sizes { + let crate_name = + compiler.session().opts.crate_name.as_deref().unwrap_or(""); + + sess.code_stats.print_vtable_sizes(crate_name); + } + let linker = queries.linker()?; Ok(Some(linker)) })?; @@ -764,9 +771,7 @@ fn print_crate_info( use rustc_target::spec::SplitDebuginfo::{Off, Packed, Unpacked}; for split in &[Off, Packed, Unpacked] { - let stable = sess.target.options.supported_split_debuginfo.contains(split); - let unstable_ok = sess.unstable_options(); - if stable || unstable_ok { + if sess.target.options.supported_split_debuginfo.contains(split) { safe_println!("{split}"); } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 7a297ea0d5f82..24d1cc8af82f5 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -4,7 +4,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(array_windows)] -#![feature(drain_filter)] +#![feature(extract_if)] #![feature(if_let_guard)] #![feature(let_chains)] #![feature(never_type)] @@ -1399,7 +1399,7 @@ impl HandlerInner { !self.emitted_diagnostics.insert(diagnostic_hash) }; - diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {}); + diagnostic.children.extract_if(already_emitted_sub).for_each(|_| {}); self.emitter.emit_diagnostic(diagnostic); if diagnostic.is_error() { diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index a9e8afe434ed3..1037a49acdf32 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -26,10 +26,9 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{walk_generics, Visitor as _}; use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin}; -use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; +use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability::AllowUnstable; -use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; @@ -43,7 +42,10 @@ use rustc_trait_selection::traits::error_reporting::{ report_object_safety_error, suggestions::NextTypeParamName, }; use rustc_trait_selection::traits::wf::object_region_bounds; -use rustc_trait_selection::traits::{self, astconv_object_safety_violations, ObligationCtxt}; +use rustc_trait_selection::traits::{ + self, astconv_object_safety_violations, NormalizeExt, ObligationCtxt, +}; +use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use smallvec::{smallvec, SmallVec}; use std::collections::BTreeSet; @@ -2442,6 +2444,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { return Ok(None); } + if !tcx.features().inherent_associated_types { + tcx.sess + .delay_span_bug(span, "found inherent assoc type without the feature being gated"); + } + // // Select applicable inherent associated type candidates modulo regions. // @@ -2465,23 +2472,53 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut fulfillment_errors = Vec::new(); let mut applicable_candidates: Vec<_> = infcx.probe(|_| { - let universe = infcx.create_next_universe(); - // Regions are not considered during selection. - // FIXME(non_lifetime_binders): Here we are "truncating" or "flattening" the universes - // of type and const binders. Is that correct in the selection phase? See also #109505. - let self_ty = tcx.replace_escaping_bound_vars_uncached( - self_ty, - FnMutDelegate { - regions: &mut |_| tcx.lifetimes.re_erased, - types: &mut |bv| { - tcx.mk_placeholder(ty::PlaceholderType { universe, bound: bv }) - }, - consts: &mut |bv, ty| { - tcx.mk_const(ty::PlaceholderConst { universe, bound: bv }, ty) - }, - }, - ); + let self_ty = self_ty + .fold_with(&mut BoundVarEraser { tcx, universe: infcx.create_next_universe() }); + + struct BoundVarEraser<'tcx> { + tcx: TyCtxt<'tcx>, + universe: ty::UniverseIndex, + } + + // FIXME(non_lifetime_binders): Don't assign the same universe to each placeholder. + impl<'tcx> TypeFolder> for BoundVarEraser<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + if r.is_late_bound() { self.tcx.lifetimes.re_erased } else { r } + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match *ty.kind() { + ty::Bound(_, bv) => self.tcx.mk_placeholder(ty::PlaceholderType { + universe: self.universe, + bound: bv, + }), + _ => ty.super_fold_with(self), + } + } + + fn fold_const( + &mut self, + ct: ty::Const<'tcx>, + ) -> as rustc_type_ir::Interner>::Const { + assert!(!ct.ty().has_escaping_bound_vars()); + + match ct.kind() { + ty::ConstKind::Bound(_, bv) => self.tcx.mk_const( + ty::PlaceholderConst { universe: self.universe, bound: bv }, + ct.ty(), + ), + _ => ct.super_fold_with(self), + } + } + } + + let InferOk { value: self_ty, obligations } = + infcx.at(&cause, param_env).normalize(self_ty); candidates .iter() @@ -2489,6 +2526,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .filter(|&(impl_, _)| { infcx.probe(|_| { let ocx = ObligationCtxt::new_in_snapshot(&infcx); + ocx.register_obligations(obligations.clone()); let impl_substs = infcx.fresh_substs_for_item(span, impl_); let impl_ty = tcx.type_of(impl_).subst(tcx, impl_substs); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index dce31975dbc5d..4fbe68b8b6c54 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -45,12 +45,7 @@ pub(super) fn compare_impl_method<'tcx>( debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref); let _: Result<_, ErrorGuaranteed> = try { - compare_self_type(tcx, impl_m, trait_m, impl_trait_ref)?; - compare_number_of_generics(tcx, impl_m, trait_m, false)?; - compare_generic_param_kinds(tcx, impl_m, trait_m, false)?; - compare_number_of_method_arguments(tcx, impl_m, trait_m)?; - compare_synthetic_generics(tcx, impl_m, trait_m)?; - compare_asyncness(tcx, impl_m, trait_m)?; + check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?; compare_method_predicate_entailment( tcx, impl_m, @@ -61,6 +56,26 @@ pub(super) fn compare_impl_method<'tcx>( }; } +/// Checks a bunch of different properties of the impl/trait methods for +/// compatibility, such as asyncness, number of argument, self receiver kind, +/// and number of early- and late-bound generics. +fn check_method_is_structurally_compatible<'tcx>( + tcx: TyCtxt<'tcx>, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, + impl_trait_ref: ty::TraitRef<'tcx>, + delay: bool, +) -> Result<(), ErrorGuaranteed> { + compare_self_type(tcx, impl_m, trait_m, impl_trait_ref, delay)?; + compare_number_of_generics(tcx, impl_m, trait_m, delay)?; + compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?; + compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?; + compare_synthetic_generics(tcx, impl_m, trait_m, delay)?; + compare_asyncness(tcx, impl_m, trait_m, delay)?; + check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?; + Ok(()) +} + /// This function is best explained by example. Consider a trait with it's implementation: /// /// ```rust @@ -177,9 +192,6 @@ fn compare_method_predicate_entailment<'tcx>( let impl_m_predicates = tcx.predicates_of(impl_m.def_id); let trait_m_predicates = tcx.predicates_of(trait_m.def_id); - // Check region bounds. - check_region_bounds_on_impl_item(tcx, impl_m, trait_m, false)?; - // Create obligations for each predicate declared by the impl // definition in the context of the trait's parameter // environment. We can't just use `impl_env.caller_bounds`, @@ -534,6 +546,7 @@ fn compare_asyncness<'tcx>( tcx: TyCtxt<'tcx>, impl_m: ty::AssocItem, trait_m: ty::AssocItem, + delay: bool, ) -> Result<(), ErrorGuaranteed> { if tcx.asyncness(trait_m.def_id) == hir::IsAsync::Async { match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() { @@ -544,11 +557,14 @@ fn compare_asyncness<'tcx>( // We don't know if it's ok, but at least it's already an error. } _ => { - return Err(tcx.sess.emit_err(crate::errors::AsyncTraitImplShouldBeAsync { - span: tcx.def_span(impl_m.def_id), - method_name: trait_m.name, - trait_item_span: tcx.hir().span_if_local(trait_m.def_id), - })); + return Err(tcx + .sess + .create_err(crate::errors::AsyncTraitImplShouldBeAsync { + span: tcx.def_span(impl_m.def_id), + method_name: trait_m.name, + trait_item_span: tcx.hir().span_if_local(trait_m.def_id), + }) + .emit_unless(delay)); } }; } @@ -602,9 +618,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // First, check a few of the same things as `compare_impl_method`, // just so we don't ICE during substitution later. - compare_number_of_generics(tcx, impl_m, trait_m, true)?; - compare_generic_param_kinds(tcx, impl_m, trait_m, true)?; - check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?; + check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; let trait_to_impl_substs = impl_trait_ref.substs; @@ -1097,6 +1111,7 @@ fn compare_self_type<'tcx>( impl_m: ty::AssocItem, trait_m: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, + delay: bool, ) -> Result<(), ErrorGuaranteed> { // Try to give more informative error messages about self typing // mismatches. Note that any mismatch will also be detected @@ -1145,7 +1160,7 @@ fn compare_self_type<'tcx>( } else { err.note_trait_signature(trait_m.name, trait_m.signature(tcx)); } - return Err(err.emit()); + return Err(err.emit_unless(delay)); } (true, false) => { @@ -1166,7 +1181,7 @@ fn compare_self_type<'tcx>( err.note_trait_signature(trait_m.name, trait_m.signature(tcx)); } - return Err(err.emit()); + return Err(err.emit_unless(delay)); } } @@ -1352,6 +1367,7 @@ fn compare_number_of_method_arguments<'tcx>( tcx: TyCtxt<'tcx>, impl_m: ty::AssocItem, trait_m: ty::AssocItem, + delay: bool, ) -> Result<(), ErrorGuaranteed> { let impl_m_fty = tcx.fn_sig(impl_m.def_id); let trait_m_fty = tcx.fn_sig(trait_m.def_id); @@ -1422,7 +1438,7 @@ fn compare_number_of_method_arguments<'tcx>( ), ); - return Err(err.emit()); + return Err(err.emit_unless(delay)); } Ok(()) @@ -1432,6 +1448,7 @@ fn compare_synthetic_generics<'tcx>( tcx: TyCtxt<'tcx>, impl_m: ty::AssocItem, trait_m: ty::AssocItem, + delay: bool, ) -> Result<(), ErrorGuaranteed> { // FIXME(chrisvittal) Clean up this function, list of FIXME items: // 1. Better messages for the span labels @@ -1551,7 +1568,7 @@ fn compare_synthetic_generics<'tcx>( } _ => unreachable!(), } - error_found = Some(err.emit()); + error_found = Some(err.emit_unless(delay)); } } if let Some(reported) = error_found { Err(reported) } else { Ok(()) } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a269a7a1d8b1e..4554d167080bd 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1449,7 +1449,7 @@ fn check_fn_or_method<'tcx>( let span = tcx.def_span(def_id); let has_implicit_self = hir_decl.implicit_self != hir::ImplicitSelfKind::None; let mut inputs = sig.inputs().iter().skip(if has_implicit_self { 1 } else { 0 }); - // Check that the argument is a tuple + // Check that the argument is a tuple and is sized if let Some(ty) = inputs.next() { wfcx.register_bound( ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall), @@ -1457,6 +1457,12 @@ fn check_fn_or_method<'tcx>( *ty, tcx.require_lang_item(hir::LangItem::Tuple, Some(span)), ); + wfcx.register_bound( + ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall), + wfcx.param_env, + *ty, + tcx.require_lang_item(hir::LangItem::Sized, Some(span)), + ); } else { tcx.sess.span_err( hir_decl.inputs.last().map_or(span, |input| input.span), diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index c7b9fc9a697f4..8b5c1791fc139 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -666,17 +666,15 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { tcx.ensure().fn_sig(def_id); } - hir::TraitItemKind::Const(.., Some(_)) => { + hir::TraitItemKind::Const(ty, body_id) => { tcx.ensure().type_of(def_id); - } - - hir::TraitItemKind::Const(hir_ty, _) => { - tcx.ensure().type_of(def_id); - // Account for `const C: _;`. - let mut visitor = HirPlaceholderCollector::default(); - visitor.visit_trait_item(trait_item); - if !tcx.sess.diagnostic().has_stashed_diagnostic(hir_ty.span, StashKey::ItemNoType) { - placeholder_type_error(tcx, None, visitor.0, false, None, "constant"); + if !tcx.sess.diagnostic().has_stashed_diagnostic(ty.span, StashKey::ItemNoType) + && !(is_suggestable_infer_ty(ty) && body_id.is_some()) + { + // Account for `const C: _;`. + let mut visitor = HirPlaceholderCollector::default(); + visitor.visit_trait_item(trait_item); + placeholder_type_error(tcx, None, visitor.0, false, None, "associated constant"); } } @@ -721,7 +719,14 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { placeholder_type_error(tcx, None, visitor.0, false, None, "associated type"); } - hir::ImplItemKind::Const(..) => {} + hir::ImplItemKind::Const(ty, _) => { + // Account for `const T: _ = ..;` + if !is_suggestable_infer_ty(ty) { + let mut visitor = HirPlaceholderCollector::default(); + visitor.visit_impl_item(impl_item); + placeholder_type_error(tcx, None, visitor.0, false, None, "associated constant"); + } + } } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c2b837fcfa670..318d0d0c22397 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -341,7 +341,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder, def_id: LocalDefId) -> ty::EarlyBinder { if is_suggestable_infer_ty(ty) { - infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant") + infer_placeholder_type( + tcx, + def_id, + body_id, + ty.span, + item.ident, + "associated constant", + ) } else { icx.to_ty(ty) } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 612d4ff3df843..5526dd4b007dd 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -106,10 +106,23 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) if item.defaultness(tcx).has_value() { cgp::parameters_for(&tcx.type_of(def_id).subst_identity(), true) } else { - Vec::new() + vec![] } } - ty::AssocKind::Fn | ty::AssocKind::Const => Vec::new(), + ty::AssocKind::Fn => { + if !tcx.lower_impl_trait_in_trait_to_assoc_ty() + && item.defaultness(tcx).has_value() + && tcx.impl_method_has_trait_impl_trait_tys(item.def_id) + && let Ok(table) = tcx.collect_return_position_impl_trait_in_trait_tys(def_id) + { + table.values().copied().flat_map(|ty| { + cgp::parameters_for(&ty.subst_identity(), true) + }).collect() + } else { + vec![] + } + } + ty::AssocKind::Const => vec![], } }) .collect(); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 5cd2cd50c113c..d2a1b1c1a428e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -59,8 +59,6 @@ This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(box_patterns)] #![feature(control_flow_enum)] -#![feature(drain_filter)] -#![feature(hash_drain_filter)] #![feature(if_let_guard)] #![feature(is_sorted)] #![feature(iter_intersperse)] diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 4728edd837a6c..c1c58db57648c 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -89,6 +89,8 @@ hir_typeck_suggest_boxing_note = for more on the distinction between the stack a hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new` +hir_typeck_suggest_ptr_null_mut = consider using `core::ptr::null_mut` instead + hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 7d2f7e876083a..444ff90595c23 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -510,6 +510,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .. } = self.type_var_origin(expected)? else { return None; }; + let Some(rpit_local_def_id) = rpit_def_id.as_local() else { return None; }; + if !matches!( + self.tcx.hir().expect_item(rpit_local_def_id).expect_opaque_ty().origin, + hir::OpaqueTyOrigin::FnReturn(..) + ) { + return None; + } + let sig = self.body_fn_sig()?; let substs = sig.output().walk().find_map(|arg| { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 4389ad6ef2678..9da72aae77660 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -470,6 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.require_lang_item(hir::LangItem::Tuple, Some(sp)), traits::ObligationCause::new(sp, self.body_id, traits::RustCall), ); + self.require_type_is_sized(ty, sp, traits::RustCall); } else { self.tcx.sess.span_err( sp, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 81231e8fe068b..79157eae7ed6d 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -36,9 +36,7 @@ //! ``` use crate::FnCtxt; -use rustc_errors::{ - struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, -}; +use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, Visitor}; @@ -58,7 +56,7 @@ use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TypeAndMut}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; -use rustc_span::{self, BytePos, DesugaringKind, Span}; +use rustc_span::{self, DesugaringKind}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; @@ -1702,9 +1700,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err); - let mut pointing_at_return_type = false; - let mut fn_output = None; - let parent_id = fcx.tcx.hir().parent_id(id); let parent = fcx.tcx.hir().get(parent_id); if let Some(expr) = expression @@ -1717,7 +1712,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // label pointing out the cause for the type coercion will be wrong // as prior return coercions would not be relevant (#57664). let fn_decl = if let (Some(expr), Some(blk_id)) = (expression, blk_id) { - pointing_at_return_type = + let pointing_at_return_type = fcx.suggest_mismatched_types_on_tail(&mut err, expr, expected, found, blk_id); if let (Some(cond_expr), true, false) = ( fcx.tcx.hir().get_if_cause(expr.hir_id), @@ -1749,7 +1744,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { if let Some((fn_id, fn_decl, can_suggest)) = fn_decl { if blk_id.is_none() { - pointing_at_return_type |= fcx.suggest_missing_return_type( + fcx.suggest_missing_return_type( &mut err, &fn_decl, expected, @@ -1758,9 +1753,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fn_id, ); } - if !pointing_at_return_type { - fn_output = Some(&fn_decl.output); // `impl Trait` return type - } } let parent_id = fcx.tcx.hir().get_parent_item(id); @@ -1795,106 +1787,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { ); } - if let (Some(sp), Some(fn_output)) = (ret_coercion_span, fn_output) { - self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output); - } - err } - fn add_impl_trait_explanation<'a>( - &self, - err: &mut Diagnostic, - cause: &ObligationCause<'tcx>, - fcx: &FnCtxt<'a, 'tcx>, - expected: Ty<'tcx>, - sp: Span, - fn_output: &hir::FnRetTy<'_>, - ) { - let return_sp = fn_output.span(); - err.span_label(return_sp, "expected because this return type..."); - err.span_label( - sp, - format!("...is found to be `{}` here", fcx.resolve_vars_with_obligations(expected)), - ); - let impl_trait_msg = "for information on `impl Trait`, see \ - "; - let trait_obj_msg = "for information on trait objects, see \ - "; - err.note("to return `impl Trait`, all returned values must be of the same type"); - err.note(impl_trait_msg); - let snippet = fcx - .tcx - .sess - .source_map() - .span_to_snippet(return_sp) - .unwrap_or_else(|_| "dyn Trait".to_string()); - let mut snippet_iter = snippet.split_whitespace(); - let has_impl = snippet_iter.next().is_some_and(|s| s == "impl"); - // Only suggest `Box` if `Trait` in `impl Trait` is object safe. - let mut is_object_safe = false; - if let hir::FnRetTy::Return(ty) = fn_output - // Get the return type. - && let hir::TyKind::OpaqueDef(..) = ty.kind - { - let ty = fcx.astconv().ast_ty_to_ty( ty); - // Get the `impl Trait`'s `DefId`. - if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() - // Get the `impl Trait`'s `Item` so that we can get its trait bounds and - // get the `Trait`'s `DefId`. - && let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) = - fcx.tcx.hir().expect_item(def_id.expect_local()).kind - { - // Are of this `impl Trait`'s traits object safe? - is_object_safe = bounds.iter().all(|bound| { - bound - .trait_ref() - .and_then(|t| t.trait_def_id()) - .is_some_and(|def_id| { - fcx.tcx.check_is_object_safe(def_id) - }) - }) - } - }; - if has_impl { - if is_object_safe { - err.multipart_suggestion( - "you could change the return type to be a boxed trait object", - vec![ - (return_sp.with_hi(return_sp.lo() + BytePos(4)), "Box".to_string()), - ], - Applicability::MachineApplicable, - ); - let sugg = [sp, cause.span] - .into_iter() - .flat_map(|sp| { - [ - (sp.shrink_to_lo(), "Box::new(".to_string()), - (sp.shrink_to_hi(), ")".to_string()), - ] - .into_iter() - }) - .collect::>(); - err.multipart_suggestion( - "if you change the return type to expect trait objects, box the returned \ - expressions", - sugg, - Applicability::MaybeIncorrect, - ); - } else { - err.help(format!( - "if the trait `{}` were object safe, you could return a boxed trait object", - &snippet[5..] - )); - } - err.note(trait_obj_msg); - } - err.help("you could instead create a new `enum` with a variant for each returned type"); - } - /// Checks whether the return type is unsized via an obligation, which makes /// sure we consider `dyn Trait: Sized` where clauses, which are trivially /// false but technically valid for typeck. diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 5161a366ae7d3..6b4168d89446f 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -298,6 +298,17 @@ pub enum SuggestBoxing { }, } +#[derive(Subdiagnostic)] +#[suggestion( + hir_typeck_suggest_ptr_null_mut, + applicability = "maybe-incorrect", + code = "core::ptr::null_mut()" +)] +pub struct SuggestPtrNullMut { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(hir_typeck_no_associated_item, code = "E0599")] pub struct NoAssociatedItem { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f03c7ca44ba5f..3f6847be91b65 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2871,6 +2871,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } + + if base_t.is_unsafe_ptr() && idx_t.is_integral() { + err.multipart_suggestion( + "consider using `wrapping_add` or `add` for indexing into raw pointer", + vec![ + (base.span.between(idx.span), ".wrapping_add(".to_owned()), + ( + idx.span.shrink_to_hi().until(expr.span.shrink_to_hi()), + ")".to_owned(), + ), + ], + Applicability::MaybeIncorrect, + ); + } + let reported = err.emit(); self.tcx.ty_error(reported) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 48c3d6f08dee1..bf8ad5faac482 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1,4 +1,5 @@ use crate::coercion::CoerceMany; +use crate::errors::SuggestPtrNullMut; use crate::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx}; use crate::gather_locals::Declaration; use crate::method::MethodCallee; @@ -752,20 +753,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - errors.drain_filter(|error| { + errors.retain(|error| { let Error::Invalid( provided_idx, expected_idx, Compatibility::Incompatible(Some(e)), - ) = error else { return false }; + ) = error else { return true }; let (provided_ty, provided_span) = provided_arg_tys[*provided_idx]; let trace = mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty); if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308) { self.err_ctxt().report_and_explain_type_error(trace, *e).emit(); - return true; + return false; } - false + true }); // We're done if we found errors, but we already emitted them. @@ -814,6 +815,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } + self.suggest_ptr_null_mut( + expected_ty, + provided_ty, + provided_args[*provided_idx], + &mut err, + ); + // Call out where the function is defined self.label_fn_like( &mut err, @@ -1271,6 +1279,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } + fn suggest_ptr_null_mut( + &self, + expected_ty: Ty<'tcx>, + provided_ty: Ty<'tcx>, + arg: &hir::Expr<'tcx>, + err: &mut rustc_errors::DiagnosticBuilder<'tcx, ErrorGuaranteed>, + ) { + if let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Mut, .. }) = expected_ty.kind() + && let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Not, .. }) = provided_ty.kind() + && let hir::ExprKind::Call(callee, _) = arg.kind + && let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = callee.kind + && let Res::Def(_, def_id) = path.res + && self.tcx.get_diagnostic_item(sym::ptr_null) == Some(def_id) + { + // The user provided `ptr::null()`, but the function expects + // `ptr::null_mut()`. + err.subdiagnostic(SuggestPtrNullMut { + span: arg.span + }); + } + } + // AST fragment checking pub(in super::super) fn check_lit( &self, diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 3c5eafd948488..362c07431e0a2 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -82,8 +82,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Try to display a sensible error with as much information as possible. let skeleton_string = |ty: Ty<'tcx>, sk| match sk { - Ok(SizeSkeleton::Known(size)) => format!("{} bits", size.bits()), Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"), + Ok(SizeSkeleton::Known(size)) => { + if let Some(v) = u128::from(size.bytes()).checked_mul(8) { + format!("{} bits", v) + } else { + // `u128` should definitely be able to hold the size of different architectures + // larger sizes should be reported as error `are too big for the current architecture` + // otherwise we have a bug somewhere + bug!("{:?} overflow for u128", size) + } + } Ok(SizeSkeleton::Generic(size)) => { if let Some(size) = size.try_eval_target_usize(tcx, self.param_env) { format!("{size} bytes") diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index b97b55d8f7ee8..7a897778ff7af 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -5,7 +5,6 @@ #![feature(box_patterns)] #![feature(min_specialization)] #![feature(control_flow_enum)] -#![feature(drain_filter)] #![feature(option_as_slice)] #![allow(rustc::potential_query_instability)] #![recursion_limit = "256"] diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index b8bf2b6912039..4f3d1d456798c 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -521,6 +521,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + + // Suggest using `add`, `offset` or `offset_from` for pointer - {integer}, + // pointer + {integer} or pointer - pointer. + if op.span.can_be_used_for_suggestions() { + match op.node { + hir::BinOpKind::Add if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() => { + err.multipart_suggestion( + "consider using `wrapping_add` or `add` for pointer + {integer}", + vec![ + ( + lhs_expr.span.between(rhs_expr.span), + ".wrapping_add(".to_owned(), + ), + (rhs_expr.span.shrink_to_hi(), ")".to_owned()), + ], + Applicability::MaybeIncorrect, + ); + } + hir::BinOpKind::Sub => { + if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() { + err.multipart_suggestion( + "consider using `wrapping_sub` or `sub` for pointer - {integer}", + vec![ + (lhs_expr.span.between(rhs_expr.span), ".wrapping_sub(".to_owned()), + (rhs_expr.span.shrink_to_hi(), ")".to_owned()), + ], + Applicability::MaybeIncorrect + ); + } + + if lhs_ty.is_unsafe_ptr() && rhs_ty.is_unsafe_ptr() { + err.multipart_suggestion( + "consider using `offset_from` for pointer - pointer if the pointers point to the same allocation", + vec![ + (lhs_expr.span.shrink_to_lo(), "unsafe { ".to_owned()), + (lhs_expr.span.between(rhs_expr.span), ".offset_from(".to_owned()), + (rhs_expr.span.shrink_to_hi(), ") }".to_owned()), + ], + Applicability::MaybeIncorrect + ); + } + } + _ => {} + } + } + let reported = err.emit(); self.tcx.ty_error(reported) } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index a395858262f04..29abe921bbdcd 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -136,7 +136,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn write_ty_to_typeck_results(&mut self, hir_id: hir::HirId, ty: Ty<'tcx>) { debug!("write_ty_to_typeck_results({:?}, {:?})", hir_id, ty); - assert!(!ty.has_infer() && !ty.has_placeholders() && !ty.has_free_regions()); + assert!( + !ty.has_infer() && !ty.has_placeholders() && !ty.has_free_regions(), + "{ty} can't be put into typeck results" + ); self.typeck_results.node_types_mut().insert(hir_id, ty); } @@ -803,7 +806,11 @@ impl<'cx, 'tcx> TypeFolder> for Resolver<'cx, 'tcx> { // We must normalize erasing regions here, since later lints // expect that types that show up in the typeck are fully // normalized. - self.fcx.tcx.try_normalize_erasing_regions(self.fcx.param_env, t).unwrap_or(t) + if let Ok(t) = self.fcx.tcx.try_normalize_erasing_regions(self.fcx.param_env, t) { + t + } else { + EraseEarlyRegions { tcx: self.fcx.tcx }.fold_ty(t) + } } Ok(t) => { // Do not anonymize late-bound regions diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 7a80ee98cb3c1..bb2bd2faec208 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -34,7 +34,7 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{RelateResult, TypeRelation}; -use rustc_middle::ty::{self, AliasKind, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{IntType, UintType}; use rustc_span::DUMMY_SP; @@ -103,12 +103,12 @@ impl<'tcx> InferCtxt<'tcx> { // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm. ( - ty::Alias(AliasKind::Projection, _), + ty::Alias(..), ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), ) | ( ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), - ty::Alias(AliasKind::Projection, _), + ty::Alias(..), ) if self.next_trait_solver() => { bug!() } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index ce5b5882e3b26..3e4812e7ca995 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -847,7 +847,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) { err.subdiagnostic(subdiag); } - if let Some(ret_sp) = opt_suggest_box_span { + // don't suggest wrapping either blocks in `if .. {} else {}` + let is_empty_arm = |id| { + let hir::Node::Block(blk) = self.tcx.hir().get(id) + else { + return false; + }; + if blk.expr.is_some() || !blk.stmts.is_empty() { + return false; + } + let Some((_, hir::Node::Expr(expr))) = self.tcx.hir().parent_iter(id).nth(1) + else { + return false; + }; + matches!(expr.kind, hir::ExprKind::If(..)) + }; + if let Some(ret_sp) = opt_suggest_box_span + && !is_empty_arm(then_id) + && !is_empty_arm(else_id) + { self.suggest_boxing_for_return_impl_trait( err, ret_sp, diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index a9ead429f4c71..6b8293f90f10a 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -33,9 +33,6 @@ pub struct OpaqueTypeDecl<'tcx> { /// There can be multiple, but they are all `lub`ed together at the end /// to obtain the canonical hidden type. pub hidden_type: OpaqueHiddenType<'tcx>, - - /// The origin of the opaque type. - pub origin: hir::OpaqueTyOrigin, } impl<'tcx> InferCtxt<'tcx> { @@ -108,7 +105,7 @@ impl<'tcx> InferCtxt<'tcx> { let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) if def_id.is_local() => { let def_id = def_id.expect_local(); - let origin = match self.defining_use_anchor { + match self.defining_use_anchor { DefiningAnchor::Bind(_) => { // Check that this is `impl Trait` type is // declared by `parent_def_id` -- i.e., one whose @@ -144,9 +141,11 @@ impl<'tcx> InferCtxt<'tcx> { // let x = || foo(); // returns the Opaque assoc with `foo` // } // ``` - self.opaque_type_origin(def_id)? + if self.opaque_type_origin(def_id).is_none() { + return None; + } } - DefiningAnchor::Bubble => self.opaque_type_origin_unchecked(def_id), + DefiningAnchor::Bubble => {} DefiningAnchor::Error => return None, }; if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() { @@ -170,7 +169,6 @@ impl<'tcx> InferCtxt<'tcx> { cause.clone(), param_env, b, - origin, a_is_expected, )) } @@ -524,72 +522,78 @@ impl<'tcx> InferCtxt<'tcx> { cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, - origin: hir::OpaqueTyOrigin, a_is_expected: bool, ) -> InferResult<'tcx, ()> { + let mut obligations = Vec::new(); + + self.insert_hidden_type( + opaque_type_key, + &cause, + param_env, + hidden_ty, + a_is_expected, + &mut obligations, + )?; + + self.add_item_bounds_for_hidden_type( + opaque_type_key, + cause, + param_env, + hidden_ty, + &mut obligations, + ); + + Ok(InferOk { value: (), obligations }) + } + + /// Insert a hidden type into the opaque type storage, equating it + /// with any previous entries if necessary. + /// + /// This **does not** add the item bounds of the opaque as nested + /// obligations. That is only necessary when normalizing the opaque + /// itself, not when getting the opaque type constraints from + /// somewhere else. + pub fn insert_hidden_type( + &self, + opaque_type_key: OpaqueTypeKey<'tcx>, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + hidden_ty: Ty<'tcx>, + a_is_expected: bool, + obligations: &mut Vec>, + ) -> Result<(), TypeError<'tcx>> { // Ideally, we'd get the span where *this specific `ty` came // from*, but right now we just use the span from the overall // value being folded. In simple cases like `-> impl Foo`, // these are the same span, but not in cases like `-> (impl // Foo, impl Bar)`. let span = cause.span; - let mut obligations = if self.intercrate { + if self.intercrate { // During intercrate we do not define opaque types but instead always // force ambiguity unless the hidden type is known to not implement // our trait. - vec![traits::Obligation::new( + obligations.push(traits::Obligation::new( self.tcx, cause.clone(), param_env, ty::PredicateKind::Ambiguous, - )] + )) } else { - let prev = self.inner.borrow_mut().opaque_types().register( - opaque_type_key, - OpaqueHiddenType { ty: hidden_ty, span }, - origin, - ); + let prev = self + .inner + .borrow_mut() + .opaque_types() + .register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span }); if let Some(prev) = prev { - self.at(&cause, param_env) - .eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)? - .obligations - } else { - Vec::new() + obligations.extend( + self.at(&cause, param_env) + .eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)? + .obligations, + ); } }; - self.add_item_bounds_for_hidden_type( - opaque_type_key, - cause, - param_env, - hidden_ty, - &mut obligations, - ); - - Ok(InferOk { value: (), obligations }) - } - - /// Registers an opaque's hidden type -- only should be used when the opaque - /// can be defined. For something more fallible -- checks the anchors, tries - /// to unify opaques in both dirs, etc. -- use `InferCtxt::handle_opaque_type`. - pub fn register_hidden_type_in_new_solver( - &self, - opaque_type_key: OpaqueTypeKey<'tcx>, - param_env: ty::ParamEnv<'tcx>, - hidden_ty: Ty<'tcx>, - ) -> InferResult<'tcx, ()> { - assert!(self.next_trait_solver()); - let origin = self - .opaque_type_origin(opaque_type_key.def_id) - .expect("should be called for defining usages only"); - self.register_hidden_type( - opaque_type_key, - ObligationCause::dummy(), - param_env, - hidden_ty, - origin, - true, - ) + Ok(()) } pub fn add_item_bounds_for_hidden_type( diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index a0f6d7ecab70f..a737761ba2282 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -1,5 +1,4 @@ use rustc_data_structures::undo_log::UndoLogs; -use rustc_hir::OpaqueTyOrigin; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty}; use rustc_span::DUMMY_SP; @@ -60,14 +59,13 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> { &mut self, key: OpaqueTypeKey<'tcx>, hidden_type: OpaqueHiddenType<'tcx>, - origin: OpaqueTyOrigin, ) -> Option> { if let Some(decl) = self.storage.opaque_types.get_mut(&key) { let prev = std::mem::replace(&mut decl.hidden_type, hidden_type); self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev))); return Some(prev.ty); } - let decl = OpaqueTypeDecl { hidden_type, origin }; + let decl = OpaqueTypeDecl { hidden_type }; self.storage.opaque_types.insert(key, decl); self.undo_log.push(UndoLog::OpaqueTypes(key, None)); None diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 2edc72ba72ea1..5e3ea71f0e768 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -333,6 +333,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se }; let prof = compiler.sess.prof.clone(); + prof.generic_activity("drop_compiler").run(move || drop(compiler)); r }) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 83a74742f5b76..be2af94961ffa 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -24,6 +24,7 @@ use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_a use rustc_passes::{self, hir_stats, layout_test}; use rustc_plugin_impl as plugin; use rustc_resolve::Resolver; +use rustc_session::code_stats::VTableSizeInfo; use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType}; use rustc_session::cstore::{MetadataLoader, Untracked}; use rustc_session::output::filename_for_input; @@ -866,6 +867,92 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { sess.time("check_lint_expectations", || tcx.check_expectations(None)); }); + if sess.opts.unstable_opts.print_vtable_sizes { + let traits = tcx.traits(LOCAL_CRATE); + + for &tr in traits { + if !tcx.check_is_object_safe(tr) { + continue; + } + + let name = ty::print::with_no_trimmed_paths!(tcx.def_path_str(tr)); + + let mut first_dsa = true; + + // Number of vtable entries, if we didn't have upcasting + let mut entries_ignoring_upcasting = 0; + // Number of vtable entries needed solely for upcasting + let mut entries_for_upcasting = 0; + + let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, tr)); + + // A slightly edited version of the code in `rustc_trait_selection::traits::vtable::vtable_entries`, + // that works without self type and just counts number of entries. + // + // Note that this is technically wrong, for traits which have associated types in supertraits: + // + // trait A: AsRef + AsRef<()> { type T; } + // + // Without self type we can't normalize `Self::T`, so we can't know if `AsRef` and + // `AsRef<()>` are the same trait, thus we assume that those are different, and potentially + // over-estimate how many vtable entries there are. + // + // Similarly this is wrong for traits that have methods with possibly-impossible bounds. + // For example: + // + // trait B { fn f(&self) where T: Copy; } + // + // Here `dyn B` will have 4 entries, while `dyn B` will only have 3. + // However, since we don't know `T`, we can't know if `T: Copy` holds or not, + // thus we lean on the bigger side and say it has 4 entries. + traits::vtable::prepare_vtable_segments(tcx, trait_ref, |segment| { + match segment { + traits::vtable::VtblSegment::MetadataDSA => { + // If this is the first dsa, it would be included either way, + // otherwise it's needed for upcasting + if std::mem::take(&mut first_dsa) { + entries_ignoring_upcasting += 3; + } else { + entries_for_upcasting += 3; + } + } + + traits::vtable::VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { + // Lookup the shape of vtable for the trait. + let own_existential_entries = + tcx.own_existential_vtable_entries(trait_ref.def_id()); + + // The original code here ignores the method if its predicates are impossible. + // We can't really do that as, for example, all not trivial bounds on generic + // parameters are impossible (since we don't know the parameters...), + // see the comment above. + entries_ignoring_upcasting += own_existential_entries.len(); + + if emit_vptr { + entries_for_upcasting += 1; + } + } + } + + std::ops::ControlFlow::Continue::(()) + }); + + sess.code_stats.record_vtable_size( + tr, + &name, + VTableSizeInfo { + trait_name: name.clone(), + entries: entries_ignoring_upcasting + entries_for_upcasting, + entries_ignoring_upcasting, + entries_for_upcasting, + upcasting_cost_percent: entries_for_upcasting as f64 + / entries_ignoring_upcasting as f64 + * 100., + }, + ) + } + } + Ok(()) } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index ff2989112af1a..7b05bff515148 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2124,12 +2124,16 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { } let ty_generics = cx.tcx.generics_of(def_id); + let num_where_predicates = hir_generics + .predicates + .iter() + .filter(|predicate| predicate.in_where_clause()) + .count(); let mut bound_count = 0; let mut lint_spans = Vec::new(); let mut where_lint_spans = Vec::new(); - let mut dropped_predicate_count = 0; - let num_predicates = hir_generics.predicates.len(); + let mut dropped_where_predicate_count = 0; for (i, where_predicate) in hir_generics.predicates.iter().enumerate() { let (relevant_lifetimes, bounds, predicate_span, in_where_clause) = match where_predicate { @@ -2186,8 +2190,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { bound_count += bound_spans.len(); let drop_predicate = bound_spans.len() == bounds.len(); - if drop_predicate { - dropped_predicate_count += 1; + if drop_predicate && in_where_clause { + dropped_where_predicate_count += 1; } if drop_predicate { @@ -2196,7 +2200,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { } else if predicate_span.from_expansion() { // Don't try to extend the span if it comes from a macro expansion. where_lint_spans.push(predicate_span); - } else if i + 1 < num_predicates { + } else if i + 1 < num_where_predicates { // If all the bounds on a predicate were inferable and there are // further predicates, we want to eat the trailing comma. let next_predicate_span = hir_generics.predicates[i + 1].span(); @@ -2224,9 +2228,10 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { } } - // If all predicates are inferable, drop the entire clause + // If all predicates in where clause are inferable, drop the entire clause // (including the `where`) - if hir_generics.has_where_clause_predicates && dropped_predicate_count == num_predicates + if hir_generics.has_where_clause_predicates + && dropped_where_predicate_count == num_where_predicates { let where_span = hir_generics.where_clause_span; // Extend the where clause back to the closing `>` of the diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 8a4a451f8a837..fb12ded71d682 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -16,6 +16,7 @@ use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore}; use rustc_ast as ast; +use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::{join, DynSend}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; @@ -157,10 +158,12 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas } fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) { - self.with_lint_attrs(e.hir_id, |cx| { - lint_callback!(cx, check_expr, e); - hir_visit::walk_expr(cx, e); - lint_callback!(cx, check_expr_post, e); + ensure_sufficient_stack(|| { + self.with_lint_attrs(e.hir_id, |cx| { + lint_callback!(cx, check_expr, e); + hir_visit::walk_expr(cx, e); + lint_callback!(cx, check_expr_post, e); + }) }) } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index eb246c3f93eb0..53ece08ac3d92 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3372,7 +3372,9 @@ declare_lint_pass! { OVERLAPPING_RANGE_ENDPOINTS, PATTERNS_IN_FNS_WITHOUT_BODY, POINTER_STRUCTURAL_MATCH, + PRIVATE_BOUNDS, PRIVATE_IN_PUBLIC, + PRIVATE_INTERFACES, PROC_MACRO_BACK_COMPAT, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, PUB_USE_OF_PRIVATE_EXTERN_CRATE, @@ -3399,6 +3401,7 @@ declare_lint_pass! { UNINHABITED_STATIC, UNKNOWN_CRATE_TYPES, UNKNOWN_LINTS, + UNNAMEABLE_TYPES, UNREACHABLE_CODE, UNREACHABLE_PATTERNS, UNSAFE_OP_IN_UNSAFE_FN, @@ -4251,3 +4254,95 @@ declare_lint! { Warn, "\"invalid_parameter\" isn't a valid argument for `#[macro_export]`", } + +declare_lint! { + /// The `private_interfaces` lint detects types in a primary interface of an item, + /// that are more private than the item itself. Primary interface of an item is all + /// its interface except for bounds on generic parameters and where clauses. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// # #![allow(unused)] + /// # #![allow(private_in_public)] + /// #![deny(private_interfaces)] + /// struct SemiPriv; + /// + /// mod m1 { + /// struct Priv; + /// impl crate::SemiPriv { + /// pub fn f(_: Priv) {} + /// } + /// } + /// + /// # fn main() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Having something private in primary interface guarantees that + /// the item will be unusable from outer modules due to type privacy. + pub PRIVATE_INTERFACES, + Allow, + "private type in primary interface of an item", +} + +declare_lint! { + /// The `private_bounds` lint detects types in a secondary interface of an item, + /// that are more private than the item itself. Secondary interface of an item consists of + /// bounds on generic parameters and where clauses, including supertraits for trait items. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// # #![allow(private_in_public)] + /// # #![allow(unused)] + /// #![deny(private_bounds)] + /// + /// struct PrivTy; + /// pub struct S + /// where PrivTy: + /// {} + /// # fn main() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Having private types or traits in item bounds makes it less clear what interface + /// the item actually provides. + pub PRIVATE_BOUNDS, + Allow, + "private type in secondary interface of an item" +} + +declare_lint! { + /// The `unnameable_types` lint detects types for which you can get objects of that type, + /// but cannot name the type itself. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// # #![allow(unused)] + /// #![deny(unnameable_types)] + /// mod m { + /// pub struct S; + /// } + /// + /// pub fn get_voldemort() -> m::S { m::S } + /// # fn main() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// It is often expected that if you can obtain an object of type `T`, then + /// you can name the type `T` as well, this lint attempts to enforce this rule. + pub UNNAMEABLE_TYPES, + Allow, + "effective visibility of a type is larger than the area in which it can be named" +} diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 9f664d0f0c8e2..87373d9974357 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -1,6 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(decl_macro)] -#![feature(drain_filter)] +#![feature(extract_if)] #![feature(generators)] #![feature(iter_from_generator)] #![feature(let_chains)] diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index c83c47e722bf0..0dd7b11979168 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -425,7 +425,7 @@ impl<'tcx> Collector<'tcx> { // can move them to the end of the list below. let mut existing = self .libs - .drain_filter(|lib| { + .extract_if(|lib| { if lib.name.as_str() == passed_lib.name { // FIXME: This whole logic is questionable, whether modifiers are // involved or not, library reordering and kind overriding without diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 0d6c2eba06c89..1b125e8e26dbc 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -54,7 +54,7 @@ #![feature(try_reserve_kind)] #![feature(nonzero_ops)] #![feature(decl_macro)] -#![feature(drain_filter)] +#![feature(extract_if)] #![feature(intra_doc_pointers)] #![feature(yeet_expr)] #![feature(result_option_inspect)] diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 9c91b7784032d..9c948dba1e438 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -237,7 +237,7 @@ pub fn suggest_constraining_type_params<'a>( { let mut sized_constraints = - constraints.drain_filter(|(_, def_id)| *def_id == tcx.lang_items().sized_trait()); + constraints.extract_if(|(_, def_id)| *def_id == tcx.lang_items().sized_trait()); if let Some((constraint, def_id)) = sized_constraints.next() { applicability = Applicability::MaybeIncorrect; diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl index b13429d121d10..2598eb2ed0968 100644 --- a/compiler/rustc_mir_transform/messages.ftl +++ b/compiler/rustc_mir_transform/messages.ftl @@ -55,6 +55,8 @@ mir_transform_unaligned_packed_ref = reference to packed field is unaligned mir_transform_union_access_label = access to union field mir_transform_union_access_note = the field may not be properly initialized: using uninitialized data will cause undefined behavior mir_transform_unsafe_op_in_unsafe_fn = {$details} is unsafe and requires unsafe block (error E0133) + .suggestion = consider wrapping the function body in an unsafe block + .note = an unsafe function restricts its caller, but its body is safe by default mir_transform_unused_unsafe = unnecessary `unsafe` block .label = because it's nested under this `unsafe` block diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 2f851cd1eb5f7..70812761e88d6 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -525,6 +525,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { } let UnsafetyCheckResult { violations, unused_unsafes, .. } = tcx.unsafety_check_result(def_id); + // Only suggest wrapping the entire function body in an unsafe block once + let mut suggest_unsafe_block = true; for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() { let details = errors::RequiresUnsafeDetail { violation: details, span: source_info.span }; @@ -559,12 +561,29 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { op_in_unsafe_fn_allowed, }); } - UnsafetyViolationKind::UnsafeFn => tcx.emit_spanned_lint( - UNSAFE_OP_IN_UNSAFE_FN, - lint_root, - source_info.span, - errors::UnsafeOpInUnsafeFn { details }, - ), + UnsafetyViolationKind::UnsafeFn => { + tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + lint_root, + source_info.span, + errors::UnsafeOpInUnsafeFn { + details, + suggest_unsafe_block: suggest_unsafe_block.then(|| { + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + let fn_sig = tcx + .hir() + .fn_sig_by_hir_id(hir_id) + .expect("this violation only occurs in fn"); + let body = tcx.hir().body_owned_by(def_id); + let body_span = tcx.hir().body(body).value.span; + let start = tcx.sess.source_map().start_point(body_span).shrink_to_hi(); + let end = tcx.sess.source_map().end_point(body_span).shrink_to_lo(); + (start, end, fn_sig.span) + }), + }, + ); + suggest_unsafe_block = false; + } } } diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 22f71bb08516c..4b796d79ef69a 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -1,5 +1,6 @@ use rustc_errors::{ - DecorateLint, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler, IntoDiagnostic, + Applicability, DecorateLint, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler, + IntoDiagnostic, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails}; @@ -130,6 +131,12 @@ impl RequiresUnsafeDetail { pub(crate) struct UnsafeOpInUnsafeFn { pub details: RequiresUnsafeDetail, + + /// These spans point to: + /// 1. the start of the function body + /// 2. the end of the function body + /// 3. the function signature + pub suggest_unsafe_block: Option<(Span, Span, Span)>, } impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn { @@ -138,13 +145,21 @@ impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn { self, diag: &'b mut DiagnosticBuilder<'a, ()>, ) -> &'b mut DiagnosticBuilder<'a, ()> { - let desc = diag - .handler() - .expect("lint should not yet be emitted") - .eagerly_translate_to_string(self.details.label(), [].into_iter()); + let handler = diag.handler().expect("lint should not yet be emitted"); + let desc = handler.eagerly_translate_to_string(self.details.label(), [].into_iter()); diag.set_arg("details", desc); diag.span_label(self.details.span, self.details.label()); diag.note(self.details.note()); + + if let Some((start, end, fn_sig)) = self.suggest_unsafe_block { + diag.span_note(fn_sig, crate::fluent_generated::mir_transform_note); + diag.tool_only_multipart_suggestion( + crate::fluent_generated::mir_transform_suggestion, + vec![(start, " unsafe {".into()), (end, "}".into())], + Applicability::MaybeIncorrect, + ); + } + diag } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 7d9f6c38e36a4..9c8c0ea0be004 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -2,7 +2,6 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] #![feature(box_patterns)] -#![feature(drain_filter)] #![feature(is_sorted)] #![feature(let_chains)] #![feature(map_try_insert)] diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index e4b3b8b926213..881a1547c5245 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -436,13 +436,12 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { VarDebugInfoContents::Composite { ty: _, ref mut fragments } => { let mut new_fragments = Vec::new(); debug!(?fragments); - fragments - .drain_filter(|fragment| { - if let Some(repl) = + fragments.retain_mut(|fragment| { + if let Some(repl) = self.replacements.replace_place(self.tcx, fragment.contents.as_ref()) { fragment.contents = repl; - false + true } else if let Some(local) = fragment.contents.as_local() && let Some(frg) = self.gather_debug_info_fragments(local) { @@ -450,12 +449,11 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { f.projection.splice(0..0, fragment.projection.iter().copied()); f })); - true - } else { false + } else { + true } - }) - .for_each(drop); + }); debug!(?fragments); debug!(?new_fragments); fragments.extend(new_fragments); diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 1d9c8ded349c0..ebcc3b0399973 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -113,6 +113,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths}; use rustc_middle::ty::{self, visit::TypeVisitableExt, InstanceDef, TyCtxt}; use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath}; +use rustc_session::CodegenUnits; use rustc_span::symbol::Symbol; use crate::collector::UsageMap; @@ -121,7 +122,6 @@ use crate::errors::{CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollec struct PartitioningCx<'a, 'tcx> { tcx: TyCtxt<'tcx>, - target_cgu_count: usize, usage_map: &'a UsageMap<'tcx>, } @@ -130,13 +130,17 @@ struct PlacedRootMonoItems<'tcx> { codegen_units: Vec>, internalization_candidates: FxHashSet>, + + /// These must be obtained when the iterator in `partition` runs. They + /// can't be obtained later because some inlined functions might not be + /// reachable. + unique_inlined_stats: (usize, usize), } // The output CGUs are sorted by name. fn partition<'tcx, I>( tcx: TyCtxt<'tcx>, mono_items: I, - max_cgu_count: usize, usage_map: &UsageMap<'tcx>, ) -> Vec> where @@ -144,12 +148,12 @@ where { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning"); - let cx = &PartitioningCx { tcx, target_cgu_count: max_cgu_count, usage_map }; + let cx = &PartitioningCx { tcx, usage_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. - let PlacedRootMonoItems { mut codegen_units, internalization_candidates } = { + let PlacedRootMonoItems { mut codegen_units, internalization_candidates, unique_inlined_stats } = { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots"); place_root_mono_items(cx, mono_items) }; @@ -158,7 +162,7 @@ where cgu.create_size_estimate(tcx); } - debug_dump(tcx, "INITIAL PARTITIONING", &codegen_units); + debug_dump(tcx, "ROOTS", &codegen_units, unique_inlined_stats); // Merge until we have at most `max_cgu_count` codegen units. // `merge_codegen_units` is responsible for updating the CGU size @@ -166,7 +170,7 @@ where { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus"); merge_codegen_units(cx, &mut codegen_units); - debug_dump(tcx, "POST MERGING", &codegen_units); + debug_dump(tcx, "MERGE", &codegen_units, unique_inlined_stats); } // In the next step, we use the inlining map to determine which additional @@ -182,7 +186,7 @@ where cgu.create_size_estimate(tcx); } - debug_dump(tcx, "POST INLINING", &codegen_units); + debug_dump(tcx, "INLINE", &codegen_units, unique_inlined_stats); // Next we try to make as many symbols "internal" as possible, so LLVM has // more freedom to optimize. @@ -226,7 +230,7 @@ where // 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); + debug_dump(tcx, "FINAL", &codegen_units, unique_inlined_stats); codegen_units } @@ -252,10 +256,16 @@ where let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx); let cgu_name_cache = &mut FxHashMap::default(); + let mut num_unique_inlined_items = 0; + let mut unique_inlined_items_size = 0; for mono_item in mono_items { match mono_item.instantiation_mode(cx.tcx) { InstantiationMode::GloballyShared { .. } => {} - InstantiationMode::LocalCopy => continue, + InstantiationMode::LocalCopy => { + num_unique_inlined_items += 1; + unique_inlined_items_size += mono_item.size_estimate(cx.tcx); + continue; + } } let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item); @@ -300,7 +310,11 @@ where 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, internalization_candidates } + PlacedRootMonoItems { + codegen_units, + internalization_candidates, + unique_inlined_stats: (num_unique_inlined_items, unique_inlined_items_size), + } } // This function requires the CGUs to be sorted by name on input, and ensures @@ -309,7 +323,7 @@ fn merge_codegen_units<'tcx>( cx: &PartitioningCx<'_, 'tcx>, codegen_units: &mut Vec>, ) { - assert!(cx.target_cgu_count >= 1); + assert!(cx.tcx.sess.codegen_units().as_usize() >= 1); // 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())))); @@ -318,11 +332,32 @@ fn merge_codegen_units<'tcx>( let mut cgu_contents: FxHashMap> = codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect(); - // Merge the two smallest codegen units until the target size is - // reached. - while codegen_units.len() > cx.target_cgu_count { - // Sort small cgus to the back + // Having multiple CGUs can drastically speed up compilation. But for + // non-incremental builds, tiny CGUs slow down compilation *and* result in + // worse generated code. So we don't allow CGUs smaller than this (unless + // there is just one CGU, of course). Note that CGU sizes of 100,000+ are + // common in larger programs, so this isn't all that large. + const NON_INCR_MIN_CGU_SIZE: usize = 1000; + + // Repeatedly merge the two smallest codegen units as long as: + // - we have more CGUs than the upper limit, or + // - (Non-incremental builds only) the user didn't specify a CGU count, and + // there are multiple CGUs, and some are below the minimum size. + // + // The "didn't specify a CGU count" condition is because when an explicit + // count is requested we observe it as closely as possible. For example, + // the `compiler_builtins` crate sets `codegen-units = 10000` and it's + // critical they aren't merged. Also, some tests use explicit small values + // and likewise won't work if small CGUs are merged. + while codegen_units.len() > cx.tcx.sess.codegen_units().as_usize() + || (cx.tcx.sess.opts.incremental.is_none() + && matches!(cx.tcx.sess.codegen_units(), CodegenUnits::Default(_)) + && codegen_units.len() > 1 + && codegen_units.iter().any(|cgu| cgu.size_estimate() < NON_INCR_MIN_CGU_SIZE)) + { + // Sort small cgus to the back. codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate())); + let mut smallest = codegen_units.pop().unwrap(); let second_smallest = codegen_units.last_mut().unwrap(); @@ -814,47 +849,147 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit } } -fn debug_dump<'a, 'tcx: 'a>(tcx: TyCtxt<'tcx>, label: &str, cgus: &[CodegenUnit<'tcx>]) { +fn debug_dump<'a, 'tcx: 'a>( + tcx: TyCtxt<'tcx>, + label: &str, + cgus: &[CodegenUnit<'tcx>], + (unique_inlined_items, unique_inlined_size): (usize, usize), +) { let dump = move || { use std::fmt::Write; - let num_cgus = cgus.len(); - 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 mut num_cgus = 0; + let mut all_cgu_sizes = Vec::new(); + + // Note: every unique root item is placed exactly once, so the number + // of unique root items always equals the number of placed root items. + + let mut root_items = 0; + // unique_inlined_items is passed in above. + let mut placed_inlined_items = 0; + + let mut root_size = 0; + // unique_inlined_size is passed in above. + let mut placed_inlined_size = 0; + + for cgu in cgus.iter() { + num_cgus += 1; + all_cgu_sizes.push(cgu.size_estimate()); + + for (item, _) in cgu.items() { + match item.instantiation_mode(tcx) { + InstantiationMode::GloballyShared { .. } => { + root_items += 1; + root_size += item.size_estimate(tcx); + } + InstantiationMode::LocalCopy => { + placed_inlined_items += 1; + placed_inlined_size += item.size_estimate(tcx); + } + } + } + } + + all_cgu_sizes.sort_unstable_by_key(|&n| cmp::Reverse(n)); + + let unique_items = root_items + unique_inlined_items; + let placed_items = root_items + placed_inlined_items; + let items_ratio = placed_items as f64 / unique_items as f64; + + let unique_size = root_size + unique_inlined_size; + let placed_size = root_size + placed_inlined_size; + let size_ratio = placed_size as f64 / unique_size as f64; + + let mean_cgu_size = placed_size as f64 / num_cgus as f64; + + assert_eq!(placed_size, all_cgu_sizes.iter().sum::()); let s = &mut String::new(); + let _ = writeln!(s, "{label}"); let _ = writeln!( s, - "{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}):" + "- unique items: {unique_items} ({root_items} root + {unique_inlined_items} inlined), \ + unique size: {unique_size} ({root_size} root + {unique_inlined_size} inlined)\n\ + - placed items: {placed_items} ({root_items} root + {placed_inlined_items} inlined), \ + placed size: {placed_size} ({root_size} root + {placed_inlined_size} inlined)\n\ + - placed/unique items ratio: {items_ratio:.2}, \ + placed/unique size ratio: {size_ratio:.2}\n\ + - CGUs: {num_cgus}, mean size: {mean_cgu_size:.1}, sizes: {}", + list(&all_cgu_sizes), ); + let _ = writeln!(s); + for (i, cgu) in cgus.iter().enumerate() { + let name = cgu.name(); + let size = cgu.size_estimate(); let num_items = cgu.items().len(); - let _ = writeln!( - s, - "- CGU[{i}] {} ({num_items} items, size={}):", - cgu.name(), - cgu.size_estimate() - ); + let mean_size = size as f64 / num_items as f64; + + let mut placed_item_sizes: Vec<_> = + cgu.items().iter().map(|(item, _)| item.size_estimate(tcx)).collect(); + placed_item_sizes.sort_unstable_by_key(|&n| cmp::Reverse(n)); + let sizes = list(&placed_item_sizes); + + let _ = writeln!(s, "- CGU[{i}]"); + let _ = writeln!(s, " - {name}, size: {size}"); + let _ = + writeln!(s, " - items: {num_items}, mean size: {mean_size:.1}, sizes: {sizes}",); for (item, linkage) in cgu.items_in_deterministic_order(tcx) { 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 kind = match item.instantiation_mode(tcx) { + InstantiationMode::GloballyShared { .. } => "root", + InstantiationMode::LocalCopy => "inlined", + }; let _ = with_no_trimmed_paths!(writeln!( s, - " - {item} [{linkage:?}] [{symbol_hash}] (size={size})" + " - {item} [{linkage:?}] [{symbol_hash}] ({kind}, size: {size})" )); } let _ = writeln!(s); } - std::mem::take(s) + return std::mem::take(s); + + // Converts a slice to a string, capturing repetitions to save space. + // E.g. `[4, 4, 4, 3, 2, 1, 1, 1, 1, 1]` -> "[4 (x3), 3, 2, 1 (x5)]". + fn list(ns: &[usize]) -> String { + let mut v = Vec::new(); + if ns.is_empty() { + return "[]".to_string(); + } + + let mut elem = |curr, curr_count| { + if curr_count == 1 { + v.push(format!("{curr}")); + } else { + v.push(format!("{curr} (x{curr_count})")); + } + }; + + let mut curr = ns[0]; + let mut curr_count = 1; + + for &n in &ns[1..] { + if n != curr { + elem(curr, curr_count); + curr = n; + curr_count = 1; + } else { + curr_count += 1; + } + } + elem(curr, curr_count); + + let mut s = "[".to_string(); + s.push_str(&v.join(", ")); + s.push_str("]"); + s + } }; debug!("{}", dump()); @@ -922,8 +1057,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || { sync::join( || { - let mut codegen_units = - partition(tcx, items.iter().copied(), tcx.sess.codegen_units(), &usage_map); + let mut codegen_units = partition(tcx, items.iter().copied(), &usage_map); codegen_units[0].make_primary(); &*tcx.arena.alloc_from_iter(codegen_units) }, diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 9263394508ee3..35eec2c8e1b17 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -695,7 +695,7 @@ parse_struct_literal_body_without_path = parse_struct_literal_needing_parens = invalid struct literal - .suggestion = you might need to surround the struct literal in parentheses + .suggestion = you might need to surround the struct literal with parentheses parse_struct_literal_not_allowed_here = struct literals are not allowed here .suggestion = surround the struct literal with parentheses diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index eb9625f923ab9..461a34b67db6f 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -158,7 +158,7 @@ pub(crate) fn emit_unescape_error( diag.help( "for more information, visit \ - ", + ", ); } diag.emit(); diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index c145403968574..228eff1269f11 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -751,13 +751,24 @@ impl<'a> Parser<'a> { tail.could_be_bare_literal = true; if maybe_struct_name.is_ident() && can_be_struct_literal { // Account for `if Example { a: one(), }.is_pos() {}`. - Err(self.sess.create_err(StructLiteralNeedingParens { - span: maybe_struct_name.span.to(expr.span), - sugg: StructLiteralNeedingParensSugg { - before: maybe_struct_name.span.shrink_to_lo(), - after: expr.span.shrink_to_hi(), - }, - })) + // expand `before` so that we take care of module path such as: + // `foo::Bar { ... } ` + // we expect to suggest `(foo::Bar { ... })` instead of `foo::(Bar { ... })` + let sm = self.sess.source_map(); + let before = maybe_struct_name.span.shrink_to_lo(); + if let Ok(extend_before) = sm.span_extend_prev_while(before, |t| { + t.is_alphanumeric() || t == ':' || t == '_' + }) { + Err(self.sess.create_err(StructLiteralNeedingParens { + span: maybe_struct_name.span.to(expr.span), + sugg: StructLiteralNeedingParensSugg { + before: extend_before.shrink_to_lo(), + after: expr.span.shrink_to_hi(), + }, + })) + } else { + return None; + } } else { self.sess.emit_err(StructLiteralBodyWithoutPath { span: expr.span, diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl index b68e8a78aab86..6f51981cf09dd 100644 --- a/compiler/rustc_privacy/messages.ftl +++ b/compiler/rustc_privacy/messages.ftl @@ -17,7 +17,14 @@ privacy_private_in_public_lint = *[other] E0446 }) +privacy_private_interface_or_bounds_lint = {$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}` + .item_note = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}` + .ty_note = but {$ty_kind} `{$ty_descr}` is only usable at visibility `{$ty_vis_descr}` + privacy_report_effective_visibility = {$descr} +privacy_unnameable_types_lint = {$kind} `{$descr}` is reachable but cannot be named + .label = reachable at visibility `{$reachable_vis}`, but can only be named at visibility `{$reexported_vis}` + privacy_unnamed_item_is_private = {$kind} is private .label = private {$kind} diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index 72b53eefa0817..67689b5e71304 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -98,3 +98,32 @@ pub struct PrivateInPublicLint<'a> { pub kind: &'a str, pub descr: DiagnosticArgFromDisplay<'a>, } + +#[derive(LintDiagnostic)] +#[diag(privacy_unnameable_types_lint)] +pub struct UnnameableTypesLint<'a> { + #[label] + pub span: Span, + pub kind: &'a str, + pub descr: DiagnosticArgFromDisplay<'a>, + pub reachable_vis: &'a str, + pub reexported_vis: &'a str, +} + +// Used for `private_interfaces` and `private_bounds` lints. +// They will replace private-in-public errors and compatibility lints in future. +// See https://rust-lang.github.io/rfcs/2145-type-privacy.html for more details. +#[derive(LintDiagnostic)] +#[diag(privacy_private_interface_or_bounds_lint)] +pub struct PrivateInterfacesOrBoundsLint<'a> { + #[note(privacy_item_note)] + pub item_span: Span, + pub item_kind: &'a str, + pub item_descr: DiagnosticArgFromDisplay<'a>, + pub item_vis_descr: &'a str, + #[note(privacy_ty_note)] + pub ty_span: Span, + pub ty_kind: &'a str, + pub ty_descr: DiagnosticArgFromDisplay<'a>, + pub ty_vis_descr: &'a str, +} diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index afd32e38d5b87..a51a1c9a8a436 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -22,7 +22,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind}; +use rustc_hir::{AssocItemKind, ForeignItemKind, HirIdSet, ItemId, Node, PatKind}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level}; @@ -42,8 +42,8 @@ use std::{fmt, mem}; use errors::{ FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface, - InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportEffectiveVisibility, - UnnamedItemIsPrivate, + InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, PrivateInterfacesOrBoundsLint, + ReportEffectiveVisibility, UnnameableTypesLint, UnnamedItemIsPrivate, }; fluent_messages! { "../messages.ftl" } @@ -52,6 +52,17 @@ fluent_messages! { "../messages.ftl" } /// Generic infrastructure used to implement specific visitors below. //////////////////////////////////////////////////////////////////////////////// +struct LazyDefPathStr<'tcx> { + def_id: DefId, + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.tcx.def_path_str(self.def_id)) + } +} + /// Implemented to visit all `DefId`s in a type. /// Visiting `DefId`s is useful because visibilities and reachabilities are attached to them. /// The idea is to visit "all components of a type", as documented in @@ -259,16 +270,6 @@ where &LazyDefPathStr { def_id: data.def_id, tcx }, )?; - struct LazyDefPathStr<'tcx> { - def_id: DefId, - tcx: TyCtxt<'tcx>, - } - impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.tcx.def_path_str(self.def_id)) - } - } - // This will also visit substs if necessary, so we don't need to recurse. return if self.def_id_visitor.shallow() { ControlFlow::Continue(()) @@ -409,8 +410,25 @@ impl VisibilityLike for ty::Visibility { } } -impl VisibilityLike for EffectiveVisibility { - const MAX: Self = EffectiveVisibility::from_vis(ty::Visibility::Public); +struct NonShallowEffectiveVis(EffectiveVisibility); + +impl VisibilityLike for NonShallowEffectiveVis { + const MAX: Self = NonShallowEffectiveVis(EffectiveVisibility::from_vis(ty::Visibility::Public)); + const SHALLOW: bool = false; + + fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self { + let find = FindMin { + tcx: find.tcx, + effective_visibilities: find.effective_visibilities, + min: ShallowEffectiveVis(find.min.0), + }; + NonShallowEffectiveVis(VisibilityLike::new_min(&find, def_id).0) + } +} + +struct ShallowEffectiveVis(EffectiveVisibility); +impl VisibilityLike for ShallowEffectiveVis { + const MAX: Self = ShallowEffectiveVis(EffectiveVisibility::from_vis(ty::Visibility::Public)); // Type inference is very smart sometimes. // It can make an impl reachable even some components of its type or trait are unreachable. // E.g. methods of `impl ReachableTrait for ReachableTy { ... }` @@ -429,7 +447,7 @@ impl VisibilityLike for EffectiveVisibility { EffectiveVisibility::from_vis(private_vis) }); - effective_vis.min(find.min, find.tcx) + ShallowEffectiveVis(effective_vis.min(find.min.0, find.tcx)) } } @@ -767,11 +785,13 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } } hir::ItemKind::Impl(ref impl_) => { - let item_ev = EffectiveVisibility::of_impl( + let item_ev = ShallowEffectiveVis::of_impl( item.owner_id.def_id, self.tcx, &self.effective_visibilities, - ); + ) + .0; + self.update_eff_vis(item.owner_id.def_id, item_ev, None, Level::Direct); self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty().trait_ref(); @@ -912,6 +932,21 @@ pub struct TestReachabilityVisitor<'tcx, 'a> { effective_visibilities: &'a EffectiveVisibilities, } +fn vis_to_string<'tcx>(def_id: LocalDefId, vis: ty::Visibility, tcx: TyCtxt<'tcx>) -> String { + match vis { + ty::Visibility::Restricted(restricted_id) => { + if restricted_id.is_top_level_module() { + "pub(crate)".to_string() + } else if restricted_id == tcx.parent_module_from_def_id(def_id) { + "pub(self)".to_string() + } else { + format!("pub({})", tcx.item_name(restricted_id.to_def_id())) + } + } + ty::Visibility::Public => "pub".to_string(), + } +} + impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> { fn effective_visibility_diagnostic(&mut self, def_id: LocalDefId) { if self.tcx.has_attr(def_id, sym::rustc_effective_visibility) { @@ -919,18 +954,7 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> { let span = self.tcx.def_span(def_id.to_def_id()); if let Some(effective_vis) = self.effective_visibilities.effective_vis(def_id) { for level in Level::all_levels() { - let vis_str = match effective_vis.at_level(level) { - ty::Visibility::Restricted(restricted_id) => { - if restricted_id.is_top_level_module() { - "pub(crate)".to_string() - } else if *restricted_id == self.tcx.parent_module_from_def_id(def_id) { - "pub(self)".to_string() - } else { - format!("pub({})", self.tcx.item_name(restricted_id.to_def_id())) - } - } - ty::Visibility::Public => "pub".to_string(), - }; + let vis_str = vis_to_string(def_id, *effective_vis.at_level(level), self.tcx); if level != Level::Direct { error_msg.push_str(", "); } @@ -1745,12 +1769,15 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> { item_def_id: LocalDefId, /// The visitor checks that each component type is at least this visible. required_visibility: ty::Visibility, + required_effective_vis: Option, has_old_errors: bool, in_assoc_ty: bool, + in_primary_interface: bool, } impl SearchInterfaceForPrivateItemsVisitor<'_> { fn generics(&mut self) -> &mut Self { + self.in_primary_interface = true; for param in &self.tcx.generics_of(self.item_def_id).params { match param.kind { GenericParamDefKind::Lifetime => {} @@ -1769,6 +1796,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } fn predicates(&mut self) -> &mut Self { + self.in_primary_interface = false; // N.B., we use `explicit_predicates_of` and not `predicates_of` // because we don't want to report privacy errors due to where // clauses that the compiler inferred. We only want to @@ -1780,6 +1808,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } fn bounds(&mut self) -> &mut Self { + self.in_primary_interface = false; self.visit_predicates(ty::GenericPredicates { parent: None, predicates: self.tcx.explicit_item_bounds(self.item_def_id).skip_binder(), @@ -1788,6 +1817,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } fn ty(&mut self) -> &mut Self { + self.in_primary_interface = true; self.visit(self.tcx.type_of(self.item_def_id).subst_identity()); self } @@ -1811,8 +1841,10 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { }; let vis = self.tcx.local_visibility(local_def_id); + let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); + let span = self.tcx.def_span(self.item_def_id.to_def_id()); + let vis_span = self.tcx.def_span(def_id); if !vis.is_at_least(self.required_visibility, self.tcx) { - let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); let vis_descr = match vis { ty::Visibility::Public => "public", ty::Visibility::Restricted(vis_def_id) => { @@ -1825,12 +1857,11 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } } }; - let span = self.tcx.def_span(self.item_def_id.to_def_id()); + if self.has_old_errors || self.in_assoc_ty || self.tcx.resolutions(()).has_pub_restricted { - let vis_span = self.tcx.def_span(def_id); if kind == "trait" { self.tcx.sess.emit_err(InPublicInterfaceTraits { span, @@ -1858,6 +1889,39 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } } + let Some(effective_vis) = self.required_effective_vis else { + return false; + }; + + // FIXME: `Level::Reachable` should be taken instead of `Level::Reexported` + let reexported_at_vis = *effective_vis.at_level(Level::Reexported); + + if !vis.is_at_least(reexported_at_vis, self.tcx) { + let lint = if self.in_primary_interface { + lint::builtin::PRIVATE_INTERFACES + } else { + lint::builtin::PRIVATE_BOUNDS + }; + self.tcx.emit_lint( + lint, + hir_id, + PrivateInterfacesOrBoundsLint { + item_span: span, + item_kind: self.tcx.def_descr(self.item_def_id.to_def_id()), + item_descr: (&LazyDefPathStr { + def_id: self.item_def_id.to_def_id(), + tcx: self.tcx, + }) + .into(), + item_vis_descr: &vis_to_string(self.item_def_id, reexported_at_vis, self.tcx), + ty_span: vis_span, + ty_kind: kind, + ty_descr: descr.into(), + ty_vis_descr: &vis_to_string(local_def_id, vis, self.tcx), + }, + ); + } + false } @@ -1891,25 +1955,55 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> { } } -struct PrivateItemsInPublicInterfacesChecker<'tcx> { +struct PrivateItemsInPublicInterfacesChecker<'tcx, 'a> { tcx: TyCtxt<'tcx>, old_error_set_ancestry: HirIdSet, + effective_visibilities: &'a EffectiveVisibilities, } -impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { +impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> { fn check( &self, def_id: LocalDefId, required_visibility: ty::Visibility, + required_effective_vis: Option, ) -> SearchInterfaceForPrivateItemsVisitor<'tcx> { SearchInterfaceForPrivateItemsVisitor { tcx: self.tcx, item_def_id: def_id, required_visibility, + required_effective_vis, has_old_errors: self .old_error_set_ancestry .contains(&self.tcx.hir().local_def_id_to_hir_id(def_id)), in_assoc_ty: false, + in_primary_interface: true, + } + } + + fn check_unnameable(&self, def_id: LocalDefId, effective_vis: Option) { + let Some(effective_vis) = effective_vis else { + return; + }; + + let reexported_at_vis = effective_vis.at_level(Level::Reexported); + let reachable_at_vis = effective_vis.at_level(Level::Reachable); + + if reexported_at_vis != reachable_at_vis { + let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); + let span = self.tcx.def_span(def_id.to_def_id()); + self.tcx.emit_spanned_lint( + lint::builtin::UNNAMEABLE_TYPES, + hir_id, + span, + UnnameableTypesLint { + span, + kind: self.tcx.def_descr(def_id.to_def_id()), + descr: (&LazyDefPathStr { def_id: def_id.to_def_id(), tcx: self.tcx }).into(), + reachable_vis: &vis_to_string(def_id, *reachable_at_vis, self.tcx), + reexported_vis: &vis_to_string(def_id, *reexported_at_vis, self.tcx), + }, + ); } } @@ -1918,13 +2012,19 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { def_id: LocalDefId, assoc_item_kind: AssocItemKind, vis: ty::Visibility, + effective_vis: Option, ) { - let mut check = self.check(def_id, vis); + let mut check = self.check(def_id, vis, effective_vis); let (check_ty, is_assoc_ty) = match assoc_item_kind { AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false), AssocItemKind::Type => (self.tcx.defaultness(def_id).has_value(), true), }; + + if is_assoc_ty { + self.check_unnameable(def_id, self.get(def_id)); + } + check.in_assoc_ty = is_assoc_ty; check.generics().predicates(); if check_ty { @@ -1932,50 +2032,72 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { } } + fn get(&self, def_id: LocalDefId) -> Option { + self.effective_visibilities.effective_vis(def_id).copied() + } + pub fn check_item(&mut self, id: ItemId) { let tcx = self.tcx; let def_id = id.owner_id.def_id; let item_visibility = tcx.local_visibility(def_id); + let effective_vis = self.get(def_id); let def_kind = tcx.def_kind(def_id); match def_kind { DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => { - self.check(def_id, item_visibility).generics().predicates().ty(); + if let DefKind::TyAlias = def_kind { + self.check_unnameable(def_id, effective_vis); + } + self.check(def_id, item_visibility, effective_vis).generics().predicates().ty(); } DefKind::OpaqueTy => { // `ty()` for opaque types is the underlying type, // it's not a part of interface, so we skip it. - self.check(def_id, item_visibility).generics().bounds(); + self.check(def_id, item_visibility, effective_vis).generics().bounds(); } DefKind::Trait => { let item = tcx.hir().item(id); if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind { - self.check(item.owner_id.def_id, item_visibility).generics().predicates(); + self.check_unnameable(item.owner_id.def_id, effective_vis); + + self.check(item.owner_id.def_id, item_visibility, effective_vis) + .generics() + .predicates(); for trait_item_ref in trait_item_refs { self.check_assoc_item( trait_item_ref.id.owner_id.def_id, trait_item_ref.kind, item_visibility, + effective_vis, ); if let AssocItemKind::Type = trait_item_ref.kind { - self.check(trait_item_ref.id.owner_id.def_id, item_visibility).bounds(); + self.check( + trait_item_ref.id.owner_id.def_id, + item_visibility, + effective_vis, + ) + .bounds(); } } } } DefKind::TraitAlias => { - self.check(def_id, item_visibility).generics().predicates(); + self.check(def_id, item_visibility, effective_vis).generics().predicates(); } DefKind::Enum => { let item = tcx.hir().item(id); if let hir::ItemKind::Enum(ref def, _) = item.kind { - self.check(item.owner_id.def_id, item_visibility).generics().predicates(); + self.check_unnameable(item.owner_id.def_id, effective_vis); + + self.check(item.owner_id.def_id, item_visibility, effective_vis) + .generics() + .predicates(); for variant in def.variants { for field in variant.data.fields() { - self.check(field.def_id, item_visibility).ty(); + self.check(field.def_id, item_visibility, effective_vis).ty(); } } } @@ -1985,8 +2107,16 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { let item = tcx.hir().item(id); if let hir::ItemKind::ForeignMod { items, .. } = item.kind { for foreign_item in items { - let vis = tcx.local_visibility(foreign_item.id.owner_id.def_id); - self.check(foreign_item.id.owner_id.def_id, vis) + let foreign_item = tcx.hir().foreign_item(foreign_item.id); + + let ev = self.get(foreign_item.owner_id.def_id); + let vis = tcx.local_visibility(foreign_item.owner_id.def_id); + + if let ForeignItemKind::Type = foreign_item.kind { + self.check_unnameable(foreign_item.owner_id.def_id, ev); + } + + self.check(foreign_item.owner_id.def_id, vis, ev) .generics() .predicates() .ty(); @@ -1999,11 +2129,21 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { if let hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) = item.kind { - self.check(item.owner_id.def_id, item_visibility).generics().predicates(); + self.check_unnameable(item.owner_id.def_id, effective_vis); + self.check(item.owner_id.def_id, item_visibility, effective_vis) + .generics() + .predicates(); for field in struct_def.fields() { let field_visibility = tcx.local_visibility(field.def_id); - self.check(field.def_id, min(item_visibility, field_visibility, tcx)).ty(); + let field_ev = self.get(field.def_id); + + self.check( + field.def_id, + min(item_visibility, field_visibility, tcx), + field_ev, + ) + .ty(); } } } @@ -2016,10 +2156,30 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { if let hir::ItemKind::Impl(ref impl_) = item.kind { let impl_vis = ty::Visibility::of_impl(item.owner_id.def_id, tcx, &Default::default()); + + // we are using the non-shallow version here, unlike when building the + // effective visisibilities table to avoid large number of false positives. + // For example: + // + // impl From for Pub { + // fn from(_: Priv) -> Pub {...} + // } + // + // lints shouldn't be emmited even `from` effective visibility + // is larger then `Priv` nominal visibility. + let impl_ev = Some( + NonShallowEffectiveVis::of_impl( + item.owner_id.def_id, + tcx, + self.effective_visibilities, + ) + .0, + ); + // check that private components do not appear in the generics or predicates of inherent impls // this check is intentionally NOT performed for impls of traits, per #90586 if impl_.of_trait.is_none() { - self.check(item.owner_id.def_id, impl_vis).generics().predicates(); + self.check(item.owner_id.def_id, impl_vis, impl_ev).generics().predicates(); } for impl_item_ref in impl_.items { let impl_item_vis = if impl_.of_trait.is_none() { @@ -2031,10 +2191,18 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { } else { impl_vis }; + + let impl_item_ev = if impl_.of_trait.is_none() { + self.get(impl_item_ref.id.owner_id.def_id) + } else { + impl_ev + }; + self.check_assoc_item( impl_item_ref.id.owner_id.def_id, impl_item_ref.kind, impl_item_vis, + impl_item_ev, ); } } @@ -2186,7 +2354,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) { } // Check for private types and traits in public interfaces. - let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, old_error_set_ancestry }; + let mut checker = PrivateItemsInPublicInterfacesChecker { + tcx, + old_error_set_ancestry, + effective_visibilities, + }; for id in tcx.hir().items() { checker.check_item(id); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index ca811c9ed7d98..e42b2df1a5ab8 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2494,7 +2494,7 @@ fn show_candidates( for path_strings in [&mut accessible_path_strings, &mut inaccessible_path_strings] { path_strings.sort_by(|a, b| a.0.cmp(&b.0)); let core_path_strings = - path_strings.drain_filter(|p| p.0.starts_with("core::")).collect::>(); + path_strings.extract_if(|p| p.0.starts_with("core::")).collect::>(); path_strings.extend(core_path_strings); path_strings.dedup_by(|a, b| a.0 == b.0); } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 7f944fb574596..47d8e5993fd82 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -338,7 +338,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } else { resolution.binding = Some(nonglob_binding); } - resolution.shadowed_glob = Some(glob_binding); + + if let Some(old_binding) = resolution.shadowed_glob { + assert!(old_binding.is_glob_import()); + if glob_binding.res() != old_binding.res() { + resolution.shadowed_glob = Some(this.ambiguity( + AmbiguityKind::GlobVsGlob, + old_binding, + glob_binding, + )); + } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { + resolution.shadowed_glob = Some(glob_binding); + } + } else { + resolution.shadowed_glob = Some(glob_binding); + } } (false, false) => { return Err(old_binding); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 2f9759a668bbe..e4b01ef2b1710 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -496,7 +496,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { // Try to filter out intrinsics candidates, as long as we have // some other candidates to suggest. let intrinsic_candidates: Vec<_> = candidates - .drain_filter(|sugg| { + .extract_if(|sugg| { let path = path_names_to_string(&sugg.path); path.starts_with("core::intrinsics::") || path.starts_with("std::intrinsics::") }) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index db97039b907c4..82b333fee28b8 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -9,7 +9,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(assert_matches)] #![feature(box_patterns)] -#![feature(drain_filter)] +#![feature(extract_if)] #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(let_chains)] diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs index 0dfee92f40434..cabe1c96bf795 100644 --- a/compiler/rustc_session/src/code_stats.rs +++ b/compiler/rustc_session/src/code_stats.rs @@ -1,5 +1,6 @@ -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lock; +use rustc_span::def_id::DefId; use rustc_span::Symbol; use rustc_target::abi::{Align, Size}; use std::cmp; @@ -65,9 +66,29 @@ pub struct TypeSizeInfo { pub variants: Vec, } +pub struct VTableSizeInfo { + pub trait_name: String, + + /// Number of entries in a vtable with the current algorithm + /// (i.e. with upcasting). + pub entries: usize, + + /// Number of entries in a vtable, as-if we did not have trait upcasting. + pub entries_ignoring_upcasting: usize, + + /// Number of entries in a vtable needed solely for upcasting + /// (i.e. `entries - entries_ignoring_upcasting`). + pub entries_for_upcasting: usize, + + /// Cost of having upcasting in % relative to the number of entries without + /// upcasting (i.e. `entries_for_upcasting / entries_ignoring_upcasting * 100%`). + pub upcasting_cost_percent: f64, +} + #[derive(Default)] pub struct CodeStats { type_sizes: Lock>, + vtable_sizes: Lock>, } impl CodeStats { @@ -101,6 +122,14 @@ impl CodeStats { self.type_sizes.borrow_mut().insert(info); } + pub fn record_vtable_size(&self, trait_did: DefId, trait_name: &str, info: VTableSizeInfo) { + let prev = self.vtable_sizes.lock().insert(trait_did, info); + assert!( + prev.is_none(), + "size of vtable for `{trait_name}` ({trait_did:?}) is already recorded" + ); + } + pub fn print_type_sizes(&self) { let type_sizes = self.type_sizes.borrow(); let mut sorted: Vec<_> = type_sizes.iter().collect(); @@ -196,4 +225,33 @@ impl CodeStats { } } } + + pub fn print_vtable_sizes(&self, crate_name: &str) { + let mut infos = std::mem::take(&mut *self.vtable_sizes.lock()) + .into_iter() + .map(|(_did, stats)| stats) + .collect::>(); + + // Primary sort: cost % in reverse order (from largest to smallest) + // Secondary sort: trait_name + infos.sort_by(|a, b| { + a.upcasting_cost_percent + .total_cmp(&b.upcasting_cost_percent) + .reverse() + .then_with(|| a.trait_name.cmp(&b.trait_name)) + }); + + for VTableSizeInfo { + trait_name, + entries, + entries_ignoring_upcasting, + entries_for_upcasting, + upcasting_cost_percent, + } in infos + { + println!( + r#"print-vtable-sizes {{ "crate_name": "{crate_name}", "trait_name": "{trait_name}", "entries": "{entries}", "entries_ignoring_upcasting": "{entries_ignoring_upcasting}", "entries_for_upcasting": "{entries_for_upcasting}", "upcasting_cost_percent": "{upcasting_cost_percent}" }}"# + ); + } + } } diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 590a68c660061..d57aa820fcb47 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -27,7 +27,7 @@ pub use lint::{declare_lint, declare_lint_pass, declare_tool_lint, impl_lint_pas pub use rustc_lint_defs as lint; pub mod parse; -mod code_stats; +pub mod code_stats; #[macro_use] pub mod config; pub mod cstore; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 201066e395017..b626c721481db 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1632,6 +1632,8 @@ options! { "print the result of the monomorphization collection pass"), print_type_sizes: bool = (false, parse_bool, [UNTRACKED], "print layout information for each type encountered (default: no)"), + print_vtable_sizes: bool = (false, parse_bool, [UNTRACKED], + "print size comparison between old and new vtable layouts (default: no)"), proc_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], "show backtraces for panics during proc-macro execution (default: no)"), proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 2cc02003218ee..5feea83edb6a3 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -234,6 +234,27 @@ pub enum MetadataKind { Compressed, } +#[derive(Clone, Copy)] +pub enum CodegenUnits { + /// Specified by the user. In this case we try fairly hard to produce the + /// number of CGUs requested. + User(usize), + + /// A default value, i.e. not specified by the user. In this case we take + /// more liberties about CGU formation, e.g. avoid producing very small + /// CGUs. + Default(usize), +} + +impl CodegenUnits { + pub fn as_usize(self) -> usize { + match self { + CodegenUnits::User(n) => n, + CodegenUnits::Default(n) => n, + } + } +} + impl Session { pub fn miri_unleashed_feature(&self, span: Span, feature_gate: Option) { self.miri_unleashed_features.lock().push((span, feature_gate)); @@ -1104,7 +1125,7 @@ impl Session { // If there's only one codegen unit and LTO isn't enabled then there's // no need for ThinLTO so just return false. - if self.codegen_units() == 1 { + if self.codegen_units().as_usize() == 1 { return config::Lto::No; } @@ -1206,19 +1227,19 @@ impl Session { /// Returns the number of codegen units that should be used for this /// compilation - pub fn codegen_units(&self) -> usize { + pub fn codegen_units(&self) -> CodegenUnits { if let Some(n) = self.opts.cli_forced_codegen_units { - return n; + return CodegenUnits::User(n); } if let Some(n) = self.target.default_codegen_units { - return n as usize; + return CodegenUnits::Default(n as usize); } // If incremental compilation is turned on, we default to a high number // codegen units in order to reduce the "collateral damage" small // changes cause. if self.opts.incremental.is_some() { - return 256; + return CodegenUnits::Default(256); } // Why is 16 codegen units the default all the time? @@ -1271,7 +1292,7 @@ impl Session { // As a result 16 was chosen here! Mostly because it was a power of 2 // and most benchmarks agreed it was roughly a local optimum. Not very // scientific. - 16 + CodegenUnits::Default(16) } pub fn teach(&self, code: &DiagnosticId) -> bool { diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 6d8d99cfb5f1f..6bd030b13d1ce 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -8,6 +8,7 @@ //! For now, we are developing everything inside `rustc`, thus, we keep this module private. use crate::stable_mir::{self, ty::TyKind, Context}; +use rustc_middle::mir; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use tracing::debug; @@ -42,8 +43,8 @@ impl<'tcx> Context for Tables<'tcx> { .basic_blocks .iter() .map(|block| stable_mir::mir::BasicBlock { - terminator: rustc_terminator_to_terminator(block.terminator()), - statements: block.statements.iter().map(rustc_statement_to_statement).collect(), + terminator: block.terminator().stable(), + statements: block.statements.iter().map(mir::Statement::stable).collect(), }) .collect(), locals: mir.local_decls.iter().map(|decl| self.intern_ty(decl.ty)).collect(), @@ -118,82 +119,95 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate { stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local } } -fn rustc_statement_to_statement( - s: &rustc_middle::mir::Statement<'_>, -) -> stable_mir::mir::Statement { - use rustc_middle::mir::StatementKind::*; - match &s.kind { - Assign(assign) => stable_mir::mir::Statement::Assign( - rustc_place_to_place(&assign.0), - rustc_rvalue_to_rvalue(&assign.1), - ), - FakeRead(_) => todo!(), - SetDiscriminant { .. } => todo!(), - Deinit(_) => todo!(), - StorageLive(_) => todo!(), - StorageDead(_) => todo!(), - Retag(_, _) => todo!(), - PlaceMention(_) => todo!(), - AscribeUserType(_, _) => todo!(), - Coverage(_) => todo!(), - Intrinsic(_) => todo!(), - ConstEvalCounter => todo!(), - Nop => stable_mir::mir::Statement::Nop, +pub trait Stable { + type T; + fn stable(&self) -> Self::T; +} + +impl<'tcx> Stable for mir::Statement<'tcx> { + type T = stable_mir::mir::Statement; + fn stable(&self) -> Self::T { + use rustc_middle::mir::StatementKind::*; + match &self.kind { + Assign(assign) => { + stable_mir::mir::Statement::Assign(assign.0.stable(), assign.1.stable()) + } + FakeRead(_) => todo!(), + SetDiscriminant { .. } => todo!(), + Deinit(_) => todo!(), + StorageLive(_) => todo!(), + StorageDead(_) => todo!(), + Retag(_, _) => todo!(), + PlaceMention(_) => todo!(), + AscribeUserType(_, _) => todo!(), + Coverage(_) => todo!(), + Intrinsic(_) => todo!(), + ConstEvalCounter => todo!(), + Nop => stable_mir::mir::Statement::Nop, + } } } -fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir::mir::Rvalue { - use rustc_middle::mir::Rvalue::*; - match rvalue { - Use(op) => stable_mir::mir::Rvalue::Use(rustc_op_to_op(op)), - Repeat(_, _) => todo!(), - Ref(_, _, _) => todo!(), - ThreadLocalRef(_) => todo!(), - AddressOf(_, _) => todo!(), - Len(_) => todo!(), - Cast(_, _, _) => todo!(), - BinaryOp(_, _) => todo!(), - CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp( - rustc_bin_op_to_bin_op(bin_op), - rustc_op_to_op(&ops.0), - rustc_op_to_op(&ops.1), - ), - NullaryOp(_, _) => todo!(), - UnaryOp(un_op, op) => { - stable_mir::mir::Rvalue::UnaryOp(rustc_un_op_to_un_op(un_op), rustc_op_to_op(op)) +impl<'tcx> Stable for mir::Rvalue<'tcx> { + type T = stable_mir::mir::Rvalue; + fn stable(&self) -> Self::T { + use mir::Rvalue::*; + match self { + Use(op) => stable_mir::mir::Rvalue::Use(op.stable()), + Repeat(_, _) => todo!(), + Ref(_, _, _) => todo!(), + ThreadLocalRef(_) => todo!(), + AddressOf(_, _) => todo!(), + Len(_) => todo!(), + Cast(_, _, _) => todo!(), + BinaryOp(_, _) => todo!(), + CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp( + bin_op.stable(), + ops.0.stable(), + ops.1.stable(), + ), + NullaryOp(_, _) => todo!(), + UnaryOp(un_op, op) => stable_mir::mir::Rvalue::UnaryOp(un_op.stable(), op.stable()), + Discriminant(_) => todo!(), + Aggregate(_, _) => todo!(), + ShallowInitBox(_, _) => todo!(), + CopyForDeref(_) => todo!(), } - Discriminant(_) => todo!(), - Aggregate(_, _) => todo!(), - ShallowInitBox(_, _) => todo!(), - CopyForDeref(_) => todo!(), } } -fn rustc_op_to_op(op: &rustc_middle::mir::Operand<'_>) -> stable_mir::mir::Operand { - use rustc_middle::mir::Operand::*; - match op { - Copy(place) => stable_mir::mir::Operand::Copy(rustc_place_to_place(place)), - Move(place) => stable_mir::mir::Operand::Move(rustc_place_to_place(place)), - Constant(c) => stable_mir::mir::Operand::Constant(c.to_string()), +impl<'tcx> Stable for mir::Operand<'tcx> { + type T = stable_mir::mir::Operand; + fn stable(&self) -> Self::T { + use mir::Operand::*; + match self { + Copy(place) => stable_mir::mir::Operand::Copy(place.stable()), + Move(place) => stable_mir::mir::Operand::Move(place.stable()), + Constant(c) => stable_mir::mir::Operand::Constant(c.to_string()), + } } } -fn rustc_place_to_place(place: &rustc_middle::mir::Place<'_>) -> stable_mir::mir::Place { - stable_mir::mir::Place { - local: place.local.as_usize(), - projection: format!("{:?}", place.projection), +impl<'tcx> Stable for mir::Place<'tcx> { + type T = stable_mir::mir::Place; + fn stable(&self) -> Self::T { + stable_mir::mir::Place { + local: self.local.as_usize(), + projection: format!("{:?}", self.projection), + } } } -fn rustc_unwind_to_unwind( - unwind: &rustc_middle::mir::UnwindAction, -) -> stable_mir::mir::UnwindAction { - use rustc_middle::mir::UnwindAction; - match unwind { - UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue, - UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable, - UnwindAction::Terminate => stable_mir::mir::UnwindAction::Terminate, - UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()), +impl Stable for mir::UnwindAction { + type T = stable_mir::mir::UnwindAction; + fn stable(&self) -> Self::T { + use rustc_middle::mir::UnwindAction; + match self { + UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue, + UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable, + UnwindAction::Terminate => stable_mir::mir::UnwindAction::Terminate, + UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()), + } } } @@ -202,168 +216,163 @@ fn rustc_assert_msg_to_msg<'tcx>( ) -> stable_mir::mir::AssertMessage { use rustc_middle::mir::AssertKind; match assert_message { - AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck { - len: rustc_op_to_op(len), - index: rustc_op_to_op(index), - }, - AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow( - rustc_bin_op_to_bin_op(bin_op), - rustc_op_to_op(op1), - rustc_op_to_op(op2), - ), - AssertKind::OverflowNeg(op) => { - stable_mir::mir::AssertMessage::OverflowNeg(rustc_op_to_op(op)) + AssertKind::BoundsCheck { len, index } => { + stable_mir::mir::AssertMessage::BoundsCheck { len: len.stable(), index: index.stable() } + } + AssertKind::Overflow(bin_op, op1, op2) => { + stable_mir::mir::AssertMessage::Overflow(bin_op.stable(), op1.stable(), op2.stable()) } + AssertKind::OverflowNeg(op) => stable_mir::mir::AssertMessage::OverflowNeg(op.stable()), AssertKind::DivisionByZero(op) => { - stable_mir::mir::AssertMessage::DivisionByZero(rustc_op_to_op(op)) + stable_mir::mir::AssertMessage::DivisionByZero(op.stable()) } AssertKind::RemainderByZero(op) => { - stable_mir::mir::AssertMessage::RemainderByZero(rustc_op_to_op(op)) + stable_mir::mir::AssertMessage::RemainderByZero(op.stable()) } AssertKind::ResumedAfterReturn(generator) => { - stable_mir::mir::AssertMessage::ResumedAfterReturn(rustc_generator_to_generator( - generator, - )) + stable_mir::mir::AssertMessage::ResumedAfterReturn(generator.stable()) } AssertKind::ResumedAfterPanic(generator) => { - stable_mir::mir::AssertMessage::ResumedAfterPanic(rustc_generator_to_generator( - generator, - )) + stable_mir::mir::AssertMessage::ResumedAfterPanic(generator.stable()) } AssertKind::MisalignedPointerDereference { required, found } => { stable_mir::mir::AssertMessage::MisalignedPointerDereference { - required: rustc_op_to_op(required), - found: rustc_op_to_op(found), + required: required.stable(), + found: found.stable(), } } } } -fn rustc_bin_op_to_bin_op(bin_op: &rustc_middle::mir::BinOp) -> stable_mir::mir::BinOp { - use rustc_middle::mir::BinOp; - match bin_op { - BinOp::Add => stable_mir::mir::BinOp::Add, - BinOp::Sub => stable_mir::mir::BinOp::Sub, - BinOp::Mul => stable_mir::mir::BinOp::Mul, - BinOp::Div => stable_mir::mir::BinOp::Div, - BinOp::Rem => stable_mir::mir::BinOp::Rem, - BinOp::BitXor => stable_mir::mir::BinOp::BitXor, - BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd, - BinOp::BitOr => stable_mir::mir::BinOp::BitOr, - BinOp::Shl => stable_mir::mir::BinOp::Shl, - BinOp::Shr => stable_mir::mir::BinOp::Shr, - BinOp::Eq => stable_mir::mir::BinOp::Eq, - BinOp::Lt => stable_mir::mir::BinOp::Lt, - BinOp::Le => stable_mir::mir::BinOp::Le, - BinOp::Ne => stable_mir::mir::BinOp::Ne, - BinOp::Ge => stable_mir::mir::BinOp::Ge, - BinOp::Gt => stable_mir::mir::BinOp::Gt, - BinOp::Offset => stable_mir::mir::BinOp::Offset, +impl Stable for mir::BinOp { + type T = stable_mir::mir::BinOp; + fn stable(&self) -> Self::T { + use mir::BinOp; + match self { + BinOp::Add => stable_mir::mir::BinOp::Add, + BinOp::Sub => stable_mir::mir::BinOp::Sub, + BinOp::Mul => stable_mir::mir::BinOp::Mul, + BinOp::Div => stable_mir::mir::BinOp::Div, + BinOp::Rem => stable_mir::mir::BinOp::Rem, + BinOp::BitXor => stable_mir::mir::BinOp::BitXor, + BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd, + BinOp::BitOr => stable_mir::mir::BinOp::BitOr, + BinOp::Shl => stable_mir::mir::BinOp::Shl, + BinOp::Shr => stable_mir::mir::BinOp::Shr, + BinOp::Eq => stable_mir::mir::BinOp::Eq, + BinOp::Lt => stable_mir::mir::BinOp::Lt, + BinOp::Le => stable_mir::mir::BinOp::Le, + BinOp::Ne => stable_mir::mir::BinOp::Ne, + BinOp::Ge => stable_mir::mir::BinOp::Ge, + BinOp::Gt => stable_mir::mir::BinOp::Gt, + BinOp::Offset => stable_mir::mir::BinOp::Offset, + } } } -fn rustc_un_op_to_un_op(unary_op: &rustc_middle::mir::UnOp) -> stable_mir::mir::UnOp { - use rustc_middle::mir::UnOp; - match unary_op { - UnOp::Not => stable_mir::mir::UnOp::Not, - UnOp::Neg => stable_mir::mir::UnOp::Neg, +impl Stable for mir::UnOp { + type T = stable_mir::mir::UnOp; + fn stable(&self) -> Self::T { + use mir::UnOp; + match self { + UnOp::Not => stable_mir::mir::UnOp::Not, + UnOp::Neg => stable_mir::mir::UnOp::Neg, + } } } -fn rustc_generator_to_generator( - generator: &rustc_hir::GeneratorKind, -) -> stable_mir::mir::GeneratorKind { - use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; - match generator { - GeneratorKind::Async(async_gen) => { - let async_gen = match async_gen { - AsyncGeneratorKind::Block => stable_mir::mir::AsyncGeneratorKind::Block, - AsyncGeneratorKind::Closure => stable_mir::mir::AsyncGeneratorKind::Closure, - AsyncGeneratorKind::Fn => stable_mir::mir::AsyncGeneratorKind::Fn, - }; - stable_mir::mir::GeneratorKind::Async(async_gen) +impl Stable for rustc_hir::GeneratorKind { + type T = stable_mir::mir::GeneratorKind; + fn stable(&self) -> Self::T { + use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; + match self { + GeneratorKind::Async(async_gen) => { + let async_gen = match async_gen { + AsyncGeneratorKind::Block => stable_mir::mir::AsyncGeneratorKind::Block, + AsyncGeneratorKind::Closure => stable_mir::mir::AsyncGeneratorKind::Closure, + AsyncGeneratorKind::Fn => stable_mir::mir::AsyncGeneratorKind::Fn, + }; + stable_mir::mir::GeneratorKind::Async(async_gen) + } + GeneratorKind::Gen => stable_mir::mir::GeneratorKind::Gen, } - GeneratorKind::Gen => stable_mir::mir::GeneratorKind::Gen, } } -fn rustc_inline_asm_operand_to_inline_asm_operand( - operand: &rustc_middle::mir::InlineAsmOperand<'_>, -) -> stable_mir::mir::InlineAsmOperand { - use rustc_middle::mir::InlineAsmOperand; +impl<'tcx> Stable for mir::InlineAsmOperand<'tcx> { + type T = stable_mir::mir::InlineAsmOperand; + fn stable(&self) -> Self::T { + use rustc_middle::mir::InlineAsmOperand; - let (in_value, out_place) = match operand { - InlineAsmOperand::In { value, .. } => (Some(rustc_op_to_op(value)), None), - InlineAsmOperand::Out { place, .. } => { - (None, place.map(|place| rustc_place_to_place(&place))) - } - InlineAsmOperand::InOut { in_value, out_place, .. } => { - (Some(rustc_op_to_op(in_value)), out_place.map(|place| rustc_place_to_place(&place))) - } - InlineAsmOperand::Const { .. } - | InlineAsmOperand::SymFn { .. } - | InlineAsmOperand::SymStatic { .. } => (None, None), - }; + let (in_value, out_place) = match self { + InlineAsmOperand::In { value, .. } => (Some(value.stable()), None), + InlineAsmOperand::Out { place, .. } => (None, place.map(|place| place.stable())), + InlineAsmOperand::InOut { in_value, out_place, .. } => { + (Some(in_value.stable()), out_place.map(|place| place.stable())) + } + InlineAsmOperand::Const { .. } + | InlineAsmOperand::SymFn { .. } + | InlineAsmOperand::SymStatic { .. } => (None, None), + }; - stable_mir::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{:?}", operand) } + stable_mir::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{:?}", self) } + } } -fn rustc_terminator_to_terminator( - terminator: &rustc_middle::mir::Terminator<'_>, -) -> stable_mir::mir::Terminator { - use rustc_middle::mir::TerminatorKind::*; - use stable_mir::mir::Terminator; - match &terminator.kind { - Goto { target } => Terminator::Goto { target: target.as_usize() }, - SwitchInt { discr, targets } => Terminator::SwitchInt { - discr: rustc_op_to_op(discr), - targets: targets - .iter() - .map(|(value, target)| stable_mir::mir::SwitchTarget { - value, - target: target.as_usize(), - }) - .collect(), - otherwise: targets.otherwise().as_usize(), - }, - Resume => Terminator::Resume, - Terminate => Terminator::Abort, - Return => Terminator::Return, - Unreachable => Terminator::Unreachable, - Drop { place, target, unwind, replace: _ } => Terminator::Drop { - place: rustc_place_to_place(place), - target: target.as_usize(), - unwind: rustc_unwind_to_unwind(unwind), - }, - Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => { - Terminator::Call { - func: rustc_op_to_op(func), - args: args.iter().map(|arg| rustc_op_to_op(arg)).collect(), - destination: rustc_place_to_place(destination), - target: target.map(|t| t.as_usize()), - unwind: rustc_unwind_to_unwind(unwind), - } - } - Assert { cond, expected, msg, target, unwind } => Terminator::Assert { - cond: rustc_op_to_op(cond), - expected: *expected, - msg: rustc_assert_msg_to_msg(msg), - target: target.as_usize(), - unwind: rustc_unwind_to_unwind(unwind), - }, - InlineAsm { template, operands, options, line_spans, destination, unwind } => { - Terminator::InlineAsm { - template: format!("{:?}", template), - operands: operands +impl<'tcx> Stable for mir::Terminator<'tcx> { + type T = stable_mir::mir::Terminator; + fn stable(&self) -> Self::T { + use rustc_middle::mir::TerminatorKind::*; + use stable_mir::mir::Terminator; + match &self.kind { + Goto { target } => Terminator::Goto { target: target.as_usize() }, + SwitchInt { discr, targets } => Terminator::SwitchInt { + discr: discr.stable(), + targets: targets .iter() - .map(|operand| rustc_inline_asm_operand_to_inline_asm_operand(operand)) + .map(|(value, target)| stable_mir::mir::SwitchTarget { + value, + target: target.as_usize(), + }) .collect(), - options: format!("{:?}", options), - line_spans: format!("{:?}", line_spans), - destination: destination.map(|d| d.as_usize()), - unwind: rustc_unwind_to_unwind(unwind), + otherwise: targets.otherwise().as_usize(), + }, + Resume => Terminator::Resume, + Terminate => Terminator::Abort, + Return => Terminator::Return, + Unreachable => Terminator::Unreachable, + Drop { place, target, unwind, replace: _ } => Terminator::Drop { + place: place.stable(), + target: target.as_usize(), + unwind: unwind.stable(), + }, + Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => { + Terminator::Call { + func: func.stable(), + args: args.iter().map(|arg| arg.stable()).collect(), + destination: destination.stable(), + target: target.map(|t| t.as_usize()), + unwind: unwind.stable(), + } + } + Assert { cond, expected, msg, target, unwind } => Terminator::Assert { + cond: cond.stable(), + expected: *expected, + msg: rustc_assert_msg_to_msg(msg), + target: target.as_usize(), + unwind: unwind.stable(), + }, + InlineAsm { template, operands, options, line_spans, destination, unwind } => { + Terminator::InlineAsm { + template: format!("{:?}", template), + operands: operands.iter().map(|operand| operand.stable()).collect(), + options: format!("{:?}", options), + line_spans: format!("{:?}", line_spans), + destination: destination.map(|d| d.as_usize()), + unwind: unwind.stable(), + } } + Yield { .. } | GeneratorDrop | FalseEdge { .. } | FalseUnwind { .. } => unreachable!(), } - Yield { .. } | GeneratorDrop | FalseEdge { .. } | FalseUnwind { .. } => unreachable!(), } } diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 1824510a9742e..c53fe084c4db0 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -744,6 +744,21 @@ impl SourceMap { }) } + /// Extends the given `Span` to previous character while the previous character matches the predicate + pub fn span_extend_prev_while( + &self, + span: Span, + f: impl Fn(char) -> bool, + ) -> Result { + self.span_to_source(span, |s, start, _end| { + let n = s[..start] + .char_indices() + .rfind(|&(_, c)| !f(c)) + .map_or(start, |(i, _)| start - i - 1); + Ok(span.with_lo(span.lo() - BytePos(n as u32))) + }) + } + /// Extends the given `Span` to just before the next occurrence of `c`. pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span { if let Ok(next_source) = self.span_to_next_source(sp) { diff --git a/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs index 618250591ad88..209d481d6f824 100644 --- a/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs @@ -1,4 +1,4 @@ -use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy}; +use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel}; use super::{Target, TargetOptions}; pub fn target() -> Target { @@ -13,8 +13,7 @@ pub fn target() -> Target { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No), llvm_abiname: "lp64d".into(), max_atomic_width: Some(64), - position_independent_executables: true, - static_position_independent_executables: true, + relocation_model: RelocModel::Static, panic_strategy: PanicStrategy::Abort, code_model: Some(CodeModel::Small), ..Default::default() diff --git a/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs index 23123d7630c8b..f444a7f24bb72 100644 --- a/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs @@ -1,9 +1,9 @@ -use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy}; +use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel}; use super::{Target, TargetOptions}; pub fn target() -> Target { Target { - llvm_target: "loongarch64-unknown-none-softfloat".into(), + llvm_target: "loongarch64-unknown-none".into(), pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), arch: "loongarch64".into(), @@ -14,8 +14,7 @@ pub fn target() -> Target { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No), llvm_abiname: "lp64s".into(), max_atomic_width: Some(64), - position_independent_executables: true, - static_position_independent_executables: true, + relocation_model: RelocModel::Static, panic_strategy: PanicStrategy::Abort, code_model: Some(CodeModel::Small), ..Default::default() diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index ed3994be98796..56d37d58de752 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -14,8 +14,7 @@ #![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(control_flow_enum)] -#![feature(drain_filter)] -#![feature(hash_drain_filter)] +#![feature(extract_if)] #![feature(let_chains)] #![feature(if_let_guard)] #![feature(never_type)] diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index f32ff0442a4c5..1b749b9c854cd 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -320,7 +320,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { candidates } - /// If the self type of a goal is a projection, computing the relevant candidates is difficult. + /// If the self type of a goal is an alias, computing the relevant candidates is difficult. /// /// To deal with this, we first try to normalize the self type and add the candidates for the normalized /// self type to the list of candidates in case that succeeds. We also have to consider candidates with the diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 3001d9f1b1f3f..a8a0e1ebfb42c 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -15,8 +15,8 @@ use rustc_middle::traits::solve::{ }; use rustc_middle::traits::DefiningAnchor; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, - TypeVisitor, + self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, }; use rustc_span::DUMMY_SP; use std::ops::ControlFlow; @@ -191,16 +191,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { .with_opaque_type_inference(canonical_input.value.anchor) .build_with_canonical(DUMMY_SP, &canonical_input); - for &(a, b) in &input.predefined_opaques_in_body.opaque_types { - let InferOk { value: (), obligations } = infcx - .register_hidden_type_in_new_solver(a, input.goal.param_env, b) - .expect("expected opaque type instantiation to succeed"); - // We're only registering opaques already defined by the caller, - // so we're not responsible for proving that they satisfy their - // item bounds, unless we use them in a normalizes-to goal, - // which is handled in `EvalCtxt::unify_existing_opaque_tys`. - let _ = obligations; - } let mut ecx = EvalCtxt { infcx, var_values, @@ -211,6 +201,15 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { tainted: Ok(()), }; + for &(key, ty) in &input.predefined_opaques_in_body.opaque_types { + ecx.insert_hidden_type(key, input.goal.param_env, ty) + .expect("failed to prepopulate opaque types"); + } + + if !ecx.nested_goals.is_empty() { + panic!("prepopulating opaque types shouldn't add goals: {:?}", ecx.nested_goals); + } + let result = ecx.compute_goal(input.goal); // When creating a query response we clone the opaque type constraints @@ -710,6 +709,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { scope: Ty<'tcx>, assume: rustc_transmute::Assume, ) -> Result { + use rustc_transmute::Answer; // FIXME(transmutability): This really should be returning nested goals for `Answer::If*` match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable( ObligationCause::dummy(), @@ -717,11 +717,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { scope, assume, ) { - rustc_transmute::Answer::Yes => Ok(Certainty::Yes), - rustc_transmute::Answer::No(_) - | rustc_transmute::Answer::IfTransmutable { .. } - | rustc_transmute::Answer::IfAll(_) - | rustc_transmute::Answer::IfAny(_) => Err(NoSolution), + Answer::Yes => Ok(Certainty::Yes), + Answer::No(_) | Answer::If(_) => Err(NoSolution), } } @@ -729,18 +726,42 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.infcx.opaque_type_origin(def_id).is_some() } - pub(super) fn register_opaque_ty( + pub(super) fn insert_hidden_type( &mut self, - a: ty::OpaqueTypeKey<'tcx>, - b: Ty<'tcx>, + opaque_type_key: OpaqueTypeKey<'tcx>, param_env: ty::ParamEnv<'tcx>, + hidden_ty: Ty<'tcx>, ) -> Result<(), NoSolution> { - let InferOk { value: (), obligations } = - self.infcx.register_hidden_type_in_new_solver(a, param_env, b)?; - self.add_goals(obligations.into_iter().map(|obligation| obligation.into())); + let mut obligations = Vec::new(); + self.infcx.insert_hidden_type( + opaque_type_key, + &ObligationCause::dummy(), + param_env, + hidden_ty, + true, + &mut obligations, + )?; + self.add_goals(obligations.into_iter().map(|o| o.into())); Ok(()) } + pub(super) fn add_item_bounds_for_hidden_type( + &mut self, + opaque_type_key: OpaqueTypeKey<'tcx>, + param_env: ty::ParamEnv<'tcx>, + hidden_ty: Ty<'tcx>, + ) { + let mut obligations = Vec::new(); + self.infcx.add_item_bounds_for_hidden_type( + opaque_type_key, + ObligationCause::dummy(), + param_env, + hidden_ty, + &mut obligations, + ); + self.add_goals(obligations.into_iter().map(|o| o.into())); + } + // Do something for each opaque/hidden pair defined with `def_id` in the // current inference context. pub(super) fn unify_existing_opaque_tys( @@ -762,15 +783,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ecx.eq(param_env, a, b)?; } ecx.eq(param_env, candidate_ty, ty)?; - let mut obl = vec![]; - ecx.infcx.add_item_bounds_for_hidden_type( - candidate_key, - ObligationCause::dummy(), - param_env, - candidate_ty, - &mut obl, - ); - ecx.add_goals(obl.into_iter().map(Into::into)); + ecx.add_item_bounds_for_hidden_type(candidate_key, param_env, candidate_ty); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) })); } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index 72b3c3d01804a..851edf1fa1cb6 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -16,7 +16,6 @@ use rustc_index::IndexVec; use rustc_infer::infer::canonical::query_response::make_query_region_constraints; use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; -use rustc_infer::infer::InferOk; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{ ExternalConstraints, ExternalConstraintsData, MaybeCause, PredefinedOpaquesData, QueryInput, @@ -321,12 +320,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { param_env: ty::ParamEnv<'tcx>, opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)], ) -> Result<(), NoSolution> { - for &(a, b) in opaque_types { - let InferOk { value: (), obligations } = - self.infcx.register_hidden_type_in_new_solver(a, param_env, b)?; - // It's sound to drop these obligations, since the normalizes-to goal - // is responsible for proving these obligations. - let _ = obligations; + for &(key, ty) in opaque_types { + self.insert_hidden_type(key, param_env, ty)?; } Ok(()) } diff --git a/compiler/rustc_trait_selection/src/solve/opaques.rs b/compiler/rustc_trait_selection/src/solve/opaques.rs index a5de4ddee82ba..538c16c8ce2cd 100644 --- a/compiler/rustc_trait_selection/src/solve/opaques.rs +++ b/compiler/rustc_trait_selection/src/solve/opaques.rs @@ -50,7 +50,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } // Otherwise, define a new opaque type - self.register_opaque_ty(opaque_ty, expected, goal.param_env)?; + self.insert_hidden_type(opaque_ty, goal.param_env, expected)?; + self.add_item_bounds_for_hidden_type(opaque_ty, goal.param_env, expected); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } (Reveal::UserFacing, SolverMode::Coherence) => { diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 2c793ea33dc88..190a78f6a8ecd 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -23,7 +23,7 @@ use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::traits::DefiningAnchor; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; -use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitor}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use std::fmt::Debug; @@ -170,8 +170,8 @@ fn overlap<'tcx>( overlap_mode: OverlapMode, ) -> Option> { if overlap_mode.use_negative_impl() { - if negative_impl(tcx, impl1_def_id, impl2_def_id) - || negative_impl(tcx, impl2_def_id, impl1_def_id) + if impl_intersection_has_negative_obligation(tcx, impl1_def_id, impl2_def_id) + || impl_intersection_has_negative_obligation(tcx, impl2_def_id, impl1_def_id) { return None; } @@ -198,13 +198,21 @@ fn overlap<'tcx>( let impl1_header = with_fresh_ty_vars(selcx, param_env, impl1_def_id); let impl2_header = with_fresh_ty_vars(selcx, param_env, impl2_def_id); - let obligations = equate_impl_headers(selcx.infcx, &impl1_header, &impl2_header)?; + // Equate the headers to find their intersection (the general type, with infer vars, + // that may apply both impls). + let equate_obligations = equate_impl_headers(selcx.infcx, &impl1_header, &impl2_header)?; debug!("overlap: unification check succeeded"); - if overlap_mode.use_implicit_negative() { - if implicit_negative(selcx, param_env, &impl1_header, impl2_header, obligations) { - return None; - } + if overlap_mode.use_implicit_negative() + && impl_intersection_has_impossible_obligation( + selcx, + param_env, + &impl1_header, + impl2_header, + equate_obligations, + ) + { + return None; } // We toggle the `leak_check` by using `skip_leak_check` when constructing the @@ -250,52 +258,38 @@ fn equate_impl_headers<'tcx>( result.map(|infer_ok| infer_ok.obligations).ok() } -/// Given impl1 and impl2 check if both impls can be satisfied by a common type (including -/// where-clauses) If so, return false, otherwise return true, they are disjoint. -fn implicit_negative<'cx, 'tcx>( +/// Check if both impls can be satisfied by a common type by considering whether +/// any of either impl's obligations is not known to hold. +/// +/// For example, given these two impls: +/// `impl From for Box` (in my crate) +/// `impl From for Box where E: Error` (in libstd) +/// +/// After replacing both impl headers with inference vars (which happens before +/// this function is called), we get: +/// `Box: From` +/// `Box: From` +/// +/// This gives us `?E = MyLocalType`. We then certainly know that `MyLocalType: Error` +/// never holds in intercrate mode since a local impl does not exist, and a +/// downstream impl cannot be added -- therefore can consider the intersection +/// of the two impls above to be empty. +/// +/// Importantly, this works even if there isn't a `impl !Error for MyLocalType`. +fn impl_intersection_has_impossible_obligation<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, param_env: ty::ParamEnv<'tcx>, impl1_header: &ty::ImplHeader<'tcx>, impl2_header: ty::ImplHeader<'tcx>, obligations: PredicateObligations<'tcx>, ) -> bool { - // There's no overlap if obligations are unsatisfiable or if the obligation negated is - // satisfied. - // - // For example, given these two impl headers: - // - // `impl<'a> From<&'a str> for Box` - // `impl From for Box where E: Error` - // - // So we have: - // - // `Box: From<&'?a str>` - // `Box: From` - // - // After equating the two headers: - // - // `Box = Box` - // So, `?E = &'?a str` and then given the where clause `&'?a str: Error`. - // - // If the obligation `&'?a str: Error` holds, it means that there's overlap. If that doesn't - // hold we need to check if `&'?a str: !Error` holds, if doesn't hold there's overlap because - // at some point an impl for `&'?a str: Error` could be added. - debug!( - "implicit_negative(impl1_header={:?}, impl2_header={:?}, obligations={:?})", - impl1_header, impl2_header, obligations - ); let infcx = selcx.infcx; - let opt_failing_obligation = impl1_header - .predicates - .iter() - .copied() - .chain(impl2_header.predicates) - .map(|p| infcx.resolve_vars_if_possible(p)) - .map(|p| Obligation { - cause: ObligationCause::dummy(), - param_env, - recursion_depth: 0, - predicate: p, + + let opt_failing_obligation = [&impl1_header.predicates, &impl2_header.predicates] + .into_iter() + .flatten() + .map(|&predicate| { + Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, predicate) }) .chain(obligations) .find(|o| !selcx.predicate_may_hold_fatal(o)); @@ -308,9 +302,27 @@ fn implicit_negative<'cx, 'tcx>( } } -/// Given impl1 and impl2 check if both impls are never satisfied by a common type (including -/// where-clauses) If so, return true, they are disjoint and false otherwise. -fn negative_impl(tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId) -> bool { +/// Check if both impls can be satisfied by a common type by considering whether +/// any of first impl's obligations is known not to hold *via a negative predicate*. +/// +/// For example, given these two impls: +/// `struct MyCustomBox(Box);` +/// `impl From<&str> for MyCustomBox` (in my crate) +/// `impl From for MyCustomBox where E: Error` (in my crate) +/// +/// After replacing the second impl's header with inference vars, we get: +/// `MyCustomBox: From<&str>` +/// `MyCustomBox: From` +/// +/// This gives us `?E = &str`. We then try to prove the first impl's predicates +/// after negating, giving us `&str: !Error`. This is a negative impl provided by +/// libstd, and therefore we can guarantee for certain that libstd will never add +/// a positive impl for `&str: Error` (without it being a breaking change). +fn impl_intersection_has_negative_obligation( + tcx: TyCtxt<'_>, + impl1_def_id: DefId, + impl2_def_id: DefId, +) -> bool { debug!("negative_impl(impl1_def_id={:?}, impl2_def_id={:?})", impl1_def_id, impl2_def_id); // Create an infcx, taking the predicates of impl1 as assumptions: @@ -336,57 +348,45 @@ fn negative_impl(tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId) -> b // Attempt to prove that impl2 applies, given all of the above. let selcx = &mut SelectionContext::new(&infcx); let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id); - let (subject2, obligations) = + let (subject2, normalization_obligations) = impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs, |_, _| { ObligationCause::dummy() }); - !equate(&infcx, impl_env, subject1, subject2, obligations, impl1_def_id) -} - -fn equate<'tcx>( - infcx: &InferCtxt<'tcx>, - impl_env: ty::ParamEnv<'tcx>, - subject1: ImplSubject<'tcx>, - subject2: ImplSubject<'tcx>, - obligations: impl Iterator>, - body_def_id: DefId, -) -> bool { - // do the impls unify? If not, not disjoint. - let Ok(InferOk { obligations: more_obligations, .. }) = + // do the impls unify? If not, then it's not currently possible to prove any + // obligations about their intersection. + let Ok(InferOk { obligations: equate_obligations, .. }) = infcx.at(&ObligationCause::dummy(), impl_env).eq(DefineOpaqueTypes::No,subject1, subject2) else { debug!("explicit_disjoint: {:?} does not unify with {:?}", subject1, subject2); - return true; + return false; }; - let opt_failing_obligation = obligations - .into_iter() - .chain(more_obligations) - .find(|o| negative_impl_exists(infcx, o, body_def_id)); - - if let Some(failing_obligation) = opt_failing_obligation { - debug!("overlap: obligation unsatisfiable {:?}", failing_obligation); - false - } else { - true + for obligation in normalization_obligations.into_iter().chain(equate_obligations) { + if negative_impl_exists(&infcx, &obligation, impl1_def_id) { + debug!("overlap: obligation unsatisfiable {:?}", obligation); + return true; + } } + + false } -/// Try to prove that a negative impl exist for the given obligation and its super predicates. +/// Try to prove that a negative impl exist for the obligation or its supertraits. +/// +/// If such a negative impl exists, then the obligation definitely must not hold +/// due to coherence, even if it's not necessarily "knowable" in this crate. Any +/// valid impl downstream would not be able to exist due to the overlapping +/// negative impl. #[instrument(level = "debug", skip(infcx))] fn negative_impl_exists<'tcx>( infcx: &InferCtxt<'tcx>, o: &PredicateObligation<'tcx>, body_def_id: DefId, ) -> bool { - if resolve_negative_obligation(infcx.fork(), o, body_def_id) { - return true; - } - // Try to prove a negative obligation exists for super predicates for pred in util::elaborate(infcx.tcx, iter::once(o.predicate)) { - if resolve_negative_obligation(infcx.fork(), &o.with(infcx.tcx, pred), body_def_id) { + if prove_negated_obligation(infcx.fork(), &o.with(infcx.tcx, pred), body_def_id) { return true; } } @@ -395,7 +395,7 @@ fn negative_impl_exists<'tcx>( } #[instrument(level = "debug", skip(infcx))] -fn resolve_negative_obligation<'tcx>( +fn prove_negated_obligation<'tcx>( infcx: InferCtxt<'tcx>, o: &PredicateObligation<'tcx>, body_def_id: DefId, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index c4481b39e14be..1bc4599377aac 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -66,6 +66,11 @@ pub struct ImplCandidate<'tcx> { pub similarity: CandidateSimilarity, } +enum GetSafeTransmuteErrorAndReason { + Silent, + Error { err_msg: String, safe_transmute_explanation: String }, +} + pub trait InferCtxtExt<'tcx> { /// Given some node representing a fn-like thing in the HIR map, /// returns a span and `ArgKind` information that describes the @@ -739,11 +744,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { == self.tcx.lang_items().transmute_trait() { // Recompute the safe transmute reason and use that for the error reporting - self.get_safe_transmute_error_and_reason( + match self.get_safe_transmute_error_and_reason( obligation.clone(), trait_ref, span, - ) + ) { + GetSafeTransmuteErrorAndReason::Silent => return, + GetSafeTransmuteErrorAndReason::Error { + err_msg, + safe_transmute_explanation, + } => (err_msg, Some(safe_transmute_explanation)), + } } else { (err_msg, None) }; @@ -1403,7 +1414,7 @@ trait InferCtxtPrivExt<'tcx> { obligation: PredicateObligation<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, span: Span, - ) -> (String, Option); + ) -> GetSafeTransmuteErrorAndReason; fn add_tuple_trait_message( &self, @@ -2850,7 +2861,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { obligation: PredicateObligation<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, span: Span, - ) -> (String, Option) { + ) -> GetSafeTransmuteErrorAndReason { + use rustc_transmute::Answer; + // Erase regions because layout code doesn't particularly care about regions. let trait_ref = self.tcx.erase_regions(self.tcx.erase_late_bound_regions(trait_ref)); @@ -2863,19 +2876,20 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, trait_ref.substs.const_at(3)) else { span_bug!(span, "Unable to construct rustc_transmute::Assume where it was previously possible"); }; + match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable( obligation.cause, src_and_dst, scope, assume, ) { - rustc_transmute::Answer::No(reason) => { + Answer::No(reason) => { let dst = trait_ref.substs.type_at(0); let src = trait_ref.substs.type_at(1); - let custom_err_msg = format!( + let err_msg = format!( "`{src}` cannot be safely transmuted into `{dst}` in the defining scope of `{scope}`" ); - let reason_msg = match reason { + let safe_transmute_explanation = match reason { rustc_transmute::Reason::SrcIsUnspecified => { format!("`{src}` does not have a well-specified layout") } @@ -2891,19 +2905,39 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { rustc_transmute::Reason::DstIsPrivate => format!( "`{dst}` is or contains a type or field that is not visible in that scope" ), - // FIXME(bryangarza): Include the number of bytes of src and dst rustc_transmute::Reason::DstIsTooBig => { format!("The size of `{src}` is smaller than the size of `{dst}`") } + rustc_transmute::Reason::DstHasStricterAlignment { + src_min_align, + dst_min_align, + } => { + format!( + "The minimum alignment of `{src}` ({src_min_align}) should be greater than that of `{dst}` ({dst_min_align})" + ) + } + rustc_transmute::Reason::DstIsMoreUnique => { + format!("`{src}` is a shared reference, but `{dst}` is a unique reference") + } + // Already reported by rustc + rustc_transmute::Reason::TypeError => { + return GetSafeTransmuteErrorAndReason::Silent; + } + rustc_transmute::Reason::SrcLayoutUnknown => { + format!("`{src}` has an unknown layout") + } + rustc_transmute::Reason::DstLayoutUnknown => { + format!("`{dst}` has an unknown layout") + } }; - (custom_err_msg, Some(reason_msg)) + GetSafeTransmuteErrorAndReason::Error { err_msg, safe_transmute_explanation } } // Should never get a Yes at this point! We already ran it before, and did not get a Yes. - rustc_transmute::Answer::Yes => span_bug!( + Answer::Yes => span_bug!( span, "Inconsistent rustc_transmute::is_transmutable(...) result, got Yes", ), - _ => span_bug!(span, "Unsupported rustc_transmute::Reason variant"), + other => span_bug!(span, "Unsupported rustc_transmute::Answer variant: `{other:?}`"), } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index e73d917a8aed1..5783383e93e3e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2663,9 +2663,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { | ObligationCauseCode::LetElse | ObligationCauseCode::BinOp { .. } | ObligationCauseCode::AscribeUserTypeProvePredicate(..) - | ObligationCauseCode::RustCall | ObligationCauseCode::DropImpl | ObligationCauseCode::ConstParam(_) => {} + ObligationCauseCode::RustCall => { + if let Some(pred) = predicate.to_opt_poly_trait_pred() + && Some(pred.def_id()) == self.tcx.lang_items().sized_trait() + { + err.note("argument required to be sized due to `extern \"rust-call\"` ABI"); + } + } ObligationCauseCode::SliceOrArrayElem => { err.note("slice and array elements must have `Sized` type"); } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index c2f94cb638566..db9cb82585f69 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -21,7 +21,7 @@ mod structural_match; mod structural_normalize; #[cfg_attr(not(bootstrap), allow(hidden_glob_reexports))] mod util; -mod vtable; +pub mod vtable; pub mod wf; use crate::infer::outlives::env::OutlivesEnvironment; @@ -354,7 +354,7 @@ pub fn normalize_param_env_or_error<'tcx>( // This works fairly well because trait matching does not actually care about param-env // TypeOutlives predicates - these are normally used by regionck. let outlives_predicates: Vec<_> = predicates - .drain_filter(|predicate| { + .extract_if(|predicate| { matches!( predicate.kind().skip_binder(), ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 563cc257e0349..0a1e971f268e3 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1170,11 +1170,11 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( }; let mut deduped: SsoHashSet<_> = Default::default(); - result.obligations.drain_filter(|projected_obligation| { + result.obligations.retain(|projected_obligation| { if !deduped.insert(projected_obligation.clone()) { - return true; + return false; } - false + true }); if use_cache { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4e961c3ee733c..7853af959ad5d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -6,6 +6,7 @@ //! //! [rustc dev guide]: //! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation +use rustc_ast::Mutability; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::lang_items::LangItem; use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; @@ -13,7 +14,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_middle::traits::SelectionOutputTypeParameterMismatch; use rustc_middle::ty::{ self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate, - TraitRef, Ty, TyCtxt, TypeVisitableExt, + TraitPredicate, TraitRef, Ty, TyCtxt, TypeVisitableExt, }; use rustc_session::config::TraitSolver; use rustc_span::def_id::DefId; @@ -279,11 +280,60 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplSourceBuiltinData { nested: obligations } } + #[instrument(level = "debug", skip(self))] fn confirm_transmutability_candidate( &mut self, obligation: &TraitObligation<'tcx>, ) -> Result>, SelectionError<'tcx>> { - debug!(?obligation, "confirm_transmutability_candidate"); + use rustc_transmute::{Answer, Condition}; + #[instrument(level = "debug", skip(tcx, obligation, predicate))] + fn flatten_answer_tree<'tcx>( + tcx: TyCtxt<'tcx>, + obligation: &TraitObligation<'tcx>, + predicate: TraitPredicate<'tcx>, + cond: Condition>, + ) -> Vec> { + match cond { + // FIXME(bryangarza): Add separate `IfAny` case, instead of treating as `IfAll` + // Not possible until the trait solver supports disjunctions of obligations + Condition::IfAll(conds) | Condition::IfAny(conds) => conds + .into_iter() + .flat_map(|cond| flatten_answer_tree(tcx, obligation, predicate, cond)) + .collect(), + Condition::IfTransmutable { src, dst } => { + let trait_def_id = obligation.predicate.def_id(); + let scope = predicate.trait_ref.substs.type_at(2); + let assume_const = predicate.trait_ref.substs.const_at(3); + let make_obl = |from_ty, to_ty| { + let trait_ref1 = ty::TraitRef::new( + tcx, + trait_def_id, + [ + ty::GenericArg::from(to_ty), + ty::GenericArg::from(from_ty), + ty::GenericArg::from(scope), + ty::GenericArg::from(assume_const), + ], + ); + Obligation::with_depth( + tcx, + obligation.cause.clone(), + obligation.recursion_depth + 1, + obligation.param_env, + trait_ref1, + ) + }; + + // If Dst is mutable, check bidirectionally. + // For example, transmuting bool -> u8 is OK as long as you can't update that u8 + // to be > 1, because you could later transmute the u8 back to a bool and get UB. + match dst.mutability { + Mutability::Not => vec![make_obl(src.ty, dst.ty)], + Mutability::Mut => vec![make_obl(src.ty, dst.ty), make_obl(dst.ty, src.ty)], + } + } + } + } // We erase regions here because transmutability calls layout queries, // which does not handle inference regions and doesn't particularly @@ -301,21 +351,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Err(Unimplemented); }; + let dst = predicate.trait_ref.substs.type_at(0); + let src = predicate.trait_ref.substs.type_at(1); + debug!(?src, ?dst); let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx); let maybe_transmutable = transmute_env.is_transmutable( obligation.cause.clone(), - rustc_transmute::Types { - dst: predicate.trait_ref.substs.type_at(0), - src: predicate.trait_ref.substs.type_at(1), - }, + rustc_transmute::Types { dst, src }, predicate.trait_ref.substs.type_at(2), assume, ); - match maybe_transmutable { - rustc_transmute::Answer::Yes => Ok(ImplSourceBuiltinData { nested: vec![] }), - _ => Err(Unimplemented), - } + let fully_flattened = match maybe_transmutable { + Answer::No(_) => Err(Unimplemented)?, + Answer::If(cond) => flatten_answer_tree(self.tcx(), obligation, predicate, cond), + Answer::Yes => vec![], + }; + + debug!(?fully_flattened); + Ok(ImplSourceBuiltinData { nested: fully_flattened }) } /// This handles the case where an `auto trait Foo` impl is being used. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 25e5b5e17deff..5acd7b573dd9a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -365,7 +365,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } if !candidate_set.ambiguous && no_candidates_apply { - let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; + let trait_ref = self.infcx.resolve_vars_if_possible( + stack.obligation.predicate.skip_binder().trait_ref, + ); if !trait_ref.references_error() { let self_ty = trait_ref.self_ty(); let (trait_desc, self_desc) = with_no_trimmed_paths!({ diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index cc674ceee3d5d..96b8e0b82b6af 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -15,13 +15,13 @@ use std::fmt::Debug; use std::ops::ControlFlow; #[derive(Clone, Debug)] -pub(super) enum VtblSegment<'tcx> { +pub enum VtblSegment<'tcx> { MetadataDSA, TraitOwnEntries { trait_ref: ty::PolyTraitRef<'tcx>, emit_vptr: bool }, } /// Prepare the segments for a vtable -pub(super) fn prepare_vtable_segments<'tcx, T>( +pub fn prepare_vtable_segments<'tcx, T>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, mut segment_visitor: impl FnMut(VtblSegment<'tcx>) -> ControlFlow, diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index 907e2d39c518f..590d0bd0e42e1 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -4,7 +4,6 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] #![feature(let_chains)] -#![feature(drain_filter)] #![recursion_limit = "256"] #[macro_use] diff --git a/compiler/rustc_transmute/src/layout/mod.rs b/compiler/rustc_transmute/src/layout/mod.rs index f8d05bc89d26d..76d97e0e6e7a6 100644 --- a/compiler/rustc_transmute/src/layout/mod.rs +++ b/compiler/rustc_transmute/src/layout/mod.rs @@ -30,33 +30,49 @@ impl fmt::Debug for Byte { } pub(crate) trait Def: Debug + Hash + Eq + PartialEq + Copy + Clone {} -pub trait Ref: Debug + Hash + Eq + PartialEq + Copy + Clone {} +pub trait Ref: Debug + Hash + Eq + PartialEq + Copy + Clone { + fn min_align(&self) -> usize; + + fn is_mutable(&self) -> bool; +} impl Def for ! {} -impl Ref for ! {} +impl Ref for ! { + fn min_align(&self) -> usize { + unreachable!() + } + fn is_mutable(&self) -> bool { + unreachable!() + } +} #[cfg(feature = "rustc")] -pub(crate) mod rustc { +pub mod rustc { use rustc_middle::mir::Mutability; - use rustc_middle::ty; - use rustc_middle::ty::Region; - use rustc_middle::ty::Ty; + use rustc_middle::ty::{self, Ty}; /// A reference in the layout. #[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Copy)] pub struct Ref<'tcx> { - lifetime: Region<'tcx>, - ty: Ty<'tcx>, - mutability: Mutability, + pub lifetime: ty::Region<'tcx>, + pub ty: Ty<'tcx>, + pub mutability: Mutability, + pub align: usize, } - impl<'tcx> super::Ref for Ref<'tcx> {} + impl<'tcx> super::Ref for Ref<'tcx> { + fn min_align(&self) -> usize { + self.align + } - impl<'tcx> Ref<'tcx> { - pub fn min_align(&self) -> usize { - todo!() + fn is_mutable(&self) -> bool { + match self.mutability { + Mutability::Mut => true, + Mutability::Not => false, + } } } + impl<'tcx> Ref<'tcx> {} /// A visibility node in the layout. #[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)] diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index a6d88b1342ae8..6b718be7b1564 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -188,14 +188,14 @@ pub(crate) mod rustc { /// The layout of the type is unspecified. Unspecified, /// This error will be surfaced elsewhere by rustc, so don't surface it. - Unknown, + UnknownLayout, TypeError(ErrorGuaranteed), } impl<'tcx> From> for Err { fn from(err: LayoutError<'tcx>) -> Self { match err { - LayoutError::Unknown(..) => Self::Unknown, + LayoutError::Unknown(..) => Self::UnknownLayout, err => unimplemented!("{:?}", err), } } @@ -365,6 +365,17 @@ pub(crate) mod rustc { } })) } + + ty::Ref(lifetime, ty, mutability) => { + let align = layout_of(tcx, *ty)?.align(); + Ok(Tree::Ref(Ref { + lifetime: *lifetime, + ty: *ty, + mutability: *mutability, + align, + })) + } + _ => Err(Err::Unspecified), } } diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 77c0526e3aabe..34ad6bd8c6923 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -8,7 +8,7 @@ extern crate tracing; pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set}; -pub(crate) mod layout; +pub mod layout; pub(crate) mod maybe_transmutable; #[derive(Default)] @@ -19,29 +19,29 @@ pub struct Assume { pub validity: bool, } -/// The type encodes answers to the question: "Are these types transmutable?" -#[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)] -pub enum Answer -where - R: layout::Ref, -{ - /// `Src` is transmutable into `Dst`. +/// Either we have an error, transmutation is allowed, or we have an optional +/// Condition that must hold. +#[derive(Debug, Hash, Eq, PartialEq, Clone)] +pub enum Answer { Yes, - - /// `Src` is NOT transmutable into `Dst`. No(Reason), + If(Condition), +} +/// A condition which must hold for safe transmutation to be possible. +#[derive(Debug, Hash, Eq, PartialEq, Clone)] +pub enum Condition { /// `Src` is transmutable into `Dst`, if `src` is transmutable into `dst`. IfTransmutable { src: R, dst: R }, /// `Src` is transmutable into `Dst`, if all of the enclosed requirements are met. - IfAll(Vec>), + IfAll(Vec>), /// `Src` is transmutable into `Dst` if any of the enclosed requirements are met. - IfAny(Vec>), + IfAny(Vec>), } -/// Answers: Why wasn't the source type transmutable into the destination type? +/// Answers "why wasn't the source type transmutable into the destination type?" #[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)] pub enum Reason { /// The layout of the source type is unspecified. @@ -54,6 +54,16 @@ pub enum Reason { DstIsPrivate, /// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized. DstIsTooBig, + /// Src should have a stricter alignment than Dst, but it does not. + DstHasStricterAlignment { src_min_align: usize, dst_min_align: usize }, + /// Can't go from shared pointer to unique pointer + DstIsMoreUnique, + /// Encountered a type error + TypeError, + /// The layout of src is unknown + SrcLayoutUnknown, + /// The layout of dst is unknown + DstLayoutUnknown, } #[cfg(feature = "rustc")] diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs index 2e2fb90e71c1a..b223a90f7514b 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs @@ -1,13 +1,13 @@ -use crate::Map; -use crate::{Answer, Reason}; - +pub(crate) mod query_context; #[cfg(test)] mod tests; -mod query_context; -use query_context::QueryContext; +use crate::{ + layout::{self, dfa, Byte, Dfa, Nfa, Ref, Tree, Uninhabited}, + maybe_transmutable::query_context::QueryContext, + Answer, Condition, Map, Reason, +}; -use crate::layout::{self, dfa, Byte, Dfa, Nfa, Tree, Uninhabited}; pub(crate) struct MaybeTransmutableQuery where C: QueryContext, @@ -33,6 +33,7 @@ where Self { src, dst, scope, assume, context } } + // FIXME(bryangarza): Delete this when all usages are removed pub(crate) fn map_layouts( self, f: F, @@ -53,6 +54,7 @@ where } } +// FIXME: Nix this cfg, so we can write unit tests independently of rustc #[cfg(feature = "rustc")] mod rustc { use super::*; @@ -66,30 +68,26 @@ mod rustc { /// then computes an answer using those trees. #[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))] pub fn answer(self) -> Answer< as QueryContext>::Ref> { - let query_or_answer = self.map_layouts(|src, dst, scope, &context| { - // Convert `src` and `dst` from their rustc representations, to `Tree`-based - // representations. If these conversions fail, conclude that the transmutation is - // unacceptable; the layouts of both the source and destination types must be - // well-defined. - let src = Tree::from_ty(src, context); - let dst = Tree::from_ty(dst, context); - - match (src, dst) { - // Answer `Yes` here, because 'unknown layout' and type errors will already - // be reported by rustc. No need to spam the user with more errors. - (Err(Err::TypeError(_)), _) => Err(Answer::Yes), - (_, Err(Err::TypeError(_))) => Err(Answer::Yes), - (Err(Err::Unknown), _) => Err(Answer::Yes), - (_, Err(Err::Unknown)) => Err(Answer::Yes), - (Err(Err::Unspecified), _) => Err(Answer::No(Reason::SrcIsUnspecified)), - (_, Err(Err::Unspecified)) => Err(Answer::No(Reason::DstIsUnspecified)), - (Ok(src), Ok(dst)) => Ok((src, dst)), - } - }); + let Self { src, dst, scope, assume, context } = self; + + // Convert `src` and `dst` from their rustc representations, to `Tree`-based + // representations. If these conversions fail, conclude that the transmutation is + // unacceptable; the layouts of both the source and destination types must be + // well-defined. + let src = Tree::from_ty(src, context); + let dst = Tree::from_ty(dst, context); - match query_or_answer { - Ok(query) => query.answer(), - Err(answer) => answer, + match (src, dst) { + (Err(Err::TypeError(_)), _) | (_, Err(Err::TypeError(_))) => { + Answer::No(Reason::TypeError) + } + (Err(Err::UnknownLayout), _) => Answer::No(Reason::SrcLayoutUnknown), + (_, Err(Err::UnknownLayout)) => Answer::No(Reason::DstLayoutUnknown), + (Err(Err::Unspecified), _) => Answer::No(Reason::SrcIsUnspecified), + (_, Err(Err::Unspecified)) => Answer::No(Reason::DstIsUnspecified), + (Ok(src), Ok(dst)) => { + MaybeTransmutableQuery { src, dst, scope, assume, context }.answer() + } } } } @@ -107,6 +105,7 @@ where #[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))] pub(crate) fn answer(self) -> Answer<::Ref> { let assume_visibility = self.assume.safety; + // FIXME(bryangarza): Refactor this code to get rid of `map_layouts` let query_or_answer = self.map_layouts(|src, dst, scope, context| { // Remove all `Def` nodes from `src`, without checking their visibility. let src = src.prune(&|def| true); @@ -155,6 +154,7 @@ where #[inline(always)] #[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))] pub(crate) fn answer(self) -> Answer<::Ref> { + // FIXME(bryangarza): Refactor this code to get rid of `map_layouts` let query_or_answer = self .map_layouts(|src, dst, scope, context| Ok((Dfa::from_nfa(src), Dfa::from_nfa(dst)))); @@ -203,8 +203,29 @@ where if let Some(answer) = cache.get(&(src_state, dst_state)) { answer.clone() } else { + debug!(?src_state, ?dst_state); + debug!(src = ?self.src); + debug!(dst = ?self.dst); + debug!( + src_transitions_len = self.src.transitions.len(), + dst_transitions_len = self.dst.transitions.len() + ); let answer = if dst_state == self.dst.accepting { // truncation: `size_of(Src) >= size_of(Dst)` + // + // Why is truncation OK to do? Because even though the Src is bigger, all we care about + // is whether we have enough data for the Dst to be valid in accordance with what its + // type dictates. + // For example, in a u8 to `()` transmutation, we have enough data available from the u8 + // to transmute it to a `()` (though in this case does `()` really need any data to + // begin with? It doesn't). Same thing with u8 to fieldless struct. + // Now then, why is something like u8 to bool not allowed? That is not because the bool + // is smaller in size, but rather because those 2 bits that we are re-interpreting from + // the u8 could introduce invalid states for the bool type. + // + // So, if it's possible to transmute to a smaller Dst by truncating, and we can guarantee + // that none of the actually-used data can introduce an invalid state for Dst's type, we + // are able to safely transmute, even with truncation. Answer::Yes } else if src_state == self.src.accepting { // extension: `size_of(Src) >= size_of(Dst)` @@ -214,108 +235,201 @@ where Answer::No(Reason::DstIsTooBig) } } else { - let src_quantification = if self.assume.validity { + let src_quantifier = if self.assume.validity { // if the compiler may assume that the programmer is doing additional validity checks, // (e.g.: that `src != 3u8` when the destination type is `bool`) // then there must exist at least one transition out of `src_state` such that the transmute is viable... - there_exists + Quantifier::ThereExists } else { // if the compiler cannot assume that the programmer is doing additional validity checks, // then for all transitions out of `src_state`, such that the transmute is viable... - // then there must exist at least one transition out of `src_state` such that the transmute is viable... - for_all + // then there must exist at least one transition out of `dst_state` such that the transmute is viable... + Quantifier::ForAll + }; + + let bytes_answer = src_quantifier.apply( + // for each of the byte transitions out of the `src_state`... + self.src.bytes_from(src_state).unwrap_or(&Map::default()).into_iter().map( + |(&src_validity, &src_state_prime)| { + // ...try to find a matching transition out of `dst_state`. + if let Some(dst_state_prime) = + self.dst.byte_from(dst_state, src_validity) + { + self.answer_memo(cache, src_state_prime, dst_state_prime) + } else if let Some(dst_state_prime) = + // otherwise, see if `dst_state` has any outgoing `Uninit` transitions + // (any init byte is a valid uninit byte) + self.dst.byte_from(dst_state, Byte::Uninit) + { + self.answer_memo(cache, src_state_prime, dst_state_prime) + } else { + // otherwise, we've exhausted our options. + // the DFAs, from this point onwards, are bit-incompatible. + Answer::No(Reason::DstIsBitIncompatible) + } + }, + ), + ); + + // The below early returns reflect how this code would behave: + // if self.assume.validity { + // or(bytes_answer, refs_answer) + // } else { + // and(bytes_answer, refs_answer) + // } + // ...if `refs_answer` was computed lazily. The below early + // returns can be deleted without impacting the correctness of + // the algoritm; only its performance. + debug!(?bytes_answer); + match bytes_answer { + Answer::No(_) if !self.assume.validity => return bytes_answer, + Answer::Yes if self.assume.validity => return bytes_answer, + _ => {} }; - src_quantification( - self.src.bytes_from(src_state).unwrap_or(&Map::default()), - |(&src_validity, &src_state_prime)| { - if let Some(dst_state_prime) = self.dst.byte_from(dst_state, src_validity) { - self.answer_memo(cache, src_state_prime, dst_state_prime) - } else if let Some(dst_state_prime) = - self.dst.byte_from(dst_state, Byte::Uninit) - { - self.answer_memo(cache, src_state_prime, dst_state_prime) - } else { - Answer::No(Reason::DstIsBitIncompatible) - } - }, - ) + let refs_answer = src_quantifier.apply( + // for each reference transition out of `src_state`... + self.src.refs_from(src_state).unwrap_or(&Map::default()).into_iter().map( + |(&src_ref, &src_state_prime)| { + // ...there exists a reference transition out of `dst_state`... + Quantifier::ThereExists.apply( + self.dst + .refs_from(dst_state) + .unwrap_or(&Map::default()) + .into_iter() + .map(|(&dst_ref, &dst_state_prime)| { + if !src_ref.is_mutable() && dst_ref.is_mutable() { + Answer::No(Reason::DstIsMoreUnique) + } else if !self.assume.alignment + && src_ref.min_align() < dst_ref.min_align() + { + Answer::No(Reason::DstHasStricterAlignment { + src_min_align: src_ref.min_align(), + dst_min_align: dst_ref.min_align(), + }) + } else { + // ...such that `src` is transmutable into `dst`, if + // `src_ref` is transmutability into `dst_ref`. + and( + Answer::If(Condition::IfTransmutable { + src: src_ref, + dst: dst_ref, + }), + self.answer_memo( + cache, + src_state_prime, + dst_state_prime, + ), + ) + } + }), + ) + }, + ), + ); + + if self.assume.validity { + or(bytes_answer, refs_answer) + } else { + and(bytes_answer, refs_answer) + } }; - cache.insert((src_state, dst_state), answer.clone()); + if let Some(..) = cache.insert((src_state, dst_state), answer.clone()) { + panic!("failed to correctly cache transmutability") + } answer } } } -impl Answer +fn and(lhs: Answer, rhs: Answer) -> Answer where - R: layout::Ref, + R: PartialEq, { - pub(crate) fn and(self, rhs: Self) -> Self { - match (self, rhs) { - (Self::No(reason), _) | (_, Self::No(reason)) => Self::No(reason), - (Self::Yes, Self::Yes) => Self::Yes, - (Self::IfAll(mut lhs), Self::IfAll(ref mut rhs)) => { - lhs.append(rhs); - Self::IfAll(lhs) - } - (constraint, Self::IfAll(mut constraints)) - | (Self::IfAll(mut constraints), constraint) => { - constraints.push(constraint); - Self::IfAll(constraints) - } - (lhs, rhs) => Self::IfAll(vec![lhs, rhs]), + match (lhs, rhs) { + // If both are errors, then we should return the more specific one + (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason)) + | (Answer::No(reason), Answer::No(_)) + // If either is an error, return it + | (Answer::No(reason), _) | (_, Answer::No(reason)) => Answer::No(reason), + // If only one side has a condition, pass it along + | (Answer::Yes, other) | (other, Answer::Yes) => other, + // If both sides have IfAll conditions, merge them + (Answer::If(Condition::IfAll(mut lhs)), Answer::If(Condition::IfAll(ref mut rhs))) => { + lhs.append(rhs); + Answer::If(Condition::IfAll(lhs)) } - } - - pub(crate) fn or(self, rhs: Self) -> Self { - match (self, rhs) { - (Self::Yes, _) | (_, Self::Yes) => Self::Yes, - (Self::No(lhr), Self::No(rhr)) => Self::No(lhr), - (Self::IfAny(mut lhs), Self::IfAny(ref mut rhs)) => { - lhs.append(rhs); - Self::IfAny(lhs) - } - (constraint, Self::IfAny(mut constraints)) - | (Self::IfAny(mut constraints), constraint) => { - constraints.push(constraint); - Self::IfAny(constraints) - } - (lhs, rhs) => Self::IfAny(vec![lhs, rhs]), + // If only one side is an IfAll, add the other Condition to it + (Answer::If(cond), Answer::If(Condition::IfAll(mut conds))) + | (Answer::If(Condition::IfAll(mut conds)), Answer::If(cond)) => { + conds.push(cond); + Answer::If(Condition::IfAll(conds)) } + // Otherwise, both lhs and rhs conditions can be combined in a parent IfAll + (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAll(vec![lhs, rhs])), } } -pub fn for_all(iter: I, f: F) -> Answer +fn or(lhs: Answer, rhs: Answer) -> Answer where - R: layout::Ref, - I: IntoIterator, - F: FnMut(::Item) -> Answer, + R: PartialEq, { - use std::ops::ControlFlow::{Break, Continue}; - let (Continue(result) | Break(result)) = - iter.into_iter().map(f).try_fold(Answer::Yes, |constraints, constraint| { - match constraint.and(constraints) { - Answer::No(reason) => Break(Answer::No(reason)), - maybe => Continue(maybe), - } - }); - result + match (lhs, rhs) { + // If both are errors, then we should return the more specific one + (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason)) + | (Answer::No(reason), Answer::No(_)) => Answer::No(reason), + // Otherwise, errors can be ignored for the rest of the pattern matching + (Answer::No(_), other) | (other, Answer::No(_)) => or(other, Answer::Yes), + // If only one side has a condition, pass it along + (Answer::Yes, other) | (other, Answer::Yes) => other, + // If both sides have IfAny conditions, merge them + (Answer::If(Condition::IfAny(mut lhs)), Answer::If(Condition::IfAny(ref mut rhs))) => { + lhs.append(rhs); + Answer::If(Condition::IfAny(lhs)) + } + // If only one side is an IfAny, add the other Condition to it + (Answer::If(cond), Answer::If(Condition::IfAny(mut conds))) + | (Answer::If(Condition::IfAny(mut conds)), Answer::If(cond)) => { + conds.push(cond); + Answer::If(Condition::IfAny(conds)) + } + // Otherwise, both lhs and rhs conditions can be combined in a parent IfAny + (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAny(vec![lhs, rhs])), + } } -pub fn there_exists(iter: I, f: F) -> Answer -where - R: layout::Ref, - I: IntoIterator, - F: FnMut(::Item) -> Answer, -{ - use std::ops::ControlFlow::{Break, Continue}; - let (Continue(result) | Break(result)) = iter.into_iter().map(f).try_fold( - Answer::No(Reason::DstIsBitIncompatible), - |constraints, constraint| match constraint.or(constraints) { - Answer::Yes => Break(Answer::Yes), - maybe => Continue(maybe), - }, - ); - result +pub enum Quantifier { + ThereExists, + ForAll, +} + +impl Quantifier { + pub fn apply(&self, iter: I) -> Answer + where + R: layout::Ref, + I: IntoIterator>, + { + use std::ops::ControlFlow::{Break, Continue}; + + let (init, try_fold_f): (_, fn(_, _) -> _) = match self { + Self::ThereExists => { + (Answer::No(Reason::DstIsBitIncompatible), |accum: Answer, next| { + match or(accum, next) { + Answer::Yes => Break(Answer::Yes), + maybe => Continue(maybe), + } + }) + } + Self::ForAll => (Answer::Yes, |accum: Answer, next| { + let answer = and(accum, next); + match answer { + Answer::No(_) => Break(answer), + maybe => Continue(maybe), + } + }), + }; + + let (Continue(result) | Break(result)) = iter.into_iter().try_fold(init, try_fold_f); + result + } } diff --git a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs index a8675f4ae37d8..e49bebf571dea 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs @@ -1,9 +1,11 @@ use super::query_context::test::{Def, UltraMinimal}; use crate::maybe_transmutable::MaybeTransmutableQuery; -use crate::{layout, Answer, Reason}; +use crate::{layout, Reason}; use itertools::Itertools; mod bool { + use crate::Answer; + use super::*; #[test] diff --git a/library/alloc/benches/btree/map.rs b/library/alloc/benches/btree/map.rs index ec1b0a8eba039..7d236647750d0 100644 --- a/library/alloc/benches/btree/map.rs +++ b/library/alloc/benches/btree/map.rs @@ -385,7 +385,7 @@ pub fn clone_slim_100_and_clear(b: &mut Bencher) { #[bench] pub fn clone_slim_100_and_drain_all(b: &mut Bencher) { let src = slim_map(100); - b.iter(|| src.clone().drain_filter(|_, _| true).count()) + b.iter(|| src.clone().extract_if(|_, _| true).count()) } #[bench] @@ -393,7 +393,7 @@ pub fn clone_slim_100_and_drain_half(b: &mut Bencher) { let src = slim_map(100); b.iter(|| { let mut map = src.clone(); - assert_eq!(map.drain_filter(|i, _| i % 2 == 0).count(), 100 / 2); + assert_eq!(map.extract_if(|i, _| i % 2 == 0).count(), 100 / 2); assert_eq!(map.len(), 100 / 2); }) } @@ -456,7 +456,7 @@ pub fn clone_slim_10k_and_clear(b: &mut Bencher) { #[bench] pub fn clone_slim_10k_and_drain_all(b: &mut Bencher) { let src = slim_map(10_000); - b.iter(|| src.clone().drain_filter(|_, _| true).count()) + b.iter(|| src.clone().extract_if(|_, _| true).count()) } #[bench] @@ -464,7 +464,7 @@ pub fn clone_slim_10k_and_drain_half(b: &mut Bencher) { let src = slim_map(10_000); b.iter(|| { let mut map = src.clone(); - assert_eq!(map.drain_filter(|i, _| i % 2 == 0).count(), 10_000 / 2); + assert_eq!(map.extract_if(|i, _| i % 2 == 0).count(), 10_000 / 2); assert_eq!(map.len(), 10_000 / 2); }) } @@ -527,7 +527,7 @@ pub fn clone_fat_val_100_and_clear(b: &mut Bencher) { #[bench] pub fn clone_fat_val_100_and_drain_all(b: &mut Bencher) { let src = fat_val_map(100); - b.iter(|| src.clone().drain_filter(|_, _| true).count()) + b.iter(|| src.clone().extract_if(|_, _| true).count()) } #[bench] @@ -535,7 +535,7 @@ pub fn clone_fat_val_100_and_drain_half(b: &mut Bencher) { let src = fat_val_map(100); b.iter(|| { let mut map = src.clone(); - assert_eq!(map.drain_filter(|i, _| i % 2 == 0).count(), 100 / 2); + assert_eq!(map.extract_if(|i, _| i % 2 == 0).count(), 100 / 2); assert_eq!(map.len(), 100 / 2); }) } diff --git a/library/alloc/benches/btree/set.rs b/library/alloc/benches/btree/set.rs index 3f4b0e0f14af7..09d72c7206469 100644 --- a/library/alloc/benches/btree/set.rs +++ b/library/alloc/benches/btree/set.rs @@ -69,7 +69,7 @@ pub fn clone_100_and_clear(b: &mut Bencher) { #[bench] pub fn clone_100_and_drain_all(b: &mut Bencher) { let src = slim_set(100); - b.iter(|| src.clone().drain_filter(|_| true).count()) + b.iter(|| src.clone().extract_if(|_| true).count()) } #[bench] @@ -77,7 +77,7 @@ pub fn clone_100_and_drain_half(b: &mut Bencher) { let src = slim_set(100); b.iter(|| { let mut set = src.clone(); - assert_eq!(set.drain_filter(|i| i % 2 == 0).count(), 100 / 2); + assert_eq!(set.extract_if(|i| i % 2 == 0).count(), 100 / 2); assert_eq!(set.len(), 100 / 2); }) } @@ -140,7 +140,7 @@ pub fn clone_10k_and_clear(b: &mut Bencher) { #[bench] pub fn clone_10k_and_drain_all(b: &mut Bencher) { let src = slim_set(10_000); - b.iter(|| src.clone().drain_filter(|_| true).count()) + b.iter(|| src.clone().extract_if(|_| true).count()) } #[bench] @@ -148,7 +148,7 @@ pub fn clone_10k_and_drain_half(b: &mut Bencher) { let src = slim_set(10_000); b.iter(|| { let mut set = src.clone(); - assert_eq!(set.drain_filter(|i| i % 2 == 0).count(), 10_000 / 2); + assert_eq!(set.extract_if(|i| i % 2 == 0).count(), 10_000 / 2); assert_eq!(set.len(), 10_000 / 2); }) } diff --git a/library/alloc/benches/lib.rs b/library/alloc/benches/lib.rs index b25d63d835b54..638f343fb244b 100644 --- a/library/alloc/benches/lib.rs +++ b/library/alloc/benches/lib.rs @@ -1,7 +1,7 @@ // Disabling on android for the time being // See https://github.com/rust-lang/rust/issues/73535#event-3477699747 #![cfg(not(target_os = "android"))] -#![feature(btree_drain_filter)] +#![feature(btree_extract_if)] #![feature(iter_next_chunk)] #![feature(repr_simd)] #![feature(slice_partition_dedup)] diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 2c089bb314900..66573b90db963 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -143,6 +143,7 @@ #![allow(missing_docs)] #![stable(feature = "rust1", since = "1.0.0")] +use core::alloc::Allocator; use core::fmt; use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedLen}; use core::mem::{self, swap, ManuallyDrop}; @@ -150,6 +151,7 @@ use core::num::NonZeroUsize; use core::ops::{Deref, DerefMut}; use core::ptr; +use crate::alloc::Global; use crate::collections::TryReserveError; use crate::slice; use crate::vec::{self, AsVecIntoIter, Vec}; @@ -271,8 +273,11 @@ mod tests; /// [peek\_mut]: BinaryHeap::peek_mut #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "BinaryHeap")] -pub struct BinaryHeap { - data: Vec, +pub struct BinaryHeap< + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + data: Vec, } /// Structure wrapping a mutable reference to the greatest item on a @@ -283,22 +288,26 @@ pub struct BinaryHeap { /// /// [`peek_mut`]: BinaryHeap::peek_mut #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -pub struct PeekMut<'a, T: 'a + Ord> { - heap: &'a mut BinaryHeap, +pub struct PeekMut< + 'a, + T: 'a + Ord, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + heap: &'a mut BinaryHeap, // If a set_len + sift_down are required, this is Some. If a &mut T has not // yet been exposed to peek_mut()'s caller, it's None. original_len: Option, } #[stable(feature = "collection_debug", since = "1.17.0")] -impl fmt::Debug for PeekMut<'_, T> { +impl fmt::Debug for PeekMut<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("PeekMut").field(&self.heap.data[0]).finish() } } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl Drop for PeekMut<'_, T> { +impl Drop for PeekMut<'_, T, A> { fn drop(&mut self) { if let Some(original_len) = self.original_len { // SAFETY: That's how many elements were in the Vec at the time of @@ -315,7 +324,7 @@ impl Drop for PeekMut<'_, T> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl Deref for PeekMut<'_, T> { +impl Deref for PeekMut<'_, T, A> { type Target = T; fn deref(&self) -> &T { debug_assert!(!self.heap.is_empty()); @@ -325,7 +334,7 @@ impl Deref for PeekMut<'_, T> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl DerefMut for PeekMut<'_, T> { +impl DerefMut for PeekMut<'_, T, A> { fn deref_mut(&mut self) -> &mut T { debug_assert!(!self.heap.is_empty()); @@ -353,10 +362,10 @@ impl DerefMut for PeekMut<'_, T> { } } -impl<'a, T: Ord> PeekMut<'a, T> { +impl<'a, T: Ord, A: Allocator> PeekMut<'a, T, A> { /// Removes the peeked value from the heap and returns it. #[stable(feature = "binary_heap_peek_mut_pop", since = "1.18.0")] - pub fn pop(mut this: PeekMut<'a, T>) -> T { + pub fn pop(mut this: PeekMut<'a, T, A>) -> T { if let Some(original_len) = this.original_len.take() { // SAFETY: This is how many elements were in the Vec at the time of // the BinaryHeap::peek_mut call. @@ -371,7 +380,7 @@ impl<'a, T: Ord> PeekMut<'a, T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for BinaryHeap { +impl Clone for BinaryHeap { fn clone(&self) -> Self { BinaryHeap { data: self.data.clone() } } @@ -391,18 +400,22 @@ impl Default for BinaryHeap { } #[stable(feature = "binaryheap_debug", since = "1.4.0")] -impl fmt::Debug for BinaryHeap { +impl fmt::Debug for BinaryHeap { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.iter()).finish() } } -struct RebuildOnDrop<'a, T: Ord> { - heap: &'a mut BinaryHeap, +struct RebuildOnDrop< + 'a, + T: Ord, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + heap: &'a mut BinaryHeap, rebuild_from: usize, } -impl<'a, T: Ord> Drop for RebuildOnDrop<'a, T> { +impl Drop for RebuildOnDrop<'_, T, A> { fn drop(&mut self) { self.heap.rebuild_tail(self.rebuild_from); } @@ -446,6 +459,52 @@ impl BinaryHeap { pub fn with_capacity(capacity: usize) -> BinaryHeap { BinaryHeap { data: Vec::with_capacity(capacity) } } +} + +impl BinaryHeap { + /// Creates an empty `BinaryHeap` as a max-heap, using `A` as allocator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// use std::collections::BinaryHeap; + /// let mut heap = BinaryHeap::new_in(System); + /// heap.push(4); + /// ``` + #[unstable(feature = "allocator_api", issue = "32838")] + #[must_use] + pub fn new_in(alloc: A) -> BinaryHeap { + BinaryHeap { data: Vec::new_in(alloc) } + } + + /// Creates an empty `BinaryHeap` with at least the specified capacity, using `A` as allocator. + /// + /// The binary heap will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is 0, the binary heap will not allocate. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// use std::collections::BinaryHeap; + /// let mut heap = BinaryHeap::with_capacity_in(10, System); + /// heap.push(4); + /// ``` + #[unstable(feature = "allocator_api", issue = "32838")] + #[must_use] + pub fn with_capacity_in(capacity: usize, alloc: A) -> BinaryHeap { + BinaryHeap { data: Vec::with_capacity_in(capacity, alloc) } + } /// Returns a mutable reference to the greatest item in the binary heap, or /// `None` if it is empty. @@ -478,7 +537,7 @@ impl BinaryHeap { /// If the item is modified then the worst case time complexity is *O*(log(*n*)), /// otherwise it's *O*(1). #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] - pub fn peek_mut(&mut self) -> Option> { + pub fn peek_mut(&mut self) -> Option> { if self.is_empty() { None } else { Some(PeekMut { heap: self, original_len: None }) } } @@ -573,7 +632,7 @@ impl BinaryHeap { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] - pub fn into_sorted_vec(mut self) -> Vec { + pub fn into_sorted_vec(mut self) -> Vec { let mut end = self.len(); while end > 1 { end -= 1; @@ -831,7 +890,7 @@ impl BinaryHeap { /// ``` #[inline] #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] - pub fn drain_sorted(&mut self) -> DrainSorted<'_, T> { + pub fn drain_sorted(&mut self) -> DrainSorted<'_, T, A> { DrainSorted { inner: self } } @@ -874,7 +933,7 @@ impl BinaryHeap { } } -impl BinaryHeap { +impl BinaryHeap { /// Returns an iterator visiting all values in the underlying vector, in /// arbitrary order. /// @@ -911,7 +970,7 @@ impl BinaryHeap { /// assert_eq!(heap.into_iter_sorted().take(2).collect::>(), [5, 4]); /// ``` #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] - pub fn into_iter_sorted(self) -> IntoIterSorted { + pub fn into_iter_sorted(self) -> IntoIterSorted { IntoIterSorted { inner: self } } @@ -1178,10 +1237,17 @@ impl BinaryHeap { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] - pub fn into_vec(self) -> Vec { + pub fn into_vec(self) -> Vec { self.into() } + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn allocator(&self) -> &A { + self.data.allocator() + } + /// Returns the length of the binary heap. /// /// # Examples @@ -1249,7 +1315,7 @@ impl BinaryHeap { /// ``` #[inline] #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self) -> Drain<'_, T> { + pub fn drain(&mut self) -> Drain<'_, T, A> { Drain { iter: self.data.drain(..) } } @@ -1419,19 +1485,30 @@ impl FusedIterator for Iter<'_, T> {} /// [`into_iter`]: BinaryHeap::into_iter #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] -pub struct IntoIter { - iter: vec::IntoIter, +pub struct IntoIter< + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + iter: vec::IntoIter, +} + +impl IntoIter { + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn allocator(&self) -> &A { + self.iter.allocator() + } } #[stable(feature = "collection_debug", since = "1.17.0")] -impl fmt::Debug for IntoIter { +impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IntoIter").field(&self.iter.as_slice()).finish() } } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = T; #[inline] @@ -1446,7 +1523,7 @@ impl Iterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for IntoIter { +impl DoubleEndedIterator for IntoIter { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back() @@ -1454,14 +1531,14 @@ impl DoubleEndedIterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for IntoIter { +impl ExactSizeIterator for IntoIter { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for IntoIter {} +impl FusedIterator for IntoIter {} #[stable(feature = "default_iters", since = "1.70.0")] impl Default for IntoIter { @@ -1481,8 +1558,8 @@ impl Default for IntoIter { // also refer to the vec::in_place_collect module documentation to get an overview #[unstable(issue = "none", feature = "inplace_iteration")] #[doc(hidden)] -unsafe impl SourceIter for IntoIter { - type Source = IntoIter; +unsafe impl SourceIter for IntoIter { + type Source = IntoIter; #[inline] unsafe fn as_inner(&mut self) -> &mut Self::Source { @@ -1492,7 +1569,7 @@ unsafe impl SourceIter for IntoIter { #[unstable(issue = "none", feature = "inplace_iteration")] #[doc(hidden)] -unsafe impl InPlaceIterable for IntoIter {} +unsafe impl InPlaceIterable for IntoIter {} unsafe impl AsVecIntoIter for IntoIter { type Item = I; @@ -1505,12 +1582,23 @@ unsafe impl AsVecIntoIter for IntoIter { #[must_use = "iterators are lazy and do nothing unless consumed"] #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] #[derive(Clone, Debug)] -pub struct IntoIterSorted { - inner: BinaryHeap, +pub struct IntoIterSorted< + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + inner: BinaryHeap, +} + +impl IntoIterSorted { + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn allocator(&self) -> &A { + self.inner.allocator() + } } #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] -impl Iterator for IntoIterSorted { +impl Iterator for IntoIterSorted { type Item = T; #[inline] @@ -1526,13 +1614,13 @@ impl Iterator for IntoIterSorted { } #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] -impl ExactSizeIterator for IntoIterSorted {} +impl ExactSizeIterator for IntoIterSorted {} #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] -impl FusedIterator for IntoIterSorted {} +impl FusedIterator for IntoIterSorted {} #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for IntoIterSorted {} +unsafe impl TrustedLen for IntoIterSorted {} /// A draining iterator over the elements of a `BinaryHeap`. /// @@ -1542,12 +1630,24 @@ unsafe impl TrustedLen for IntoIterSorted {} /// [`drain`]: BinaryHeap::drain #[stable(feature = "drain", since = "1.6.0")] #[derive(Debug)] -pub struct Drain<'a, T: 'a> { - iter: vec::Drain<'a, T>, +pub struct Drain< + 'a, + T: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + iter: vec::Drain<'a, T, A>, +} + +impl Drain<'_, T, A> { + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn allocator(&self) -> &A { + self.iter.allocator() + } } #[stable(feature = "drain", since = "1.6.0")] -impl Iterator for Drain<'_, T> { +impl Iterator for Drain<'_, T, A> { type Item = T; #[inline] @@ -1562,7 +1662,7 @@ impl Iterator for Drain<'_, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl DoubleEndedIterator for Drain<'_, T> { +impl DoubleEndedIterator for Drain<'_, T, A> { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back() @@ -1570,14 +1670,14 @@ impl DoubleEndedIterator for Drain<'_, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl ExactSizeIterator for Drain<'_, T> { +impl ExactSizeIterator for Drain<'_, T, A> { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Drain<'_, T> {} +impl FusedIterator for Drain<'_, T, A> {} /// A draining iterator over the elements of a `BinaryHeap`. /// @@ -1587,17 +1687,29 @@ impl FusedIterator for Drain<'_, T> {} /// [`drain_sorted`]: BinaryHeap::drain_sorted #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] #[derive(Debug)] -pub struct DrainSorted<'a, T: Ord> { - inner: &'a mut BinaryHeap, +pub struct DrainSorted< + 'a, + T: Ord, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + inner: &'a mut BinaryHeap, +} + +impl<'a, T: Ord, A: Allocator> DrainSorted<'a, T, A> { + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn allocator(&self) -> &A { + self.inner.allocator() + } } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl<'a, T: Ord> Drop for DrainSorted<'a, T> { +impl<'a, T: Ord, A: Allocator> Drop for DrainSorted<'a, T, A> { /// Removes heap elements in heap order. fn drop(&mut self) { - struct DropGuard<'r, 'a, T: Ord>(&'r mut DrainSorted<'a, T>); + struct DropGuard<'r, 'a, T: Ord, A: Allocator>(&'r mut DrainSorted<'a, T, A>); - impl<'r, 'a, T: Ord> Drop for DropGuard<'r, 'a, T> { + impl<'r, 'a, T: Ord, A: Allocator> Drop for DropGuard<'r, 'a, T, A> { fn drop(&mut self) { while self.0.inner.pop().is_some() {} } @@ -1612,7 +1724,7 @@ impl<'a, T: Ord> Drop for DrainSorted<'a, T> { } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl Iterator for DrainSorted<'_, T> { +impl Iterator for DrainSorted<'_, T, A> { type Item = T; #[inline] @@ -1628,20 +1740,20 @@ impl Iterator for DrainSorted<'_, T> { } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl ExactSizeIterator for DrainSorted<'_, T> {} +impl ExactSizeIterator for DrainSorted<'_, T, A> {} #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl FusedIterator for DrainSorted<'_, T> {} +impl FusedIterator for DrainSorted<'_, T, A> {} #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for DrainSorted<'_, T> {} +unsafe impl TrustedLen for DrainSorted<'_, T, A> {} #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] -impl From> for BinaryHeap { +impl From> for BinaryHeap { /// Converts a `Vec` into a `BinaryHeap`. /// /// This conversion happens in-place, and has *O*(*n*) time complexity. - fn from(vec: Vec) -> BinaryHeap { + fn from(vec: Vec) -> BinaryHeap { let mut heap = BinaryHeap { data: vec }; heap.rebuild(); heap @@ -1665,12 +1777,12 @@ impl From<[T; N]> for BinaryHeap { } #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] -impl From> for Vec { +impl From> for Vec { /// Converts a `BinaryHeap` into a `Vec`. /// /// This conversion requires no data movement or allocation, and has /// constant time complexity. - fn from(heap: BinaryHeap) -> Vec { + fn from(heap: BinaryHeap) -> Vec { heap.data } } @@ -1683,9 +1795,9 @@ impl FromIterator for BinaryHeap { } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for BinaryHeap { +impl IntoIterator for BinaryHeap { type Item = T; - type IntoIter = IntoIter; + type IntoIter = IntoIter; /// Creates a consuming iterator, that is, one that moves each value out of /// the binary heap in arbitrary order. The binary heap cannot be used @@ -1705,13 +1817,13 @@ impl IntoIterator for BinaryHeap { /// println!("{x}"); /// } /// ``` - fn into_iter(self) -> IntoIter { + fn into_iter(self) -> IntoIter { IntoIter { iter: self.data.into_iter() } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a BinaryHeap { +impl<'a, T, A: Allocator> IntoIterator for &'a BinaryHeap { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -1721,7 +1833,7 @@ impl<'a, T> IntoIterator for &'a BinaryHeap { } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for BinaryHeap { +impl Extend for BinaryHeap { #[inline] fn extend>(&mut self, iter: I) { let guard = RebuildOnDrop { rebuild_from: self.len(), heap: self }; @@ -1740,7 +1852,7 @@ impl Extend for BinaryHeap { } #[stable(feature = "extend_ref", since = "1.2.0")] -impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BinaryHeap { +impl<'a, T: 'a + Ord + Copy, A: Allocator> Extend<&'a T> for BinaryHeap { fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); } diff --git a/library/alloc/src/collections/binary_heap/tests.rs b/library/alloc/src/collections/binary_heap/tests.rs index 500caa35678ab..565a7b7975f38 100644 --- a/library/alloc/src/collections/binary_heap/tests.rs +++ b/library/alloc/src/collections/binary_heap/tests.rs @@ -309,6 +309,7 @@ fn test_drain_sorted() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_drain_sorted_leak() { let d0 = CrashTestDummy::new(0); let d1 = CrashTestDummy::new(1); @@ -475,6 +476,7 @@ fn test_retain() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_retain_catch_unwind() { let mut heap = BinaryHeap::from(vec![3, 1, 2]); @@ -502,6 +504,7 @@ fn test_retain_catch_unwind() { // FIXME: re-enable emscripten once it can unwind again #[test] #[cfg(not(target_os = "emscripten"))] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn panic_safe() { use rand::seq::SliceRandom; use std::cmp; diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 1f8a1ecba6e67..ff908ec12ec86 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1132,7 +1132,7 @@ impl BTreeMap { K: Ord, F: FnMut(&K, &mut V) -> bool, { - self.drain_filter(|k, v| !f(k, v)); + self.extract_if(|k, v| !f(k, v)).for_each(drop); } /// Moves all elements from `other` into `self`, leaving `other` empty. @@ -1395,40 +1395,37 @@ impl BTreeMap { /// The iterator also lets you mutate the value of each element in the /// closure, regardless of whether you choose to keep or remove it. /// - /// If the iterator is only partially consumed or not consumed at all, each - /// of the remaining elements is still subjected to the closure, which may - /// change its value and, by returning `true`, have the element removed and - /// dropped. + /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating + /// or the iteration short-circuits, then the remaining elements will be retained. + /// Use [`retain`] with a negated predicate if you do not need the returned iterator. /// - /// It is unspecified how many more elements will be subjected to the - /// closure if a panic occurs in the closure, or a panic occurs while - /// dropping an element, or if the `DrainFilter` value is leaked. + /// [`retain`]: BTreeMap::retain /// /// # Examples /// /// Splitting a map into even and odd keys, reusing the original map: /// /// ``` - /// #![feature(btree_drain_filter)] + /// #![feature(btree_extract_if)] /// use std::collections::BTreeMap; /// /// let mut map: BTreeMap = (0..8).map(|x| (x, x)).collect(); - /// let evens: BTreeMap<_, _> = map.drain_filter(|k, _v| k % 2 == 0).collect(); + /// let evens: BTreeMap<_, _> = map.extract_if(|k, _v| k % 2 == 0).collect(); /// let odds = map; /// assert_eq!(evens.keys().copied().collect::>(), [0, 2, 4, 6]); /// assert_eq!(odds.keys().copied().collect::>(), [1, 3, 5, 7]); /// ``` - #[unstable(feature = "btree_drain_filter", issue = "70530")] - pub fn drain_filter(&mut self, pred: F) -> DrainFilter<'_, K, V, F, A> + #[unstable(feature = "btree_extract_if", issue = "70530")] + pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, K, V, F, A> where K: Ord, F: FnMut(&K, &mut V) -> bool, { - let (inner, alloc) = self.drain_filter_inner(); - DrainFilter { pred, inner, alloc } + let (inner, alloc) = self.extract_if_inner(); + ExtractIf { pred, inner, alloc } } - pub(super) fn drain_filter_inner(&mut self) -> (DrainFilterInner<'_, K, V>, A) + pub(super) fn extract_if_inner(&mut self) -> (ExtractIfInner<'_, K, V>, A) where K: Ord, { @@ -1436,7 +1433,7 @@ impl BTreeMap { let (root, dormant_root) = DormantMutRef::new(root); let front = root.borrow_mut().first_leaf_edge(); ( - DrainFilterInner { + ExtractIfInner { length: &mut self.length, dormant_root: Some(dormant_root), cur_leaf_edge: Some(front), @@ -1445,7 +1442,7 @@ impl BTreeMap { ) } else { ( - DrainFilterInner { + ExtractIfInner { length: &mut self.length, dormant_root: None, cur_leaf_edge: None, @@ -1899,9 +1896,10 @@ impl Default for Values<'_, K, V> { } } -/// An iterator produced by calling `drain_filter` on BTreeMap. -#[unstable(feature = "btree_drain_filter", issue = "70530")] -pub struct DrainFilter< +/// An iterator produced by calling `extract_if` on BTreeMap. +#[unstable(feature = "btree_extract_if", issue = "70530")] +#[must_use = "iterators are lazy and do nothing unless consumed"] +pub struct ExtractIf< 'a, K, V, @@ -1911,13 +1909,13 @@ pub struct DrainFilter< F: 'a + FnMut(&K, &mut V) -> bool, { pred: F, - inner: DrainFilterInner<'a, K, V>, + inner: ExtractIfInner<'a, K, V>, /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`. alloc: A, } -/// Most of the implementation of DrainFilter are generic over the type -/// of the predicate, thus also serving for BTreeSet::DrainFilter. -pub(super) struct DrainFilterInner<'a, K, V> { +/// Most of the implementation of ExtractIf are generic over the type +/// of the predicate, thus also serving for BTreeSet::ExtractIf. +pub(super) struct ExtractIfInner<'a, K, V> { /// Reference to the length field in the borrowed map, updated live. length: &'a mut usize, /// Buried reference to the root field in the borrowed map. @@ -1929,30 +1927,20 @@ pub(super) struct DrainFilterInner<'a, K, V> { cur_leaf_edge: Option, K, V, marker::Leaf>, marker::Edge>>, } -#[unstable(feature = "btree_drain_filter", issue = "70530")] -impl Drop for DrainFilter<'_, K, V, F, A> -where - F: FnMut(&K, &mut V) -> bool, -{ - fn drop(&mut self) { - self.for_each(drop); - } -} - -#[unstable(feature = "btree_drain_filter", issue = "70530")] -impl fmt::Debug for DrainFilter<'_, K, V, F> +#[unstable(feature = "btree_extract_if", issue = "70530")] +impl fmt::Debug for ExtractIf<'_, K, V, F> where K: fmt::Debug, V: fmt::Debug, F: FnMut(&K, &mut V) -> bool, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("DrainFilter").field(&self.inner.peek()).finish() + f.debug_tuple("ExtractIf").field(&self.inner.peek()).finish() } } -#[unstable(feature = "btree_drain_filter", issue = "70530")] -impl Iterator for DrainFilter<'_, K, V, F, A> +#[unstable(feature = "btree_extract_if", issue = "70530")] +impl Iterator for ExtractIf<'_, K, V, F, A> where F: FnMut(&K, &mut V) -> bool, { @@ -1967,14 +1955,14 @@ where } } -impl<'a, K, V> DrainFilterInner<'a, K, V> { +impl<'a, K, V> ExtractIfInner<'a, K, V> { /// Allow Debug implementations to predict the next element. pub(super) fn peek(&self) -> Option<(&K, &V)> { let edge = self.cur_leaf_edge.as_ref()?; edge.reborrow().next_kv().ok().map(Handle::into_kv) } - /// Implementation of a typical `DrainFilter::next` method, given the predicate. + /// Implementation of a typical `ExtractIf::next` method, given the predicate. pub(super) fn next(&mut self, pred: &mut F, alloc: A) -> Option<(K, V)> where F: FnMut(&K, &mut V) -> bool, @@ -2001,7 +1989,7 @@ impl<'a, K, V> DrainFilterInner<'a, K, V> { None } - /// Implementation of a typical `DrainFilter::size_hint` method. + /// Implementation of a typical `ExtractIf::size_hint` method. pub(super) fn size_hint(&self) -> (usize, Option) { // In most of the btree iterators, `self.length` is the number of elements // yet to be visited. Here, it includes elements that were visited and that @@ -2011,8 +1999,8 @@ impl<'a, K, V> DrainFilterInner<'a, K, V> { } } -#[unstable(feature = "btree_drain_filter", issue = "70530")] -impl FusedIterator for DrainFilter<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {} +#[unstable(feature = "btree_extract_if", issue = "70530")] +impl FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {} #[stable(feature = "btree_range", since = "1.17.0")] impl<'a, K, V> Iterator for Range<'a, K, V> { diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 7ecffe3eef2d5..8681cfcd61757 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -941,13 +941,13 @@ fn test_retain() { assert_eq!(map[&6], 60); } -mod test_drain_filter { +mod test_extract_if { use super::*; #[test] fn empty() { let mut map: BTreeMap = BTreeMap::new(); - map.drain_filter(|_, _| unreachable!("there's nothing to decide on")); + map.extract_if(|_, _| unreachable!("there's nothing to decide on")).for_each(drop); assert_eq!(map.height(), None); map.check(); } @@ -957,7 +957,7 @@ mod test_drain_filter { fn consumed_keeping_all() { let pairs = (0..3).map(|i| (i, i)); let mut map = BTreeMap::from_iter(pairs); - assert!(map.drain_filter(|_, _| false).eq(iter::empty())); + assert!(map.extract_if(|_, _| false).eq(iter::empty())); map.check(); } @@ -966,7 +966,7 @@ mod test_drain_filter { fn consumed_removing_all() { let pairs = (0..3).map(|i| (i, i)); let mut map = BTreeMap::from_iter(pairs.clone()); - assert!(map.drain_filter(|_, _| true).eq(pairs)); + assert!(map.extract_if(|_, _| true).eq(pairs)); assert!(map.is_empty()); map.check(); } @@ -977,7 +977,7 @@ mod test_drain_filter { let pairs = (0..3).map(|i| (i, i)); let mut map = BTreeMap::from_iter(pairs); assert!( - map.drain_filter(|_, v| { + map.extract_if(|_, v| { *v += 6; false }) @@ -994,7 +994,7 @@ mod test_drain_filter { let pairs = (0..3).map(|i| (i, i)); let mut map = BTreeMap::from_iter(pairs); assert!( - map.drain_filter(|_, v| { + map.extract_if(|_, v| { *v += 6; true }) @@ -1008,7 +1008,7 @@ mod test_drain_filter { fn underfull_keeping_all() { let pairs = (0..3).map(|i| (i, i)); let mut map = BTreeMap::from_iter(pairs); - map.drain_filter(|_, _| false); + map.extract_if(|_, _| false).for_each(drop); assert!(map.keys().copied().eq(0..3)); map.check(); } @@ -1018,7 +1018,7 @@ mod test_drain_filter { let pairs = (0..3).map(|i| (i, i)); for doomed in 0..3 { let mut map = BTreeMap::from_iter(pairs.clone()); - map.drain_filter(|i, _| *i == doomed); + map.extract_if(|i, _| *i == doomed).for_each(drop); assert_eq!(map.len(), 2); map.check(); } @@ -1029,7 +1029,7 @@ mod test_drain_filter { let pairs = (0..3).map(|i| (i, i)); for sacred in 0..3 { let mut map = BTreeMap::from_iter(pairs.clone()); - map.drain_filter(|i, _| *i != sacred); + map.extract_if(|i, _| *i != sacred).for_each(drop); assert!(map.keys().copied().eq(sacred..=sacred)); map.check(); } @@ -1039,7 +1039,7 @@ mod test_drain_filter { fn underfull_removing_all() { let pairs = (0..3).map(|i| (i, i)); let mut map = BTreeMap::from_iter(pairs); - map.drain_filter(|_, _| true); + map.extract_if(|_, _| true).for_each(drop); assert!(map.is_empty()); map.check(); } @@ -1048,7 +1048,7 @@ mod test_drain_filter { fn height_0_keeping_all() { let pairs = (0..node::CAPACITY).map(|i| (i, i)); let mut map = BTreeMap::from_iter(pairs); - map.drain_filter(|_, _| false); + map.extract_if(|_, _| false).for_each(drop); assert!(map.keys().copied().eq(0..node::CAPACITY)); map.check(); } @@ -1058,7 +1058,7 @@ mod test_drain_filter { let pairs = (0..node::CAPACITY).map(|i| (i, i)); for doomed in 0..node::CAPACITY { let mut map = BTreeMap::from_iter(pairs.clone()); - map.drain_filter(|i, _| *i == doomed); + map.extract_if(|i, _| *i == doomed).for_each(drop); assert_eq!(map.len(), node::CAPACITY - 1); map.check(); } @@ -1069,7 +1069,7 @@ mod test_drain_filter { let pairs = (0..node::CAPACITY).map(|i| (i, i)); for sacred in 0..node::CAPACITY { let mut map = BTreeMap::from_iter(pairs.clone()); - map.drain_filter(|i, _| *i != sacred); + map.extract_if(|i, _| *i != sacred).for_each(drop); assert!(map.keys().copied().eq(sacred..=sacred)); map.check(); } @@ -1079,7 +1079,7 @@ mod test_drain_filter { fn height_0_removing_all() { let pairs = (0..node::CAPACITY).map(|i| (i, i)); let mut map = BTreeMap::from_iter(pairs); - map.drain_filter(|_, _| true); + map.extract_if(|_, _| true).for_each(drop); assert!(map.is_empty()); map.check(); } @@ -1087,7 +1087,7 @@ mod test_drain_filter { #[test] fn height_0_keeping_half() { let mut map = BTreeMap::from_iter((0..16).map(|i| (i, i))); - assert_eq!(map.drain_filter(|i, _| *i % 2 == 0).count(), 8); + assert_eq!(map.extract_if(|i, _| *i % 2 == 0).count(), 8); assert_eq!(map.len(), 8); map.check(); } @@ -1096,7 +1096,7 @@ mod test_drain_filter { fn height_1_removing_all() { let pairs = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i)); let mut map = BTreeMap::from_iter(pairs); - map.drain_filter(|_, _| true); + map.extract_if(|_, _| true).for_each(drop); assert!(map.is_empty()); map.check(); } @@ -1106,7 +1106,7 @@ mod test_drain_filter { let pairs = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i)); for doomed in 0..MIN_INSERTS_HEIGHT_1 { let mut map = BTreeMap::from_iter(pairs.clone()); - map.drain_filter(|i, _| *i == doomed); + map.extract_if(|i, _| *i == doomed).for_each(drop); assert_eq!(map.len(), MIN_INSERTS_HEIGHT_1 - 1); map.check(); } @@ -1117,7 +1117,7 @@ mod test_drain_filter { let pairs = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i)); for sacred in 0..MIN_INSERTS_HEIGHT_1 { let mut map = BTreeMap::from_iter(pairs.clone()); - map.drain_filter(|i, _| *i != sacred); + map.extract_if(|i, _| *i != sacred).for_each(drop); assert!(map.keys().copied().eq(sacred..=sacred)); map.check(); } @@ -1128,7 +1128,7 @@ mod test_drain_filter { let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)); for doomed in (0..MIN_INSERTS_HEIGHT_2).step_by(12) { let mut map = BTreeMap::from_iter(pairs.clone()); - map.drain_filter(|i, _| *i == doomed); + map.extract_if(|i, _| *i == doomed).for_each(drop); assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2 - 1); map.check(); } @@ -1139,7 +1139,7 @@ mod test_drain_filter { let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)); for sacred in (0..MIN_INSERTS_HEIGHT_2).step_by(12) { let mut map = BTreeMap::from_iter(pairs.clone()); - map.drain_filter(|i, _| *i != sacred); + map.extract_if(|i, _| *i != sacred).for_each(drop); assert!(map.keys().copied().eq(sacred..=sacred)); map.check(); } @@ -1149,12 +1149,13 @@ mod test_drain_filter { fn height_2_removing_all() { let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)); let mut map = BTreeMap::from_iter(pairs); - map.drain_filter(|_, _| true); + map.extract_if(|_, _| true).for_each(drop); assert!(map.is_empty()); map.check(); } #[test] + #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn drop_panic_leak() { let a = CrashTestDummy::new(0); let b = CrashTestDummy::new(1); @@ -1164,7 +1165,8 @@ mod test_drain_filter { map.insert(b.spawn(Panic::InDrop), ()); map.insert(c.spawn(Panic::Never), ()); - catch_unwind(move || drop(map.drain_filter(|dummy, _| dummy.query(true)))).unwrap_err(); + catch_unwind(move || map.extract_if(|dummy, _| dummy.query(true)).for_each(drop)) + .unwrap_err(); assert_eq!(a.queried(), 1); assert_eq!(b.queried(), 1); @@ -1175,6 +1177,7 @@ mod test_drain_filter { } #[test] + #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn pred_panic_leak() { let a = CrashTestDummy::new(0); let b = CrashTestDummy::new(1); @@ -1184,8 +1187,10 @@ mod test_drain_filter { map.insert(b.spawn(Panic::InQuery), ()); map.insert(c.spawn(Panic::InQuery), ()); - catch_unwind(AssertUnwindSafe(|| drop(map.drain_filter(|dummy, _| dummy.query(true))))) - .unwrap_err(); + catch_unwind(AssertUnwindSafe(|| { + map.extract_if(|dummy, _| dummy.query(true)).for_each(drop) + })) + .unwrap_err(); assert_eq!(a.queried(), 1); assert_eq!(b.queried(), 1); @@ -1201,6 +1206,7 @@ mod test_drain_filter { // Same as above, but attempt to use the iterator again after the panic in the predicate #[test] + #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn pred_panic_reuse() { let a = CrashTestDummy::new(0); let b = CrashTestDummy::new(1); @@ -1211,7 +1217,7 @@ mod test_drain_filter { map.insert(c.spawn(Panic::InQuery), ()); { - let mut it = map.drain_filter(|dummy, _| dummy.query(true)); + let mut it = map.extract_if(|dummy, _| dummy.query(true)); catch_unwind(AssertUnwindSafe(|| while it.next().is_some() {})).unwrap_err(); // Iterator behaviour after a panic is explicitly unspecified, // so this is just the current implementation: @@ -1449,6 +1455,7 @@ fn test_clear() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_clear_drop_panic_leak() { let a = CrashTestDummy::new(0); let b = CrashTestDummy::new(1); @@ -1540,11 +1547,13 @@ fn test_clone_panic_leak(size: usize) { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_clone_panic_leak_height_0() { test_clone_panic_leak(3) } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_clone_panic_leak_height_1() { test_clone_panic_leak(MIN_INSERTS_HEIGHT_1) } @@ -1651,8 +1660,8 @@ fn assert_sync() { v.into_values() } - fn drain_filter(v: &mut BTreeMap) -> impl Sync + '_ { - v.drain_filter(|_, _| false) + fn extract_if(v: &mut BTreeMap) -> impl Sync + '_ { + v.extract_if(|_, _| false) } fn iter(v: &BTreeMap) -> impl Sync + '_ { @@ -1720,8 +1729,8 @@ fn assert_send() { v.into_values() } - fn drain_filter(v: &mut BTreeMap) -> impl Send + '_ { - v.drain_filter(|_, _| false) + fn extract_if(v: &mut BTreeMap) -> impl Send + '_ { + v.extract_if(|_, _| false) } fn iter(v: &BTreeMap) -> impl Send + '_ { @@ -2099,6 +2108,7 @@ create_append_test!(test_append_239, 239); create_append_test!(test_append_1700, 1700); #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_append_drop_leak() { let a = CrashTestDummy::new(0); let b = CrashTestDummy::new(1); @@ -2240,6 +2250,7 @@ fn test_split_off_large_random_sorted() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_into_iter_drop_leak_height_0() { let a = CrashTestDummy::new(0); let b = CrashTestDummy::new(1); @@ -2263,6 +2274,7 @@ fn test_into_iter_drop_leak_height_0() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_into_iter_drop_leak_height_1() { let size = MIN_INSERTS_HEIGHT_1; for panic_point in vec![0, 1, size - 2, size - 1] { diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 940fa30afb80f..c4461040b20d7 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -999,7 +999,7 @@ impl BTreeSet { T: Ord, F: FnMut(&T) -> bool, { - self.drain_filter(|v| !f(v)); + self.extract_if(|v| !f(v)).for_each(drop); } /// Moves all elements from `other` into `self`, leaving `other` empty. @@ -1084,36 +1084,33 @@ impl BTreeSet { /// yielded. If the closure returns `false`, or panics, the element remains /// in the set and will not be yielded. /// - /// If the iterator is only partially consumed or not consumed at all, each - /// of the remaining elements is still subjected to the closure and removed - /// and dropped if it returns `true`. - /// - /// It is unspecified how many more elements will be subjected to the - /// closure if a panic occurs in the closure, or if a panic occurs while - /// dropping an element, or if the `DrainFilter` itself is leaked. + /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating + /// or the iteration short-circuits, then the remaining elements will be retained. + /// Use [`retain`] with a negated predicate if you do not need the returned iterator. /// + /// [`retain`]: BTreeSet::retain /// # Examples /// /// Splitting a set into even and odd values, reusing the original set: /// /// ``` - /// #![feature(btree_drain_filter)] + /// #![feature(btree_extract_if)] /// use std::collections::BTreeSet; /// /// let mut set: BTreeSet = (0..8).collect(); - /// let evens: BTreeSet<_> = set.drain_filter(|v| v % 2 == 0).collect(); + /// let evens: BTreeSet<_> = set.extract_if(|v| v % 2 == 0).collect(); /// let odds = set; /// assert_eq!(evens.into_iter().collect::>(), vec![0, 2, 4, 6]); /// assert_eq!(odds.into_iter().collect::>(), vec![1, 3, 5, 7]); /// ``` - #[unstable(feature = "btree_drain_filter", issue = "70530")] - pub fn drain_filter<'a, F>(&'a mut self, pred: F) -> DrainFilter<'a, T, F, A> + #[unstable(feature = "btree_extract_if", issue = "70530")] + pub fn extract_if<'a, F>(&'a mut self, pred: F) -> ExtractIf<'a, T, F, A> where T: Ord, F: 'a + FnMut(&T) -> bool, { - let (inner, alloc) = self.map.drain_filter_inner(); - DrainFilter { pred, inner, alloc } + let (inner, alloc) = self.map.extract_if_inner(); + ExtractIf { pred, inner, alloc } } /// Gets an iterator that visits the elements in the `BTreeSet` in ascending @@ -1275,9 +1272,10 @@ impl<'a, T, A: Allocator + Clone> IntoIterator for &'a BTreeSet { } } -/// An iterator produced by calling `drain_filter` on BTreeSet. -#[unstable(feature = "btree_drain_filter", issue = "70530")] -pub struct DrainFilter< +/// An iterator produced by calling `extract_if` on BTreeSet. +#[unstable(feature = "btree_extract_if", issue = "70530")] +#[must_use = "iterators are lazy and do nothing unless consumed"] +pub struct ExtractIf< 'a, T, F, @@ -1287,34 +1285,24 @@ pub struct DrainFilter< F: 'a + FnMut(&T) -> bool, { pred: F, - inner: super::map::DrainFilterInner<'a, T, SetValZST>, + inner: super::map::ExtractIfInner<'a, T, SetValZST>, /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`. alloc: A, } -#[unstable(feature = "btree_drain_filter", issue = "70530")] -impl Drop for DrainFilter<'_, T, F, A> -where - F: FnMut(&T) -> bool, -{ - fn drop(&mut self) { - self.for_each(drop); - } -} - -#[unstable(feature = "btree_drain_filter", issue = "70530")] -impl fmt::Debug for DrainFilter<'_, T, F, A> +#[unstable(feature = "btree_extract_if", issue = "70530")] +impl fmt::Debug for ExtractIf<'_, T, F, A> where T: fmt::Debug, F: FnMut(&T) -> bool, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("DrainFilter").field(&self.inner.peek().map(|(k, _)| k)).finish() + f.debug_tuple("ExtractIf").field(&self.inner.peek().map(|(k, _)| k)).finish() } } -#[unstable(feature = "btree_drain_filter", issue = "70530")] -impl<'a, T, F, A: Allocator + Clone> Iterator for DrainFilter<'_, T, F, A> +#[unstable(feature = "btree_extract_if", issue = "70530")] +impl<'a, T, F, A: Allocator + Clone> Iterator for ExtractIf<'_, T, F, A> where F: 'a + FnMut(&T) -> bool, { @@ -1331,11 +1319,8 @@ where } } -#[unstable(feature = "btree_drain_filter", issue = "70530")] -impl FusedIterator for DrainFilter<'_, T, F, A> where - F: FnMut(&T) -> bool -{ -} +#[unstable(feature = "btree_extract_if", issue = "70530")] +impl FusedIterator for ExtractIf<'_, T, F, A> where F: FnMut(&T) -> bool {} #[stable(feature = "rust1", since = "1.0.0")] impl Extend for BTreeSet { diff --git a/library/alloc/src/collections/btree/set/tests.rs b/library/alloc/src/collections/btree/set/tests.rs index a7c839d77ed4c..e05bf0e20036d 100644 --- a/library/alloc/src/collections/btree/set/tests.rs +++ b/library/alloc/src/collections/btree/set/tests.rs @@ -366,18 +366,19 @@ fn test_retain() { } #[test] -fn test_drain_filter() { +fn test_extract_if() { let mut x = BTreeSet::from([1]); let mut y = BTreeSet::from([1]); - x.drain_filter(|_| true); - y.drain_filter(|_| false); + x.extract_if(|_| true).for_each(drop); + y.extract_if(|_| false).for_each(drop); assert_eq!(x.len(), 0); assert_eq!(y.len(), 1); } #[test] -fn test_drain_filter_drop_panic_leak() { +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn test_extract_if_drop_panic_leak() { let a = CrashTestDummy::new(0); let b = CrashTestDummy::new(1); let c = CrashTestDummy::new(2); @@ -386,7 +387,7 @@ fn test_drain_filter_drop_panic_leak() { set.insert(b.spawn(Panic::InDrop)); set.insert(c.spawn(Panic::Never)); - catch_unwind(move || drop(set.drain_filter(|dummy| dummy.query(true)))).ok(); + catch_unwind(move || set.extract_if(|dummy| dummy.query(true)).for_each(drop)).ok(); assert_eq!(a.queried(), 1); assert_eq!(b.queried(), 1); @@ -397,7 +398,8 @@ fn test_drain_filter_drop_panic_leak() { } #[test] -fn test_drain_filter_pred_panic_leak() { +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn test_extract_if_pred_panic_leak() { let a = CrashTestDummy::new(0); let b = CrashTestDummy::new(1); let c = CrashTestDummy::new(2); @@ -406,7 +408,8 @@ fn test_drain_filter_pred_panic_leak() { set.insert(b.spawn(Panic::InQuery)); set.insert(c.spawn(Panic::InQuery)); - catch_unwind(AssertUnwindSafe(|| drop(set.drain_filter(|dummy| dummy.query(true))))).ok(); + catch_unwind(AssertUnwindSafe(|| set.extract_if(|dummy| dummy.query(true)).for_each(drop))) + .ok(); assert_eq!(a.queried(), 1); assert_eq!(b.queried(), 1); @@ -603,8 +606,8 @@ fn assert_sync() { v.range(..) } - fn drain_filter(v: &mut BTreeSet) -> impl Sync + '_ { - v.drain_filter(|_| false) + fn extract_if(v: &mut BTreeSet) -> impl Sync + '_ { + v.extract_if(|_| false) } fn difference(v: &BTreeSet) -> impl Sync + '_ { @@ -642,8 +645,8 @@ fn assert_send() { v.range(..) } - fn drain_filter(v: &mut BTreeSet) -> impl Send + '_ { - v.drain_filter(|_| false) + fn extract_if(v: &mut BTreeSet) -> impl Send + '_ { + v.extract_if(|_| false) } fn difference(v: &BTreeSet) -> impl Send + '_ { diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 4cd34ac2fa74f..052edf453f679 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1030,7 +1030,11 @@ impl LinkedList { /// If the closure returns false, the element will remain in the list and will not be yielded /// by the iterator. /// - /// Note that `drain_filter` lets you mutate every element in the filter closure, regardless of + /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating + /// or the iteration short-circuits, then the remaining elements will be retained. + /// Use `extract_if().for_each(drop)` if you do not need the returned iterator. + /// + /// Note that `extract_if` lets you mutate every element in the filter closure, regardless of /// whether you choose to keep or remove it. /// /// # Examples @@ -1038,20 +1042,20 @@ impl LinkedList { /// Splitting a list into evens and odds, reusing the original list: /// /// ``` - /// #![feature(drain_filter)] + /// #![feature(extract_if)] /// use std::collections::LinkedList; /// /// let mut numbers: LinkedList = LinkedList::new(); /// numbers.extend(&[1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]); /// - /// let evens = numbers.drain_filter(|x| *x % 2 == 0).collect::>(); + /// let evens = numbers.extract_if(|x| *x % 2 == 0).collect::>(); /// let odds = numbers; /// /// assert_eq!(evens.into_iter().collect::>(), vec![2, 4, 6, 8, 14]); /// assert_eq!(odds.into_iter().collect::>(), vec![1, 3, 5, 9, 11, 13, 15]); /// ``` - #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] - pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F, A> + #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] + pub fn extract_if(&mut self, filter: F) -> ExtractIf<'_, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -1059,7 +1063,7 @@ impl LinkedList { let it = self.head; let old_len = self.len; - DrainFilter { list: self, it, pred: filter, idx: 0, old_len } + ExtractIf { list: self, it, pred: filter, idx: 0, old_len } } } @@ -1803,9 +1807,10 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { } } -/// An iterator produced by calling `drain_filter` on LinkedList. -#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -pub struct DrainFilter< +/// An iterator produced by calling `extract_if` on LinkedList. +#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] +#[must_use = "iterators are lazy and do nothing unless consumed"] +pub struct ExtractIf< 'a, T: 'a, F: 'a, @@ -1820,8 +1825,8 @@ pub struct DrainFilter< old_len: usize, } -#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl Iterator for DrainFilter<'_, T, F, A> +#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] +impl Iterator for ExtractIf<'_, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -1849,40 +1854,13 @@ where } } -#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl Drop for DrainFilter<'_, T, F, A> -where - F: FnMut(&mut T) -> bool, -{ - fn drop(&mut self) { - struct DropGuard<'r, 'a, T, F, A: Allocator>(&'r mut DrainFilter<'a, T, F, A>) - where - F: FnMut(&mut T) -> bool; - - impl<'r, 'a, T, F, A: Allocator> Drop for DropGuard<'r, 'a, T, F, A> - where - F: FnMut(&mut T) -> bool, - { - fn drop(&mut self) { - self.0.for_each(drop); - } - } - - while let Some(item) = self.next() { - let guard = DropGuard(self); - drop(item); - mem::forget(guard); - } - } -} - -#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl fmt::Debug for DrainFilter<'_, T, F> +#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] +impl fmt::Debug for ExtractIf<'_, T, F> where F: FnMut(&mut T) -> bool, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("DrainFilter").field(&self.list).finish() + f.debug_tuple("ExtractIf").field(&self.list).finish() } } diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs index 04594d55b6abf..8dcd59d12d927 100644 --- a/library/alloc/src/collections/linked_list/tests.rs +++ b/library/alloc/src/collections/linked_list/tests.rs @@ -540,10 +540,10 @@ fn test_show() { } #[test] -fn drain_filter_test() { +fn extract_if_test() { let mut m: LinkedList = LinkedList::new(); m.extend(&[1, 2, 3, 4, 5, 6]); - let deleted = m.drain_filter(|v| *v < 4).collect::>(); + let deleted = m.extract_if(|v| *v < 4).collect::>(); check_links(&m); @@ -555,7 +555,7 @@ fn drain_filter_test() { fn drain_to_empty_test() { let mut m: LinkedList = LinkedList::new(); m.extend(&[1, 2, 3, 4, 5, 6]); - let deleted = m.drain_filter(|_| true).collect::>(); + let deleted = m.extract_if(|_| true).collect::>(); check_links(&m); @@ -811,11 +811,11 @@ fn test_contains() { } #[test] -fn drain_filter_empty() { +fn extract_if_empty() { let mut list: LinkedList = LinkedList::new(); { - let mut iter = list.drain_filter(|_| true); + let mut iter = list.extract_if(|_| true); assert_eq!(iter.size_hint(), (0, Some(0))); assert_eq!(iter.next(), None); assert_eq!(iter.size_hint(), (0, Some(0))); @@ -828,13 +828,13 @@ fn drain_filter_empty() { } #[test] -fn drain_filter_zst() { +fn extract_if_zst() { let mut list: LinkedList<_> = [(), (), (), (), ()].into_iter().collect(); let initial_len = list.len(); let mut count = 0; { - let mut iter = list.drain_filter(|_| true); + let mut iter = list.extract_if(|_| true); assert_eq!(iter.size_hint(), (0, Some(initial_len))); while let Some(_) = iter.next() { count += 1; @@ -851,14 +851,14 @@ fn drain_filter_zst() { } #[test] -fn drain_filter_false() { +fn extract_if_false() { let mut list: LinkedList<_> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect(); let initial_len = list.len(); let mut count = 0; { - let mut iter = list.drain_filter(|_| false); + let mut iter = list.extract_if(|_| false); assert_eq!(iter.size_hint(), (0, Some(initial_len))); for _ in iter.by_ref() { count += 1; @@ -874,14 +874,14 @@ fn drain_filter_false() { } #[test] -fn drain_filter_true() { +fn extract_if_true() { let mut list: LinkedList<_> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect(); let initial_len = list.len(); let mut count = 0; { - let mut iter = list.drain_filter(|_| true); + let mut iter = list.extract_if(|_| true); assert_eq!(iter.size_hint(), (0, Some(initial_len))); while let Some(_) = iter.next() { count += 1; @@ -898,7 +898,7 @@ fn drain_filter_true() { } #[test] -fn drain_filter_complex() { +fn extract_if_complex() { { // [+xxx++++++xxxxx++++x+x++] let mut list = [ @@ -908,7 +908,7 @@ fn drain_filter_complex() { .into_iter() .collect::>(); - let removed = list.drain_filter(|x| *x % 2 == 0).collect::>(); + let removed = list.extract_if(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); @@ -926,7 +926,7 @@ fn drain_filter_complex() { .into_iter() .collect::>(); - let removed = list.drain_filter(|x| *x % 2 == 0).collect::>(); + let removed = list.extract_if(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); @@ -944,7 +944,7 @@ fn drain_filter_complex() { .into_iter() .collect::>(); - let removed = list.drain_filter(|x| *x % 2 == 0).collect::>(); + let removed = list.extract_if(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); @@ -961,7 +961,7 @@ fn drain_filter_complex() { .into_iter() .collect::>(); - let removed = list.drain_filter(|x| *x % 2 == 0).collect::>(); + let removed = list.extract_if(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]); @@ -975,7 +975,7 @@ fn drain_filter_complex() { .into_iter() .collect::>(); - let removed = list.drain_filter(|x| *x % 2 == 0).collect::>(); + let removed = list.extract_if(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]); @@ -985,7 +985,8 @@ fn drain_filter_complex() { } #[test] -fn drain_filter_drop_panic_leak() { +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn extract_if_drop_panic_leak() { let d0 = CrashTestDummy::new(0); let d1 = CrashTestDummy::new(1); let d2 = CrashTestDummy::new(2); @@ -1004,21 +1005,28 @@ fn drain_filter_drop_panic_leak() { q.push_front(d1.spawn(Panic::InDrop)); q.push_front(d0.spawn(Panic::Never)); - catch_unwind(AssertUnwindSafe(|| drop(q.drain_filter(|_| true)))).unwrap_err(); + catch_unwind(AssertUnwindSafe(|| q.extract_if(|_| true).for_each(drop))).unwrap_err(); assert_eq!(d0.dropped(), 1); assert_eq!(d1.dropped(), 1); + assert_eq!(d2.dropped(), 0); + assert_eq!(d3.dropped(), 0); + assert_eq!(d4.dropped(), 0); + assert_eq!(d5.dropped(), 0); + assert_eq!(d6.dropped(), 0); + assert_eq!(d7.dropped(), 0); + drop(q); assert_eq!(d2.dropped(), 1); assert_eq!(d3.dropped(), 1); assert_eq!(d4.dropped(), 1); assert_eq!(d5.dropped(), 1); assert_eq!(d6.dropped(), 1); assert_eq!(d7.dropped(), 1); - assert!(q.is_empty()); } #[test] -fn drain_filter_pred_panic_leak() { +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn extract_if_pred_panic_leak() { static mut DROPS: i32 = 0; #[derive(Debug)] @@ -1043,7 +1051,7 @@ fn drain_filter_pred_panic_leak() { q.push_front(D(0)); catch_unwind(AssertUnwindSafe(|| { - drop(q.drain_filter(|item| if item.0 >= 2 { panic!() } else { true })) + q.extract_if(|item| if item.0 >= 2 { panic!() } else { true }).for_each(drop) })) .ok(); @@ -1124,6 +1132,7 @@ fn test_drop_clear() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_drop_panic() { static mut DROPS: i32 = 0; diff --git a/library/alloc/src/slice/tests.rs b/library/alloc/src/slice/tests.rs index f674530aaa54c..54bc4e77b16f0 100644 --- a/library/alloc/src/slice/tests.rs +++ b/library/alloc/src/slice/tests.rs @@ -187,6 +187,7 @@ std::thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); #[test] #[cfg_attr(target_os = "emscripten", ignore)] // no threads +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn panic_safe() { panic::update_hook(move |prev, info| { if !SILENCE_PANIC.with(|s| s.get()) { diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 59e3f887b5232..1c6815fa94110 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1853,26 +1853,27 @@ impl String { /// Consumes and leaks the `String`, returning a mutable reference to the contents, /// `&'a mut str`. /// - /// This is mainly useful for data that lives for the remainder of - /// the program's life. Dropping the returned reference will cause a memory - /// leak. + /// The caller has free choice over the returned lifetime, including `'static`. Indeed, + /// this function is ideally used for data that lives for the remainder of the program's life, + /// as dropping the returned reference will cause a memory leak. /// /// It does not reallocate or shrink the `String`, /// so the leaked allocation may include unused capacity that is not part - /// of the returned slice. + /// of the returned slice. If you don't want that, call [`into_boxed_str`], + /// and then [`Box::leak`]. + /// + /// [`into_boxed_str`]: Self::into_boxed_str /// /// # Examples /// /// Simple usage: /// /// ``` - /// #![feature(string_leak)] - /// /// let x = String::from("bucket"); /// let static_ref: &'static mut str = x.leak(); /// assert_eq!(static_ref, "bucket"); /// ``` - #[unstable(feature = "string_leak", issue = "102929")] + #[stable(feature = "string_leak", since = "CURRENT_RUSTC_VERSION")] #[inline] pub fn leak<'a>(self) -> &'a mut str { let slice = self.vec.leak(); diff --git a/library/alloc/src/vec/drain_filter.rs b/library/alloc/src/vec/drain_filter.rs deleted file mode 100644 index 21b0902346206..0000000000000 --- a/library/alloc/src/vec/drain_filter.rs +++ /dev/null @@ -1,197 +0,0 @@ -use crate::alloc::{Allocator, Global}; -use core::mem::{ManuallyDrop, SizedTypeProperties}; -use core::ptr; -use core::slice; - -use super::Vec; - -/// An iterator which uses a closure to determine if an element should be removed. -/// -/// This struct is created by [`Vec::drain_filter`]. -/// See its documentation for more. -/// -/// # Example -/// -/// ``` -/// #![feature(drain_filter)] -/// -/// let mut v = vec![0, 1, 2]; -/// let iter: std::vec::DrainFilter<'_, _, _> = v.drain_filter(|x| *x % 2 == 0); -/// ``` -#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -#[derive(Debug)] -pub struct DrainFilter< - 'a, - T, - F, - #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, -> where - F: FnMut(&mut T) -> bool, -{ - pub(super) vec: &'a mut Vec, - /// The index of the item that will be inspected by the next call to `next`. - pub(super) idx: usize, - /// The number of items that have been drained (removed) thus far. - pub(super) del: usize, - /// The original length of `vec` prior to draining. - pub(super) old_len: usize, - /// The filter test predicate. - pub(super) pred: F, - /// A flag that indicates a panic has occurred in the filter test predicate. - /// This is used as a hint in the drop implementation to prevent consumption - /// of the remainder of the `DrainFilter`. Any unprocessed items will be - /// backshifted in the `vec`, but no further items will be dropped or - /// tested by the filter predicate. - pub(super) panic_flag: bool, -} - -impl DrainFilter<'_, T, F, A> -where - F: FnMut(&mut T) -> bool, -{ - /// Returns a reference to the underlying allocator. - #[unstable(feature = "allocator_api", issue = "32838")] - #[inline] - pub fn allocator(&self) -> &A { - self.vec.allocator() - } - - /// Keep unyielded elements in the source `Vec`. - /// - /// # Examples - /// - /// ``` - /// #![feature(drain_filter)] - /// #![feature(drain_keep_rest)] - /// - /// let mut vec = vec!['a', 'b', 'c']; - /// let mut drain = vec.drain_filter(|_| true); - /// - /// assert_eq!(drain.next().unwrap(), 'a'); - /// - /// // This call keeps 'b' and 'c' in the vec. - /// drain.keep_rest(); - /// - /// // If we wouldn't call `keep_rest()`, - /// // `vec` would be empty. - /// assert_eq!(vec, ['b', 'c']); - /// ``` - #[unstable(feature = "drain_keep_rest", issue = "101122")] - pub fn keep_rest(self) { - // At this moment layout looks like this: - // - // _____________________/-- old_len - // / \ - // [kept] [yielded] [tail] - // \_______/ ^-- idx - // \-- del - // - // Normally `Drop` impl would drop [tail] (via .for_each(drop), ie still calling `pred`) - // - // 1. Move [tail] after [kept] - // 2. Update length of the original vec to `old_len - del` - // a. In case of ZST, this is the only thing we want to do - // 3. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do - let mut this = ManuallyDrop::new(self); - - unsafe { - // ZSTs have no identity, so we don't need to move them around. - if !T::IS_ZST && this.idx < this.old_len && this.del > 0 { - let ptr = this.vec.as_mut_ptr(); - let src = ptr.add(this.idx); - let dst = src.sub(this.del); - let tail_len = this.old_len - this.idx; - src.copy_to(dst, tail_len); - } - - let new_len = this.old_len - this.del; - this.vec.set_len(new_len); - } - } -} - -#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl Iterator for DrainFilter<'_, T, F, A> -where - F: FnMut(&mut T) -> bool, -{ - type Item = T; - - fn next(&mut self) -> Option { - unsafe { - while self.idx < self.old_len { - let i = self.idx; - let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); - self.panic_flag = true; - let drained = (self.pred)(&mut v[i]); - self.panic_flag = false; - // Update the index *after* the predicate is called. If the index - // is updated prior and the predicate panics, the element at this - // index would be leaked. - self.idx += 1; - if drained { - self.del += 1; - return Some(ptr::read(&v[i])); - } else if self.del > 0 { - let del = self.del; - let src: *const T = &v[i]; - let dst: *mut T = &mut v[i - del]; - ptr::copy_nonoverlapping(src, dst, 1); - } - } - None - } - } - - fn size_hint(&self) -> (usize, Option) { - (0, Some(self.old_len - self.idx)) - } -} - -#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl Drop for DrainFilter<'_, T, F, A> -where - F: FnMut(&mut T) -> bool, -{ - fn drop(&mut self) { - struct BackshiftOnDrop<'a, 'b, T, F, A: Allocator> - where - F: FnMut(&mut T) -> bool, - { - drain: &'b mut DrainFilter<'a, T, F, A>, - } - - impl<'a, 'b, T, F, A: Allocator> Drop for BackshiftOnDrop<'a, 'b, T, F, A> - where - F: FnMut(&mut T) -> bool, - { - fn drop(&mut self) { - unsafe { - if self.drain.idx < self.drain.old_len && self.drain.del > 0 { - // This is a pretty messed up state, and there isn't really an - // obviously right thing to do. We don't want to keep trying - // to execute `pred`, so we just backshift all the unprocessed - // elements and tell the vec that they still exist. The backshift - // is required to prevent a double-drop of the last successfully - // drained item prior to a panic in the predicate. - let ptr = self.drain.vec.as_mut_ptr(); - let src = ptr.add(self.drain.idx); - let dst = src.sub(self.drain.del); - let tail_len = self.drain.old_len - self.drain.idx; - src.copy_to(dst, tail_len); - } - self.drain.vec.set_len(self.drain.old_len - self.drain.del); - } - } - } - - let backshift = BackshiftOnDrop { drain: self }; - - // Attempt to consume any remaining elements if the filter predicate - // has not yet panicked. We'll backshift any remaining elements - // whether we've already panicked or if the consumption here panics. - if !backshift.drain.panic_flag { - backshift.drain.for_each(drop); - } - } -} diff --git a/library/alloc/src/vec/extract_if.rs b/library/alloc/src/vec/extract_if.rs new file mode 100644 index 0000000000000..e8e6bd56d21ba --- /dev/null +++ b/library/alloc/src/vec/extract_if.rs @@ -0,0 +1,121 @@ +use crate::alloc::{Allocator, Global}; +use core::ptr; +use core::slice; + +use super::Vec; + +/// An iterator which uses a closure to determine if an element should be removed. +/// +/// This struct is created by [`Vec::extract_if`]. +/// See its documentation for more. +/// +/// # Example +/// +/// ``` +/// #![feature(extract_if)] +/// +/// let mut v = vec![0, 1, 2]; +/// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(|x| *x % 2 == 0); +/// ``` +#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] +#[derive(Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +pub struct ExtractIf< + 'a, + T, + F, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> where + F: FnMut(&mut T) -> bool, +{ + pub(super) vec: &'a mut Vec, + /// The index of the item that will be inspected by the next call to `next`. + pub(super) idx: usize, + /// The number of items that have been drained (removed) thus far. + pub(super) del: usize, + /// The original length of `vec` prior to draining. + pub(super) old_len: usize, + /// The filter test predicate. + pub(super) pred: F, + /// A flag that indicates a panic has occurred in the filter test predicate. + /// This is used as a hint in the drop implementation to prevent consumption + /// of the remainder of the `ExtractIf`. Any unprocessed items will be + /// backshifted in the `vec`, but no further items will be dropped or + /// tested by the filter predicate. + pub(super) panic_flag: bool, +} + +impl ExtractIf<'_, T, F, A> +where + F: FnMut(&mut T) -> bool, +{ + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn allocator(&self) -> &A { + self.vec.allocator() + } +} + +#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] +impl Iterator for ExtractIf<'_, T, F, A> +where + F: FnMut(&mut T) -> bool, +{ + type Item = T; + + fn next(&mut self) -> Option { + unsafe { + while self.idx < self.old_len { + let i = self.idx; + let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); + self.panic_flag = true; + let drained = (self.pred)(&mut v[i]); + self.panic_flag = false; + // Update the index *after* the predicate is called. If the index + // is updated prior and the predicate panics, the element at this + // index would be leaked. + self.idx += 1; + if drained { + self.del += 1; + return Some(ptr::read(&v[i])); + } else if self.del > 0 { + let del = self.del; + let src: *const T = &v[i]; + let dst: *mut T = &mut v[i - del]; + ptr::copy_nonoverlapping(src, dst, 1); + } + } + None + } + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.old_len - self.idx)) + } +} + +#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] +impl Drop for ExtractIf<'_, T, F, A> +where + F: FnMut(&mut T) -> bool, +{ + fn drop(&mut self) { + unsafe { + if self.idx < self.old_len && self.del > 0 { + // This is a pretty messed up state, and there isn't really an + // obviously right thing to do. We don't want to keep trying + // to execute `pred`, so we just backshift all the unprocessed + // elements and tell the vec that they still exist. The backshift + // is required to prevent a double-drop of the last successfully + // drained item prior to a panic in the predicate. + let ptr = self.vec.as_mut_ptr(); + let src = ptr.add(self.idx); + let dst = src.sub(self.del); + let tail_len = self.old_len - self.idx; + src.copy_to(dst, tail_len); + } + self.vec.set_len(self.old_len - self.del); + } + } +} diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index d89cdff8e366c..289bbc7d2effd 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -71,10 +71,10 @@ use crate::boxed::Box; use crate::collections::TryReserveError; use crate::raw_vec::RawVec; -#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -pub use self::drain_filter::DrainFilter; +#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] +pub use self::extract_if::ExtractIf; -mod drain_filter; +mod extract_if; #[cfg(not(no_global_oom_handling))] #[stable(feature = "vec_splice", since = "1.21.0")] @@ -2892,6 +2892,12 @@ impl Vec { /// If the closure returns false, the element will remain in the vector and will not be yielded /// by the iterator. /// + /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating + /// or the iteration short-circuits, then the remaining elements will be retained. + /// Use [`retain`] with a negated predicate if you do not need the returned iterator. + /// + /// [`retain`]: Vec::retain + /// /// Using this method is equivalent to the following code: /// /// ``` @@ -2910,10 +2916,10 @@ impl Vec { /// # assert_eq!(vec, vec![1, 4, 5]); /// ``` /// - /// But `drain_filter` is easier to use. `drain_filter` is also more efficient, + /// But `extract_if` is easier to use. `extract_if` is also more efficient, /// because it can backshift the elements of the array in bulk. /// - /// Note that `drain_filter` also lets you mutate every element in the filter closure, + /// Note that `extract_if` also lets you mutate every element in the filter closure, /// regardless of whether you choose to keep or remove it. /// /// # Examples @@ -2921,17 +2927,17 @@ impl Vec { /// Splitting an array into evens and odds, reusing the original allocation: /// /// ``` - /// #![feature(drain_filter)] + /// #![feature(extract_if)] /// let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]; /// - /// let evens = numbers.drain_filter(|x| *x % 2 == 0).collect::>(); + /// let evens = numbers.extract_if(|x| *x % 2 == 0).collect::>(); /// let odds = numbers; /// /// assert_eq!(evens, vec![2, 4, 6, 8, 14]); /// assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]); /// ``` - #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] - pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F, A> + #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] + pub fn extract_if(&mut self, filter: F) -> ExtractIf<'_, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -2942,7 +2948,7 @@ impl Vec { self.set_len(0); } - DrainFilter { vec: self, idx: 0, del: 0, old_len, pred: filter, panic_flag: false } + ExtractIf { vec: self, idx: 0, del: 0, old_len, pred: filter, panic_flag: false } } } diff --git a/library/alloc/tests/autotraits.rs b/library/alloc/tests/autotraits.rs index 879e32b3fa309..6a8e55bff23d9 100644 --- a/library/alloc/tests/autotraits.rs +++ b/library/alloc/tests/autotraits.rs @@ -55,7 +55,7 @@ fn test_btree_map() { require_send_sync(async { let _v = None::< - alloc::collections::btree_map::DrainFilter< + alloc::collections::btree_map::ExtractIf< '_, &u32, &u32, @@ -149,7 +149,7 @@ fn test_btree_set() { }); require_send_sync(async { - let _v = None:: bool>>; + let _v = None:: bool>>; async {}.await; }); @@ -238,7 +238,7 @@ fn test_linked_list() { /* require_send_sync(async { let _v = - None:: bool>>; + None:: bool>>; async {}.await; }); */ diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 0eca4c9bb07aa..aa7a331b368be 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -1,7 +1,7 @@ #![feature(allocator_api)] #![feature(alloc_layout_extra)] #![feature(assert_matches)] -#![feature(btree_drain_filter)] +#![feature(btree_extract_if)] #![feature(cow_is_borrowed)] #![feature(const_cow_is_borrowed)] #![feature(const_heap)] @@ -10,7 +10,7 @@ #![feature(const_ptr_write)] #![feature(const_try)] #![feature(core_intrinsics)] -#![feature(drain_filter)] +#![feature(extract_if)] #![feature(exact_size_is_empty)] #![feature(linked_list_cursors)] #![feature(map_try_insert)] diff --git a/library/alloc/tests/slice.rs b/library/alloc/tests/slice.rs index 9aa5575ca938b..784839a3ffa42 100644 --- a/library/alloc/tests/slice.rs +++ b/library/alloc/tests/slice.rs @@ -1418,6 +1418,7 @@ fn test_box_slice_clone() { #[test] #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_box_slice_clone_panics() { use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; diff --git a/library/alloc/tests/string.rs b/library/alloc/tests/string.rs index 99d1296a4c925..17d56d491d9a0 100644 --- a/library/alloc/tests/string.rs +++ b/library/alloc/tests/string.rs @@ -394,6 +394,7 @@ fn test_remove_matches() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_retain() { let mut s = String::from("α_β_γ"); diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index cc4c1f1272865..21824c8a17c46 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -314,6 +314,7 @@ fn test_retain_predicate_order() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_retain_pred_panic_with_hole() { let v = (0..5).map(Rc::new).collect::>(); catch_unwind(AssertUnwindSafe(|| { @@ -331,6 +332,7 @@ fn test_retain_pred_panic_with_hole() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_retain_pred_panic_no_hole() { let v = (0..5).map(Rc::new).collect::>(); catch_unwind(AssertUnwindSafe(|| { @@ -346,6 +348,7 @@ fn test_retain_pred_panic_no_hole() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_retain_drop_panic() { struct Wrap(Rc); @@ -806,6 +809,7 @@ fn test_drain_end_overflow() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_drain_leak() { static mut DROPS: i32 = 0; @@ -1038,6 +1042,7 @@ fn test_into_iter_clone() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_into_iter_leak() { static mut DROPS: i32 = 0; @@ -1195,6 +1200,7 @@ fn test_from_iter_specialization_head_tail_drop() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_from_iter_specialization_panic_during_iteration_drops() { let drop_count: Vec<_> = (0..=2).map(|_| Rc::new(())).collect(); let src: Vec<_> = drop_count.iter().cloned().collect(); @@ -1219,6 +1225,7 @@ fn test_from_iter_specialization_panic_during_iteration_drops() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_from_iter_specialization_panic_during_drop_doesnt_leak() { static mut DROP_COUNTER_OLD: [usize; 5] = [0; 5]; static mut DROP_COUNTER_NEW: [usize; 2] = [0; 2]; @@ -1340,11 +1347,11 @@ fn overaligned_allocations() { } #[test] -fn drain_filter_empty() { +fn extract_if_empty() { let mut vec: Vec = vec![]; { - let mut iter = vec.drain_filter(|_| true); + let mut iter = vec.extract_if(|_| true); assert_eq!(iter.size_hint(), (0, Some(0))); assert_eq!(iter.next(), None); assert_eq!(iter.size_hint(), (0, Some(0))); @@ -1356,12 +1363,12 @@ fn drain_filter_empty() { } #[test] -fn drain_filter_zst() { +fn extract_if_zst() { let mut vec = vec![(), (), (), (), ()]; let initial_len = vec.len(); let mut count = 0; { - let mut iter = vec.drain_filter(|_| true); + let mut iter = vec.extract_if(|_| true); assert_eq!(iter.size_hint(), (0, Some(initial_len))); while let Some(_) = iter.next() { count += 1; @@ -1378,13 +1385,13 @@ fn drain_filter_zst() { } #[test] -fn drain_filter_false() { +fn extract_if_false() { let mut vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let initial_len = vec.len(); let mut count = 0; { - let mut iter = vec.drain_filter(|_| false); + let mut iter = vec.extract_if(|_| false); assert_eq!(iter.size_hint(), (0, Some(initial_len))); for _ in iter.by_ref() { count += 1; @@ -1400,13 +1407,13 @@ fn drain_filter_false() { } #[test] -fn drain_filter_true() { +fn extract_if_true() { let mut vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let initial_len = vec.len(); let mut count = 0; { - let mut iter = vec.drain_filter(|_| true); + let mut iter = vec.extract_if(|_| true); assert_eq!(iter.size_hint(), (0, Some(initial_len))); while let Some(_) = iter.next() { count += 1; @@ -1423,7 +1430,7 @@ fn drain_filter_true() { } #[test] -fn drain_filter_complex() { +fn extract_if_complex() { { // [+xxx++++++xxxxx++++x+x++] let mut vec = vec![ @@ -1431,7 +1438,7 @@ fn drain_filter_complex() { 39, ]; - let removed = vec.drain_filter(|x| *x % 2 == 0).collect::>(); + let removed = vec.extract_if(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); @@ -1445,7 +1452,7 @@ fn drain_filter_complex() { 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 39, ]; - let removed = vec.drain_filter(|x| *x % 2 == 0).collect::>(); + let removed = vec.extract_if(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); @@ -1458,7 +1465,7 @@ fn drain_filter_complex() { let mut vec = vec![2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36]; - let removed = vec.drain_filter(|x| *x % 2 == 0).collect::>(); + let removed = vec.extract_if(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); @@ -1470,7 +1477,7 @@ fn drain_filter_complex() { // [xxxxxxxxxx+++++++++++] let mut vec = vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]; - let removed = vec.drain_filter(|x| *x % 2 == 0).collect::>(); + let removed = vec.extract_if(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]); @@ -1482,7 +1489,7 @@ fn drain_filter_complex() { // [+++++++++++xxxxxxxxxx] let mut vec = vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; - let removed = vec.drain_filter(|x| *x % 2 == 0).collect::>(); + let removed = vec.extract_if(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]); @@ -1494,7 +1501,8 @@ fn drain_filter_complex() { // FIXME: re-enable emscripten once it can unwind again #[test] #[cfg(not(target_os = "emscripten"))] -fn drain_filter_consumed_panic() { +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn extract_if_consumed_panic() { use std::rc::Rc; use std::sync::Mutex; @@ -1529,9 +1537,9 @@ fn drain_filter_consumed_panic() { } c.index < 6 }; - let drain = data.drain_filter(filter); + let drain = data.extract_if(filter); - // NOTE: The DrainFilter is explicitly consumed + // NOTE: The ExtractIf is explicitly consumed drain.for_each(drop); }); @@ -1546,7 +1554,8 @@ fn drain_filter_consumed_panic() { // FIXME: Re-enable emscripten once it can catch panics #[test] #[cfg(not(target_os = "emscripten"))] -fn drain_filter_unconsumed_panic() { +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn extract_if_unconsumed_panic() { use std::rc::Rc; use std::sync::Mutex; @@ -1581,9 +1590,9 @@ fn drain_filter_unconsumed_panic() { } c.index < 6 }; - let _drain = data.drain_filter(filter); + let _drain = data.extract_if(filter); - // NOTE: The DrainFilter is dropped without being consumed + // NOTE: The ExtractIf is dropped without being consumed }); let drop_counts = drop_counts.lock().unwrap(); @@ -1595,40 +1604,11 @@ fn drain_filter_unconsumed_panic() { } #[test] -fn drain_filter_unconsumed() { +fn extract_if_unconsumed() { let mut vec = vec![1, 2, 3, 4]; - let drain = vec.drain_filter(|&mut x| x % 2 != 0); + let drain = vec.extract_if(|&mut x| x % 2 != 0); drop(drain); - assert_eq!(vec, [2, 4]); -} - -#[test] -fn test_drain_filter_keep_rest() { - let mut v = vec![0, 1, 2, 3, 4, 5, 6]; - let mut drain = v.drain_filter(|&mut x| x % 2 == 0); - assert_eq!(drain.next(), Some(0)); - assert_eq!(drain.next(), Some(2)); - - drain.keep_rest(); - assert_eq!(v, &[1, 3, 4, 5, 6]); -} - -#[test] -fn test_drain_filter_keep_rest_all() { - let mut v = vec![0, 1, 2, 3, 4, 5, 6]; - v.drain_filter(|_| true).keep_rest(); - assert_eq!(v, &[0, 1, 2, 3, 4, 5, 6]); -} - -#[test] -fn test_drain_filter_keep_rest_none() { - let mut v = vec![0, 1, 2, 3, 4, 5, 6]; - let mut drain = v.drain_filter(|_| true); - - drain.by_ref().for_each(drop); - - drain.keep_rest(); - assert_eq!(v, &[]); + assert_eq!(vec, [1, 2, 3, 4]); } #[test] @@ -2414,6 +2394,7 @@ fn test_vec_dedup() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_vec_dedup_panicking() { #[derive(Debug)] struct Panic<'a> { @@ -2470,6 +2451,7 @@ fn test_vec_dedup_panicking() { // Regression test for issue #82533 #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_extend_from_within_panicking_clone() { struct Panic<'dc> { drop_count: &'dc AtomicU32, diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs index ddc27e34ed994..f6fb1f73e5cf9 100644 --- a/library/alloc/tests/vec_deque.rs +++ b/library/alloc/tests/vec_deque.rs @@ -747,6 +747,7 @@ fn test_drop_clear() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_drop_panic() { static mut DROPS: i32 = 0; @@ -1601,6 +1602,7 @@ fn test_try_rfold_moves_iter() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn truncate_leak() { static mut DROPS: i32 = 0; @@ -1634,6 +1636,7 @@ fn truncate_leak() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_drain_leak() { static mut DROPS: i32 = 0; diff --git a/library/core/src/iter/sources/successors.rs b/library/core/src/iter/sources/successors.rs index 99f058a901a31..6a6cbe905e464 100644 --- a/library/core/src/iter/sources/successors.rs +++ b/library/core/src/iter/sources/successors.rs @@ -22,7 +22,7 @@ where Successors { next: first, succ } } -/// An new iterator where each successive item is computed based on the preceding one. +/// A new iterator where each successive item is computed based on the preceding one. /// /// This `struct` is created by the [`iter::successors()`] function. /// See its documentation for more. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index e753647ff7868..c6f43857887c9 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -106,7 +106,7 @@ impl *mut T { /// with [`cast_mut`] on `*const T` and may have documentation value if used instead of implicit /// coercion. /// - /// [`cast_mut`]: pointer::cast_mut + /// [`cast_mut`]: #method.cast_mut #[stable(feature = "ptr_const_cast", since = "1.65.0")] #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")] #[inline(always)] @@ -117,7 +117,7 @@ impl *mut T { /// Casts a pointer to its raw bits. /// /// This is equivalent to `as usize`, but is more specific to enhance readability. - /// The inverse method is [`from_bits`](pointer#method.from_bits-1). + /// The inverse method is [`from_bits`](#method.from_bits-1). /// /// In particular, `*p as usize` and `p as usize` will both compile for /// pointers to numeric types but do very different things, so using this @@ -153,7 +153,7 @@ impl *mut T { /// Creates a pointer from its raw bits. /// /// This is equivalent to `as *mut T`, but is more specific to enhance readability. - /// The inverse method is [`to_bits`](pointer#method.to_bits-1). + /// The inverse method is [`to_bits`](#method.to_bits-1). /// /// # Examples /// @@ -303,7 +303,7 @@ impl *mut T { /// /// For the mutable counterpart see [`as_mut`]. /// - /// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1 + /// [`as_uninit_ref`]: #method.as_uninit_ref-1 /// [`as_mut`]: #method.as_mut /// /// # Safety @@ -369,7 +369,7 @@ impl *mut T { /// /// For the mutable counterpart see [`as_uninit_mut`]. /// - /// [`as_ref`]: pointer#method.as_ref-1 + /// [`as_ref`]: #method.as_ref-1 /// [`as_uninit_mut`]: #method.as_uninit_mut /// /// # Safety @@ -624,7 +624,7 @@ impl *mut T { /// For the shared counterpart see [`as_ref`]. /// /// [`as_uninit_mut`]: #method.as_uninit_mut - /// [`as_ref`]: pointer#method.as_ref-1 + /// [`as_ref`]: #method.as_ref-1 /// /// # Safety /// @@ -689,7 +689,7 @@ impl *mut T { /// For the shared counterpart see [`as_uninit_ref`]. /// /// [`as_mut`]: #method.as_mut - /// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1 + /// [`as_uninit_ref`]: #method.as_uninit_ref-1 /// /// # Safety /// @@ -779,7 +779,7 @@ impl *mut T { /// /// This function is the inverse of [`offset`]. /// - /// [`offset`]: pointer#method.offset-1 + /// [`offset`]: #method.offset-1 /// /// # Safety /// @@ -2051,7 +2051,7 @@ impl *mut [T] { /// /// For the mutable counterpart see [`as_uninit_slice_mut`]. /// - /// [`as_ref`]: pointer#method.as_ref-1 + /// [`as_ref`]: #method.as_ref-1 /// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut /// /// # Safety diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index c87af35fbc449..5d6e7dcfcee87 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2995,7 +2995,7 @@ impl [T] { /// This reordering has the additional property that any value at position `i < index` will be /// less than or equal to any value at a position `j > index`. Additionally, this reordering is /// unstable (i.e. any number of equal elements may end up at position `index`), in-place - /// (i.e. does not allocate), and *O*(*n*) on average. The worst-case performance is *O*(*n* log *n*). + /// (i.e. does not allocate), and runs in *O*(*n*) time. /// This function is also known as "kth element" in other libraries. /// /// It returns a triplet of the following from the reordered slice: @@ -3045,9 +3045,8 @@ impl [T] { /// This reordering has the additional property that any value at position `i < index` will be /// less than or equal to any value at a position `j > index` using the comparator function. /// Additionally, this reordering is unstable (i.e. any number of equal elements may end up at - /// position `index`), in-place (i.e. does not allocate), and *O*(*n*) on average. - /// The worst-case performance is *O*(*n* log *n*). This function is also known as - /// "kth element" in other libraries. + /// position `index`), in-place (i.e. does not allocate), and runs in *O*(*n*) time. + /// This function is also known as "kth element" in other libraries. /// /// It returns a triplet of the following from /// the slice reordered according to the provided comparator function: the subslice prior to @@ -3101,8 +3100,7 @@ impl [T] { /// This reordering has the additional property that any value at position `i < index` will be /// less than or equal to any value at a position `j > index` using the key extraction function. /// Additionally, this reordering is unstable (i.e. any number of equal elements may end up at - /// position `index`), in-place (i.e. does not allocate), and *O*(*n*) on average. - /// The worst-case performance is *O*(*n* log *n*). + /// position `index`), in-place (i.e. does not allocate), and runs in *O*(*n*) time. /// This function is also known as "kth element" in other libraries. /// /// It returns a triplet of the following from diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index 0869644c040f5..982d7853f6936 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -257,14 +257,8 @@ fn iterator_drops() { assert_eq!(i.get(), 5); } -// This test does not work on targets without panic=unwind support. -// To work around this problem, test is marked is should_panic, so it will -// be automagically skipped on unsuitable targets, such as -// wasm32-unknown-unknown. -// -// It means that we use panic for indicating success. -#[test] -#[should_panic(expected = "test succeeded")] +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn array_default_impl_avoids_leaks_on_panic() { use core::sync::atomic::{AtomicUsize, Ordering::Relaxed}; static COUNTER: AtomicUsize = AtomicUsize::new(0); @@ -296,7 +290,6 @@ fn array_default_impl_avoids_leaks_on_panic() { assert_eq!(*panic_msg, "bomb limit exceeded"); // check that all bombs are successfully dropped assert_eq!(COUNTER.load(Relaxed), 0); - panic!("test succeeded") } #[test] @@ -317,9 +310,8 @@ fn array_map() { assert_eq!(b, [1, 2, 3]); } -// See note on above test for why `should_panic` is used. #[test] -#[should_panic(expected = "test succeeded")] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn array_map_drop_safety() { static DROPPED: AtomicUsize = AtomicUsize::new(0); struct DropCounter; @@ -341,7 +333,6 @@ fn array_map_drop_safety() { }); assert!(success.is_err()); assert_eq!(DROPPED.load(Ordering::SeqCst), num_to_create); - panic!("test succeeded") } #[test] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 4b52894c509da..e6b051838861a 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -21,7 +21,7 @@ libc = { version = "0.2.146", default-features = false, features = ['rustc-dep-o compiler_builtins = { version = "0.1.92" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } -hashbrown = { version = "0.13", default-features = false, features = ['rustc-dep-of-std'] } +hashbrown = { version = "0.14", default-features = false, features = ['rustc-dep-of-std'] } std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = ['rustc-dep-of-std'] } # Dependencies of the `backtrace` crate diff --git a/library/std/build.rs b/library/std/build.rs index 0fb03c8e88af5..d0b379409369f 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -36,6 +36,8 @@ fn main() { || target.contains("nintendo-3ds") || target.contains("vita") || target.contains("nto") + // See src/bootstrap/synthetic_targets.rs + || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok() { // These platforms don't have any special requirements. } else { diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index c722bad2e4f63..f3316d97c5faf 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -623,28 +623,27 @@ impl HashMap { /// If the closure returns false, or panics, the element remains in the map and will not be /// yielded. /// - /// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of + /// Note that `extract_if` lets you mutate every value in the filter closure, regardless of /// whether you choose to keep or remove it. /// - /// If the iterator is only partially consumed or not consumed at all, each of the remaining - /// elements will still be subjected to the closure and removed and dropped if it returns true. + /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating + /// or the iteration short-circuits, then the remaining elements will be retained. + /// Use [`retain`] with a negated predicate if you do not need the returned iterator. /// - /// It is unspecified how many more elements will be subjected to the closure - /// if a panic occurs in the closure, or a panic occurs while dropping an element, - /// or if the `DrainFilter` value is leaked. + /// [`retain`]: HashMap::retain /// /// # Examples /// /// Splitting a map into even and odd keys, reusing the original map: /// /// ``` - /// #![feature(hash_drain_filter)] + /// #![feature(hash_extract_if)] /// use std::collections::HashMap; /// /// let mut map: HashMap = (0..8).map(|x| (x, x)).collect(); - /// let drained: HashMap = map.drain_filter(|k, _v| k % 2 == 0).collect(); + /// let extracted: HashMap = map.extract_if(|k, _v| k % 2 == 0).collect(); /// - /// let mut evens = drained.keys().copied().collect::>(); + /// let mut evens = extracted.keys().copied().collect::>(); /// let mut odds = map.keys().copied().collect::>(); /// evens.sort(); /// odds.sort(); @@ -654,12 +653,12 @@ impl HashMap { /// ``` #[inline] #[rustc_lint_query_instability] - #[unstable(feature = "hash_drain_filter", issue = "59618")] - pub fn drain_filter(&mut self, pred: F) -> DrainFilter<'_, K, V, F> + #[unstable(feature = "hash_extract_if", issue = "59618")] + pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool, { - DrainFilter { base: self.base.drain_filter(pred) } + ExtractIf { base: self.base.extract_if(pred) } } /// Retains only the elements specified by the predicate. @@ -1578,28 +1577,29 @@ impl<'a, K, V> Drain<'a, K, V> { /// A draining, filtering iterator over the entries of a `HashMap`. /// -/// This `struct` is created by the [`drain_filter`] method on [`HashMap`]. +/// This `struct` is created by the [`extract_if`] method on [`HashMap`]. /// -/// [`drain_filter`]: HashMap::drain_filter +/// [`extract_if`]: HashMap::extract_if /// /// # Example /// /// ``` -/// #![feature(hash_drain_filter)] +/// #![feature(hash_extract_if)] /// /// use std::collections::HashMap; /// /// let mut map = HashMap::from([ /// ("a", 1), /// ]); -/// let iter = map.drain_filter(|_k, v| *v % 2 == 0); +/// let iter = map.extract_if(|_k, v| *v % 2 == 0); /// ``` -#[unstable(feature = "hash_drain_filter", issue = "59618")] -pub struct DrainFilter<'a, K, V, F> +#[unstable(feature = "hash_extract_if", issue = "59618")] +#[must_use = "iterators are lazy and do nothing unless consumed"] +pub struct ExtractIf<'a, K, V, F> where F: FnMut(&K, &mut V) -> bool, { - base: base::DrainFilter<'a, K, V, F>, + base: base::ExtractIf<'a, K, V, F>, } /// A mutable iterator over the values of a `HashMap`. @@ -2479,8 +2479,8 @@ where } } -#[unstable(feature = "hash_drain_filter", issue = "59618")] -impl Iterator for DrainFilter<'_, K, V, F> +#[unstable(feature = "hash_extract_if", issue = "59618")] +impl Iterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool, { @@ -2496,16 +2496,16 @@ where } } -#[unstable(feature = "hash_drain_filter", issue = "59618")] -impl FusedIterator for DrainFilter<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {} +#[unstable(feature = "hash_extract_if", issue = "59618")] +impl FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {} -#[unstable(feature = "hash_drain_filter", issue = "59618")] -impl<'a, K, V, F> fmt::Debug for DrainFilter<'a, K, V, F> +#[unstable(feature = "hash_extract_if", issue = "59618")] +impl<'a, K, V, F> fmt::Debug for ExtractIf<'a, K, V, F> where F: FnMut(&K, &mut V) -> bool, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("DrainFilter").finish_non_exhaustive() + f.debug_struct("ExtractIf").finish_non_exhaustive() } } diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs index 6b89518e2e26c..91a3776e7be84 100644 --- a/library/std/src/collections/hash/map/tests.rs +++ b/library/std/src/collections/hash/map/tests.rs @@ -944,7 +944,7 @@ fn test_raw_entry() { } } -mod test_drain_filter { +mod test_extract_if { use super::*; use crate::panic::{catch_unwind, AssertUnwindSafe}; @@ -968,7 +968,7 @@ mod test_drain_filter { #[test] fn empty() { let mut map: HashMap = HashMap::new(); - map.drain_filter(|_, _| unreachable!("there's nothing to decide on")); + map.extract_if(|_, _| unreachable!("there's nothing to decide on")).for_each(drop); assert!(map.is_empty()); } @@ -976,7 +976,7 @@ mod test_drain_filter { fn consuming_nothing() { let pairs = (0..3).map(|i| (i, i)); let mut map: HashMap<_, _> = pairs.collect(); - assert!(map.drain_filter(|_, _| false).eq_sorted(crate::iter::empty())); + assert!(map.extract_if(|_, _| false).eq_sorted(crate::iter::empty())); assert_eq!(map.len(), 3); } @@ -984,7 +984,7 @@ mod test_drain_filter { fn consuming_all() { let pairs = (0..3).map(|i| (i, i)); let mut map: HashMap<_, _> = pairs.clone().collect(); - assert!(map.drain_filter(|_, _| true).eq_sorted(pairs)); + assert!(map.extract_if(|_, _| true).eq_sorted(pairs)); assert!(map.is_empty()); } @@ -993,7 +993,7 @@ mod test_drain_filter { let pairs = (0..3).map(|i| (i, i)); let mut map: HashMap<_, _> = pairs.collect(); assert!( - map.drain_filter(|_, v| { + map.extract_if(|_, v| { *v += 6; false }) @@ -1008,7 +1008,7 @@ mod test_drain_filter { let pairs = (0..3).map(|i| (i, i)); let mut map: HashMap<_, _> = pairs.collect(); assert!( - map.drain_filter(|_, v| { + map.extract_if(|_, v| { *v += 6; true }) @@ -1034,14 +1034,15 @@ mod test_drain_filter { let mut map = (0..3).map(|i| (i, D)).collect::>(); catch_unwind(move || { - drop(map.drain_filter(|_, _| { + map.extract_if(|_, _| { PREDS.fetch_add(1, Ordering::SeqCst); true - })) + }) + .for_each(drop) }) .unwrap_err(); - assert_eq!(PREDS.load(Ordering::SeqCst), 3); + assert_eq!(PREDS.load(Ordering::SeqCst), 2); assert_eq!(DROPS.load(Ordering::SeqCst), 3); } @@ -1060,10 +1061,11 @@ mod test_drain_filter { let mut map = (0..3).map(|i| (i, D)).collect::>(); catch_unwind(AssertUnwindSafe(|| { - drop(map.drain_filter(|_, _| match PREDS.fetch_add(1, Ordering::SeqCst) { + map.extract_if(|_, _| match PREDS.fetch_add(1, Ordering::SeqCst) { 0 => true, _ => panic!(), - })) + }) + .for_each(drop) })) .unwrap_err(); @@ -1088,7 +1090,7 @@ mod test_drain_filter { let mut map = (0..3).map(|i| (i, D)).collect::>(); { - let mut it = map.drain_filter(|_, _| match PREDS.fetch_add(1, Ordering::SeqCst) { + let mut it = map.extract_if(|_, _| match PREDS.fetch_add(1, Ordering::SeqCst) { 0 => true, _ => panic!(), }); diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index ac906e682d5f0..ec59634df363a 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -262,25 +262,24 @@ impl HashSet { /// If the closure returns false, the value will remain in the list and will not be yielded /// by the iterator. /// - /// If the iterator is only partially consumed or not consumed at all, each of the remaining - /// values will still be subjected to the closure and removed and dropped if it returns true. + /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating + /// or the iteration short-circuits, then the remaining elements will be retained. + /// Use [`retain`] with a negated predicate if you do not need the returned iterator. /// - /// It is unspecified how many more values will be subjected to the closure - /// if a panic occurs in the closure, or if a panic occurs while dropping a value, or if the - /// `DrainFilter` itself is leaked. + /// [`retain`]: HashSet::retain /// /// # Examples /// /// Splitting a set into even and odd values, reusing the original set: /// /// ``` - /// #![feature(hash_drain_filter)] + /// #![feature(hash_extract_if)] /// use std::collections::HashSet; /// /// let mut set: HashSet = (0..8).collect(); - /// let drained: HashSet = set.drain_filter(|v| v % 2 == 0).collect(); + /// let extracted: HashSet = set.extract_if(|v| v % 2 == 0).collect(); /// - /// let mut evens = drained.into_iter().collect::>(); + /// let mut evens = extracted.into_iter().collect::>(); /// let mut odds = set.into_iter().collect::>(); /// evens.sort(); /// odds.sort(); @@ -290,12 +289,12 @@ impl HashSet { /// ``` #[inline] #[rustc_lint_query_instability] - #[unstable(feature = "hash_drain_filter", issue = "59618")] - pub fn drain_filter(&mut self, pred: F) -> DrainFilter<'_, T, F> + #[unstable(feature = "hash_extract_if", issue = "59618")] + pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, T, F> where F: FnMut(&T) -> bool, { - DrainFilter { base: self.base.drain_filter(pred) } + ExtractIf { base: self.base.extract_if(pred) } } /// Retains only the elements specified by the predicate. @@ -868,7 +867,9 @@ where /// Returns whether the value was newly inserted. That is: /// /// - If the set did not previously contain this value, `true` is returned. - /// - If the set already contained this value, `false` is returned. + /// - If the set already contained this value, `false` is returned, + /// and the set is not modified: original value is not replaced, + /// and the value passed as argument is dropped. /// /// # Examples /// @@ -1310,27 +1311,27 @@ pub struct Drain<'a, K: 'a> { /// A draining, filtering iterator over the items of a `HashSet`. /// -/// This `struct` is created by the [`drain_filter`] method on [`HashSet`]. +/// This `struct` is created by the [`extract_if`] method on [`HashSet`]. /// -/// [`drain_filter`]: HashSet::drain_filter +/// [`extract_if`]: HashSet::extract_if /// /// # Examples /// /// ``` -/// #![feature(hash_drain_filter)] +/// #![feature(hash_extract_if)] /// /// use std::collections::HashSet; /// /// let mut a = HashSet::from([1, 2, 3]); /// -/// let mut drain_filtered = a.drain_filter(|v| v % 2 == 0); +/// let mut extract_ifed = a.extract_if(|v| v % 2 == 0); /// ``` -#[unstable(feature = "hash_drain_filter", issue = "59618")] -pub struct DrainFilter<'a, K, F> +#[unstable(feature = "hash_extract_if", issue = "59618")] +pub struct ExtractIf<'a, K, F> where F: FnMut(&K) -> bool, { - base: base::DrainFilter<'a, K, F>, + base: base::ExtractIf<'a, K, F>, } /// A lazy iterator producing elements in the intersection of `HashSet`s. @@ -1576,8 +1577,8 @@ impl fmt::Debug for Drain<'_, K> { } } -#[unstable(feature = "hash_drain_filter", issue = "59618")] -impl Iterator for DrainFilter<'_, K, F> +#[unstable(feature = "hash_extract_if", issue = "59618")] +impl Iterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool, { @@ -1593,16 +1594,16 @@ where } } -#[unstable(feature = "hash_drain_filter", issue = "59618")] -impl FusedIterator for DrainFilter<'_, K, F> where F: FnMut(&K) -> bool {} +#[unstable(feature = "hash_extract_if", issue = "59618")] +impl FusedIterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool {} -#[unstable(feature = "hash_drain_filter", issue = "59618")] -impl<'a, K, F> fmt::Debug for DrainFilter<'a, K, F> +#[unstable(feature = "hash_extract_if", issue = "59618")] +impl<'a, K, F> fmt::Debug for ExtractIf<'a, K, F> where F: FnMut(&K) -> bool, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("DrainFilter").finish_non_exhaustive() + f.debug_struct("ExtractIf").finish_non_exhaustive() } } diff --git a/library/std/src/collections/hash/set/tests.rs b/library/std/src/collections/hash/set/tests.rs index 941a0450cc770..e0cd80b44f8e6 100644 --- a/library/std/src/collections/hash/set/tests.rs +++ b/library/std/src/collections/hash/set/tests.rs @@ -3,6 +3,7 @@ use super::HashSet; use crate::panic::{catch_unwind, AssertUnwindSafe}; use crate::sync::atomic::{AtomicU32, Ordering}; +use crate::sync::Arc; #[test] fn test_zero_capacities() { @@ -418,18 +419,18 @@ fn test_retain() { } #[test] -fn test_drain_filter() { +fn test_extract_if() { let mut x: HashSet<_> = [1].iter().copied().collect(); let mut y: HashSet<_> = [1].iter().copied().collect(); - x.drain_filter(|_| true); - y.drain_filter(|_| false); + x.extract_if(|_| true).for_each(drop); + y.extract_if(|_| false).for_each(drop); assert_eq!(x.len(), 0); assert_eq!(y.len(), 1); } #[test] -fn test_drain_filter_drop_panic_leak() { +fn test_extract_if_drop_panic_leak() { static PREDS: AtomicU32 = AtomicU32::new(0); static DROPS: AtomicU32 = AtomicU32::new(0); @@ -446,19 +447,20 @@ fn test_drain_filter_drop_panic_leak() { let mut set = (0..3).map(|i| D(i)).collect::>(); catch_unwind(move || { - drop(set.drain_filter(|_| { + set.extract_if(|_| { PREDS.fetch_add(1, Ordering::SeqCst); true - })) + }) + .for_each(drop) }) .ok(); - assert_eq!(PREDS.load(Ordering::SeqCst), 3); + assert_eq!(PREDS.load(Ordering::SeqCst), 2); assert_eq!(DROPS.load(Ordering::SeqCst), 3); } #[test] -fn test_drain_filter_pred_panic_leak() { +fn test_extract_if_pred_panic_leak() { static PREDS: AtomicU32 = AtomicU32::new(0); static DROPS: AtomicU32 = AtomicU32::new(0); @@ -473,10 +475,11 @@ fn test_drain_filter_pred_panic_leak() { let mut set: HashSet<_> = (0..3).map(|_| D).collect(); catch_unwind(AssertUnwindSafe(|| { - drop(set.drain_filter(|_| match PREDS.fetch_add(1, Ordering::SeqCst) { + set.extract_if(|_| match PREDS.fetch_add(1, Ordering::SeqCst) { 0 => true, _ => panic!(), - })) + }) + .for_each(drop) })) .ok(); @@ -502,3 +505,22 @@ fn const_with_hasher() { const X: HashSet<(), ()> = HashSet::with_hasher(()); assert_eq!(X.len(), 0); } + +#[test] +fn test_insert_does_not_overwrite_the_value() { + let first_value = Arc::new(17); + let second_value = Arc::new(17); + + let mut set = HashSet::new(); + let inserted = set.insert(first_value.clone()); + assert!(inserted); + + let inserted = set.insert(second_value); + assert!(!inserted); + + assert!( + Arc::ptr_eq(set.iter().next().unwrap(), &first_value), + "Insert must not overwrite the value, so the contained value pointer \ + must be the same as first value pointer we inserted" + ); +} diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 408244b2ce9eb..bed90418be116 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -528,7 +528,7 @@ impl f32 { /// The positive difference of two numbers. /// - /// * If `self <= other`: `0:0` + /// * If `self <= other`: `0.0` /// * Else: `self - other` /// /// # Examples diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 6782b861f110b..e72de05ca41ed 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -530,7 +530,7 @@ impl f64 { /// The positive difference of two numbers. /// - /// * If `self <= other`: `0:0` + /// * If `self <= other`: `0.0` /// * Else: `self - other` /// /// # Examples diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index bb577acf769d4..fbdf7f5ecacc1 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -745,7 +745,7 @@ impl OsStr { without modifying the original"] #[inline] pub fn to_str(&self) -> Option<&str> { - self.inner.to_str() + self.inner.to_str().ok() } /// Converts an `OsStr` to a [Cow]<[str]>. @@ -1165,6 +1165,24 @@ impl<'a> From> for OsString { } } +#[stable(feature = "str_tryfrom_osstr_impl", since = "CURRENT_RUSTC_VERSION")] +impl<'a> TryFrom<&'a OsStr> for &'a str { + type Error = crate::str::Utf8Error; + + /// Tries to convert an `&OsStr` to a `&str`. + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// let os_str = OsStr::new("foo"); + /// let as_str = <&str>::try_from(os_str).unwrap(); + /// assert_eq!(as_str, "foo"); + /// ``` + fn try_from(value: &'a OsStr) -> Result { + value.inner.to_str() + } +} + #[stable(feature = "box_default_extra", since = "1.17.0")] impl Default for Box { #[inline] diff --git a/library/std/src/sys/unix/os_str.rs b/library/std/src/sys/unix/os_str.rs index 142fcb9ed0b73..f7333fd5a1fed 100644 --- a/library/std/src/sys/unix/os_str.rs +++ b/library/std/src/sys/unix/os_str.rs @@ -207,8 +207,8 @@ impl Slice { unsafe { Slice::from_os_str_bytes_unchecked(s.as_bytes()) } } - pub fn to_str(&self) -> Option<&str> { - str::from_utf8(&self.inner).ok() + pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> { + str::from_utf8(&self.inner) } pub fn to_string_lossy(&self) -> Cow<'_, str> { diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 07b0610d463fa..5fc6136ba1fc7 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -19,6 +19,7 @@ pub use windows_sys::*; pub type DWORD = c_ulong; pub type NonZeroDWORD = NonZero_c_ulong; pub type LARGE_INTEGER = c_longlong; +#[cfg_attr(target_vendor = "uwp", allow(unused))] pub type LONG = c_long; pub type UINT = c_uint; pub type WCHAR = u16; @@ -267,6 +268,8 @@ pub unsafe fn getaddrinfo( windows_sys::getaddrinfo(node.cast::(), service.cast::(), hints, res) } +cfg_if::cfg_if! { +if #[cfg(not(target_vendor = "uwp"))] { pub unsafe fn NtReadFile( filehandle: BorrowedHandle<'_>, event: HANDLE, @@ -313,6 +316,8 @@ pub unsafe fn NtWriteFile( key.map(|k| k as *const u32).unwrap_or(ptr::null()), ) } +} +} // Functions that aren't available on every version of Windows that we support, // but we still use them and just provide some form of a fallback implementation. @@ -376,4 +381,54 @@ compat_fn_with_fallback! { ) -> NTSTATUS { panic!("keyed events not available") } + + // These functions are available on UWP when lazily loaded. They will fail WACK if loaded statically. + #[cfg(target_vendor = "uwp")] + pub fn NtCreateFile( + filehandle: *mut HANDLE, + desiredaccess: FILE_ACCESS_RIGHTS, + objectattributes: *const OBJECT_ATTRIBUTES, + iostatusblock: *mut IO_STATUS_BLOCK, + allocationsize: *const i64, + fileattributes: FILE_FLAGS_AND_ATTRIBUTES, + shareaccess: FILE_SHARE_MODE, + createdisposition: NTCREATEFILE_CREATE_DISPOSITION, + createoptions: NTCREATEFILE_CREATE_OPTIONS, + eabuffer: *const ::core::ffi::c_void, + ealength: u32 + ) -> NTSTATUS { + STATUS_NOT_IMPLEMENTED + } + #[cfg(target_vendor = "uwp")] + pub fn NtReadFile( + filehandle: BorrowedHandle<'_>, + event: HANDLE, + apcroutine: PIO_APC_ROUTINE, + apccontext: *mut c_void, + iostatusblock: &mut IO_STATUS_BLOCK, + buffer: *mut crate::mem::MaybeUninit, + length: ULONG, + byteoffset: Option<&LARGE_INTEGER>, + key: Option<&ULONG> + ) -> NTSTATUS { + STATUS_NOT_IMPLEMENTED + } + #[cfg(target_vendor = "uwp")] + pub fn NtWriteFile( + filehandle: BorrowedHandle<'_>, + event: HANDLE, + apcroutine: PIO_APC_ROUTINE, + apccontext: *mut c_void, + iostatusblock: &mut IO_STATUS_BLOCK, + buffer: *const u8, + length: ULONG, + byteoffset: Option<&LARGE_INTEGER>, + key: Option<&ULONG> + ) -> NTSTATUS { + STATUS_NOT_IMPLEMENTED + } + #[cfg(target_vendor = "uwp")] + pub fn RtlNtStatusToDosError(Status: NTSTATUS) -> u32 { + Status as u32 + } } diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst index 3e454199f13b1..2cf1ade99ce54 100644 --- a/library/std/src/sys/windows/c/windows_sys.lst +++ b/library/std/src/sys/windows/c/windows_sys.lst @@ -1930,6 +1930,7 @@ Windows.Win32.Foundation.SetLastError Windows.Win32.Foundation.STATUS_DELETE_PENDING Windows.Win32.Foundation.STATUS_END_OF_FILE Windows.Win32.Foundation.STATUS_INVALID_PARAMETER +Windows.Win32.Foundation.STATUS_NOT_IMPLEMENTED Windows.Win32.Foundation.STATUS_PENDING Windows.Win32.Foundation.STATUS_SUCCESS Windows.Win32.Foundation.TRUE diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs index 36a30f6ba5652..a4294f336feca 100644 --- a/library/std/src/sys/windows/c/windows_sys.rs +++ b/library/std/src/sys/windows/c/windows_sys.rs @@ -3888,6 +3888,7 @@ pub type STARTUPINFOW_FLAGS = u32; pub const STATUS_DELETE_PENDING: NTSTATUS = -1073741738i32; pub const STATUS_END_OF_FILE: NTSTATUS = -1073741807i32; pub const STATUS_INVALID_PARAMETER: NTSTATUS = -1073741811i32; +pub const STATUS_NOT_IMPLEMENTED: NTSTATUS = -1073741822i32; pub const STATUS_PENDING: NTSTATUS = 259i32; pub const STATUS_SUCCESS: NTSTATUS = 0i32; pub const STD_ERROR_HANDLE: STD_HANDLE = 4294967284u32; @@ -4274,3 +4275,23 @@ impl ::core::clone::Clone for XSAVE_FORMAT { *self } } +// Begin of ARM32 shim +// The raw content of this file should be processed by `generate-windows-sys` +// to be merged with the generated binding. It is not supposed to be used as +// a normal Rust module. +cfg_if::cfg_if! { +if #[cfg(target_arch = "arm")] { +#[repr(C)] +pub struct WSADATA { + pub wVersion: u16, + pub wHighVersion: u16, + pub szDescription: [u8; 257], + pub szSystemStatus: [u8; 129], + pub iMaxSockets: u16, + pub iMaxUdpDg: u16, + pub lpVendorInfo: PSTR, +} +pub enum CONTEXT {} +} +} +// End of ARM32 shim diff --git a/library/std/src/sys/windows/os_str.rs b/library/std/src/sys/windows/os_str.rs index 611f0d040f0eb..16c4f55c6879a 100644 --- a/library/std/src/sys/windows/os_str.rs +++ b/library/std/src/sys/windows/os_str.rs @@ -166,7 +166,7 @@ impl Slice { unsafe { mem::transmute(Wtf8::from_str(s)) } } - pub fn to_str(&self) -> Option<&str> { + pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> { self.inner.as_str() } diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs index bca4e38d9f62c..5d8fd13785a09 100644 --- a/library/std/src/sys/windows/rand.rs +++ b/library/std/src/sys/windows/rand.rs @@ -1,5 +1,3 @@ -use crate::ffi::c_void; -use crate::io; use crate::mem; use crate::ptr; use crate::sys::c; @@ -25,6 +23,9 @@ pub fn hashmap_random_keys() -> (u64, u64) { #[cfg(not(target_vendor = "uwp"))] #[inline(never)] fn fallback_rng() -> (u64, u64) { + use crate::ffi::c_void; + use crate::io; + let mut v = (0, 0); let ret = unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut c_void, mem::size_of_val(&v) as c::ULONG) diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 31bb0ad25a656..c9d3e13cf0c56 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -626,13 +626,8 @@ impl Wtf8 { /// /// This does not copy the data. #[inline] - pub fn as_str(&self) -> Option<&str> { - // Well-formed WTF-8 is also well-formed UTF-8 - // if and only if it contains no surrogate. - match self.next_surrogate(0) { - None => Some(unsafe { str::from_utf8_unchecked(&self.bytes) }), - Some(_) => None, - } + pub fn as_str(&self) -> Result<&str, str::Utf8Error> { + str::from_utf8(&self.bytes) } /// Creates an owned `Wtf8Buf` from a borrowed `Wtf8`. diff --git a/library/std/src/sys_common/wtf8/tests.rs b/library/std/src/sys_common/wtf8/tests.rs index 1a302d646941b..a07bbe6d7e425 100644 --- a/library/std/src/sys_common/wtf8/tests.rs +++ b/library/std/src/sys_common/wtf8/tests.rs @@ -521,11 +521,11 @@ fn wtf8_code_points() { #[test] fn wtf8_as_str() { - assert_eq!(Wtf8::from_str("").as_str(), Some("")); - assert_eq!(Wtf8::from_str("aé 💩").as_str(), Some("aé 💩")); + assert_eq!(Wtf8::from_str("").as_str(), Ok("")); + assert_eq!(Wtf8::from_str("aé 💩").as_str(), Ok("aé 💩")); let mut string = Wtf8Buf::new(); string.push(CodePoint::from_u32(0xD800).unwrap()); - assert_eq!(string.as_str(), None); + assert!(string.as_str().is_err()); } #[test] diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index d9973185bc45e..1230bb5deed02 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -195,7 +195,7 @@ mod local; cfg_if::cfg_if! { if #[cfg(test)] { - // Avoid duplicating the global state assoicated with thread-locals between this crate and + // Avoid duplicating the global state associated with thread-locals between this crate and // realstd. Miri relies on this. pub use realstd::thread::{local_impl, AccessError, LocalKey}; } else { diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs index c34583e695974..4ef18b14f4cdd 100644 --- a/library/test/src/tests.rs +++ b/library/test/src/tests.rs @@ -154,6 +154,7 @@ pub fn ignored_tests_result_in_ignored() { // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] #[cfg(not(target_os = "emscripten"))] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_should_panic() { fn f() -> Result<(), String> { panic!(); @@ -184,6 +185,7 @@ fn test_should_panic() { // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] #[cfg(not(target_os = "emscripten"))] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_should_panic_good_message() { fn f() -> Result<(), String> { panic!("an error message"); @@ -214,6 +216,7 @@ fn test_should_panic_good_message() { // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] #[cfg(not(target_os = "emscripten"))] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_should_panic_bad_message() { use crate::tests::TrFailedMsg; fn f() -> Result<(), String> { @@ -249,6 +252,7 @@ fn test_should_panic_bad_message() { // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] #[cfg(not(target_os = "emscripten"))] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_should_panic_non_string_message_type() { use crate::tests::TrFailedMsg; use std::any::TypeId; @@ -288,6 +292,7 @@ fn test_should_panic_non_string_message_type() { // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] #[cfg(not(target_os = "emscripten"))] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_should_panic_but_succeeds() { let should_panic_variants = [ShouldPanic::Yes, ShouldPanic::YesWithMessage("error message")]; diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index ea1b34812e5ca..7c8e3536df588 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1649,13 +1649,9 @@ impl<'a> Builder<'a> { self.config.rust_debuginfo_level_tools } }; - if debuginfo_level == 1 { - // Use less debuginfo than the default to save on disk space. - cargo.env(profile_var("DEBUG"), "line-tables-only"); - } else { - cargo.env(profile_var("DEBUG"), debuginfo_level.to_string()); - }; - if self.cc[&target].args().iter().any(|arg| arg == "-gz") { + cargo.env(profile_var("DEBUG"), debuginfo_level.to_string()); + if !self.config.dry_run() && self.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz") + { rustflags.arg("-Clink-arg=-gz"); } cargo.env( diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index db3b69d18c8fc..ade3bfed11f9c 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -89,7 +89,7 @@ fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build { cfg } -pub fn find(build: &mut Build) { +pub fn find(build: &Build) { // For all targets we're going to need a C compiler for building some shims // and such as well as for being a linker for Rust code. let targets = build @@ -100,60 +100,64 @@ pub fn find(build: &mut Build) { .chain(iter::once(build.build)) .collect::>(); for target in targets.into_iter() { - let mut cfg = new_cc_build(build, target); - let config = build.config.target_config.get(&target); - if let Some(cc) = config.and_then(|c| c.cc.as_ref()) { - cfg.compiler(cc); - } else { - set_compiler(&mut cfg, Language::C, target, config, build); - } + find_target(build, target); + } +} - let compiler = cfg.get_compiler(); - let ar = if let ar @ Some(..) = config.and_then(|c| c.ar.clone()) { - ar - } else { - cc2ar(compiler.path(), target) - }; +pub fn find_target(build: &Build, target: TargetSelection) { + let mut cfg = new_cc_build(build, target); + let config = build.config.target_config.get(&target); + if let Some(cc) = config.and_then(|c| c.cc.as_ref()) { + cfg.compiler(cc); + } else { + set_compiler(&mut cfg, Language::C, target, config, build); + } - build.cc.insert(target, compiler.clone()); - let cflags = build.cflags(target, GitRepo::Rustc, CLang::C); + let compiler = cfg.get_compiler(); + let ar = if let ar @ Some(..) = config.and_then(|c| c.ar.clone()) { + ar + } else { + cc2ar(compiler.path(), target) + }; - // If we use llvm-libunwind, we will need a C++ compiler as well for all targets - // We'll need one anyways if the target triple is also a host triple - let mut cfg = new_cc_build(build, target); - cfg.cpp(true); - let cxx_configured = if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) { - cfg.compiler(cxx); - true - } else if build.hosts.contains(&target) || build.build == target { - set_compiler(&mut cfg, Language::CPlusPlus, target, config, build); - true - } else { - // Use an auto-detected compiler (or one configured via `CXX_target_triple` env vars). - cfg.try_get_compiler().is_ok() - }; + build.cc.borrow_mut().insert(target, compiler.clone()); + let cflags = build.cflags(target, GitRepo::Rustc, CLang::C); - // for VxWorks, record CXX compiler which will be used in lib.rs:linker() - if cxx_configured || target.contains("vxworks") { - let compiler = cfg.get_compiler(); - build.cxx.insert(target, compiler); - } + // If we use llvm-libunwind, we will need a C++ compiler as well for all targets + // We'll need one anyways if the target triple is also a host triple + let mut cfg = new_cc_build(build, target); + cfg.cpp(true); + let cxx_configured = if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) { + cfg.compiler(cxx); + true + } else if build.hosts.contains(&target) || build.build == target { + set_compiler(&mut cfg, Language::CPlusPlus, target, config, build); + true + } else { + // Use an auto-detected compiler (or one configured via `CXX_target_triple` env vars). + cfg.try_get_compiler().is_ok() + }; - build.verbose(&format!("CC_{} = {:?}", &target.triple, build.cc(target))); - build.verbose(&format!("CFLAGS_{} = {:?}", &target.triple, cflags)); - if let Ok(cxx) = build.cxx(target) { - let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx); - build.verbose(&format!("CXX_{} = {:?}", &target.triple, cxx)); - build.verbose(&format!("CXXFLAGS_{} = {:?}", &target.triple, cxxflags)); - } - if let Some(ar) = ar { - build.verbose(&format!("AR_{} = {:?}", &target.triple, ar)); - build.ar.insert(target, ar); - } + // for VxWorks, record CXX compiler which will be used in lib.rs:linker() + if cxx_configured || target.contains("vxworks") { + let compiler = cfg.get_compiler(); + build.cxx.borrow_mut().insert(target, compiler); + } - if let Some(ranlib) = config.and_then(|c| c.ranlib.clone()) { - build.ranlib.insert(target, ranlib); - } + build.verbose(&format!("CC_{} = {:?}", &target.triple, build.cc(target))); + build.verbose(&format!("CFLAGS_{} = {:?}", &target.triple, cflags)); + if let Ok(cxx) = build.cxx(target) { + let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx); + build.verbose(&format!("CXX_{} = {:?}", &target.triple, cxx)); + build.verbose(&format!("CXXFLAGS_{} = {:?}", &target.triple, cxxflags)); + } + if let Some(ar) = ar { + build.verbose(&format!("AR_{} = {:?}", &target.triple, ar)); + build.ar.borrow_mut().insert(target, ar); + } + + if let Some(ranlib) = config.and_then(|c| c.ranlib.clone()) { + build.ranlib.borrow_mut().insert(target, ranlib); } } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 72d791b543428..14c3ef79a78f2 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -169,6 +169,11 @@ impl Step for Std { cargo.arg("-p").arg(krate); } + // See src/bootstrap/synthetic_targets.rs + if target.is_synthetic() { + cargo.env("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET", "1"); + } + let _guard = builder.msg( Kind::Build, compiler.stage, @@ -314,7 +319,7 @@ fn copy_self_contained_objects( } } else if target.ends_with("windows-gnu") { for obj in ["crt2.o", "dllcrt2.o"].iter() { - let src = compiler_file(builder, builder.cc(target), target, CLang::C, obj); + let src = compiler_file(builder, &builder.cc(target), target, CLang::C, obj); let target = libdir_self_contained.join(obj); builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained)); @@ -995,8 +1000,13 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect && !target.contains("apple") && !target.contains("solaris") { - let file = - compiler_file(builder, builder.cxx(target).unwrap(), target, CLang::Cxx, "libstdc++.a"); + let file = compiler_file( + builder, + &builder.cxx(target).unwrap(), + target, + CLang::Cxx, + "libstdc++.a", + ); cargo.env("LLVM_STATIC_STDCPP", file); } if builder.llvm_link_shared() { @@ -1267,6 +1277,9 @@ pub fn compiler_file( c: CLang, file: &str, ) -> PathBuf { + if builder.config.dry_run() { + return PathBuf::new(); + } let mut cmd = Command::new(compiler); cmd.args(builder.cflags(target, GitRepo::Rustc, c)); cmd.arg(format!("-print-file-name={}", file)); @@ -1488,6 +1501,10 @@ impl Step for Assemble { // Ensure that `libLLVM.so` ends up in the newly created target directory, // so that tools using `rustc_private` can use it. dist::maybe_install_llvm_target(builder, target_compiler.host, &sysroot); + // Lower stages use `ci-rustc-sysroot`, not stageN + if target_compiler.stage == builder.top_stage { + builder.info(&format!("Creating a sysroot for stage{stage} compiler (use `rustup toolchain link 'name' build/host/stage{stage}`)", stage=target_compiler.stage)); + } return target_compiler; } @@ -1525,11 +1542,18 @@ impl Step for Assemble { let stage = target_compiler.stage; let host = target_compiler.host; - let msg = if build_compiler.host == host { - format!("Assembling stage{} compiler", stage) + let (host_info, dir_name) = if build_compiler.host == host { + ("".into(), "host".into()) } else { - format!("Assembling stage{} compiler ({})", stage, host) + (format!(" ({host})"), host.to_string()) }; + // NOTE: "Creating a sysroot" is somewhat inconsistent with our internal terminology, since + // sysroots can temporarily be empty until we put the compiler inside. However, + // `ensure(Sysroot)` isn't really something that's user facing, so there shouldn't be any + // ambiguity. + let msg = format!( + "Creating a sysroot for stage{stage} compiler{host_info} (use `rustup toolchain link 'name' build/{dir_name}/stage{stage}`)" + ); builder.info(&msg); // Link in all dylibs to the libdir diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index c59df7eecf680..8ee63e561ba78 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -10,7 +10,7 @@ use std::cell::{Cell, RefCell}; use std::cmp; use std::collections::{HashMap, HashSet}; use std::env; -use std::fmt; +use std::fmt::{self, Display}; use std::fs; use std::io::IsTerminal; use std::path::{Path, PathBuf}; @@ -50,6 +50,57 @@ pub enum DryRun { UserSelected, } +#[derive(Copy, Clone, Default)] +pub enum DebuginfoLevel { + #[default] + None, + LineTablesOnly, + Limited, + Full, +} + +// NOTE: can't derive(Deserialize) because the intermediate trip through toml::Value only +// deserializes i64, and derive() only generates visit_u64 +impl<'de> Deserialize<'de> for DebuginfoLevel { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + use serde::de::Error; + + Ok(match Deserialize::deserialize(deserializer)? { + StringOrInt::String("none") | StringOrInt::Int(0) => DebuginfoLevel::None, + StringOrInt::String("line-tables-only") => DebuginfoLevel::LineTablesOnly, + StringOrInt::String("limited") | StringOrInt::Int(1) => DebuginfoLevel::Limited, + StringOrInt::String("full") | StringOrInt::Int(2) => DebuginfoLevel::Full, + StringOrInt::Int(n) => { + let other = serde::de::Unexpected::Signed(n); + return Err(D::Error::invalid_value(other, &"expected 0, 1, or 2")); + } + StringOrInt::String(s) => { + let other = serde::de::Unexpected::Str(s); + return Err(D::Error::invalid_value( + other, + &"expected none, line-tables-only, limited, or full", + )); + } + }) + } +} + +/// Suitable for passing to `-C debuginfo` +impl Display for DebuginfoLevel { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use DebuginfoLevel::*; + f.write_str(match self { + None => "0", + LineTablesOnly => "line-tables-only", + Limited => "1", + Full => "2", + }) + } +} + /// Global configuration for the entire build and/or bootstrap. /// /// This structure is parsed from `config.toml`, and some of the fields are inferred from `git` or build-time parameters. @@ -159,10 +210,10 @@ pub struct Config { pub rust_overflow_checks: bool, pub rust_overflow_checks_std: bool, pub rust_debug_logging: bool, - pub rust_debuginfo_level_rustc: u32, - pub rust_debuginfo_level_std: u32, - pub rust_debuginfo_level_tools: u32, - pub rust_debuginfo_level_tests: u32, + pub rust_debuginfo_level_rustc: DebuginfoLevel, + pub rust_debuginfo_level_std: DebuginfoLevel, + pub rust_debuginfo_level_tools: DebuginfoLevel, + pub rust_debuginfo_level_tests: DebuginfoLevel, pub rust_split_debuginfo: SplitDebuginfo, pub rust_rpath: bool, pub rustc_parallel: bool, @@ -378,6 +429,7 @@ impl std::str::FromStr for RustcLto { pub struct TargetSelection { pub triple: Interned, file: Option>, + synthetic: bool, } /// Newtype over `Vec` so we can implement custom parsing logic @@ -409,7 +461,15 @@ impl TargetSelection { let triple = INTERNER.intern_str(triple); let file = file.map(|f| INTERNER.intern_str(f)); - Self { triple, file } + Self { triple, file, synthetic: false } + } + + pub fn create_synthetic(triple: &str, file: &str) -> Self { + Self { + triple: INTERNER.intern_str(triple), + file: Some(INTERNER.intern_str(file)), + synthetic: true, + } } pub fn rustc_target_arg(&self) -> &str { @@ -427,6 +487,11 @@ impl TargetSelection { pub fn ends_with(&self, needle: &str) -> bool { self.triple.ends_with(needle) } + + // See src/bootstrap/synthetic_targets.rs + pub fn is_synthetic(&self) -> bool { + self.synthetic + } } impl fmt::Display for TargetSelection { @@ -810,6 +875,13 @@ impl Default for StringOrBool { } } +#[derive(Deserialize)] +#[serde(untagged)] +enum StringOrInt<'a> { + String(&'a str), + Int(i64), +} + define_config! { /// TOML representation of how the Rust build is configured. struct Rust { @@ -822,11 +894,11 @@ define_config! { overflow_checks: Option = "overflow-checks", overflow_checks_std: Option = "overflow-checks-std", debug_logging: Option = "debug-logging", - debuginfo_level: Option = "debuginfo-level", - debuginfo_level_rustc: Option = "debuginfo-level-rustc", - debuginfo_level_std: Option = "debuginfo-level-std", - debuginfo_level_tools: Option = "debuginfo-level-tools", - debuginfo_level_tests: Option = "debuginfo-level-tests", + debuginfo_level: Option = "debuginfo-level", + debuginfo_level_rustc: Option = "debuginfo-level-rustc", + debuginfo_level_std: Option = "debuginfo-level-std", + debuginfo_level_tools: Option = "debuginfo-level-tools", + debuginfo_level_tests: Option = "debuginfo-level-tests", split_debuginfo: Option = "split-debuginfo", run_dsymutil: Option = "run-dsymutil", backtrace: Option = "backtrace", @@ -1478,17 +1550,17 @@ impl Config { config.rust_debug_logging = debug_logging.unwrap_or(config.rust_debug_assertions); - let with_defaults = |debuginfo_level_specific: Option| { + let with_defaults = |debuginfo_level_specific: Option<_>| { debuginfo_level_specific.or(debuginfo_level).unwrap_or(if debug == Some(true) { - 1 + DebuginfoLevel::Limited } else { - 0 + DebuginfoLevel::None }) }; config.rust_debuginfo_level_rustc = with_defaults(debuginfo_level_rustc); config.rust_debuginfo_level_std = with_defaults(debuginfo_level_std); config.rust_debuginfo_level_tools = with_defaults(debuginfo_level_tools); - config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(0); + config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(DebuginfoLevel::None); let download_rustc = config.download_rustc_commit.is_some(); // See https://github.com/rust-lang/compiler-team/issues/326 diff --git a/src/bootstrap/defaults/config.tools.toml b/src/bootstrap/defaults/config.tools.toml index 6b6625342a67e..79424f28d27b7 100644 --- a/src/bootstrap/defaults/config.tools.toml +++ b/src/bootstrap/defaults/config.tools.toml @@ -9,6 +9,8 @@ debug-logging = true incremental = true # Download rustc from CI instead of building it from source. # This cuts compile times by almost 60x, but means you can't modify the compiler. +# Using these defaults will download the stage2 compiler (see `download-rustc` +# setting) and the stage2 toolchain should therefore be used for these defaults. download-rustc = "if-unchanged" [build] diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 6a2409a0fbfc6..a34a594f13798 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -170,6 +170,10 @@ fn make_win_dist( target: TargetSelection, builder: &Builder<'_>, ) { + if builder.config.dry_run() { + return; + } + //Ask gcc where it keeps its stuff let mut cmd = Command::new(builder.cc(target)); cmd.arg("-print-search-dirs"); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 7a16189926bf5..d7e77aeb338f6 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -61,6 +61,7 @@ mod run; mod sanity; mod setup; mod suggest; +mod synthetic_targets; mod tarball; mod test; mod tool; @@ -226,10 +227,10 @@ pub struct Build { // Runtime state filled in later on // C/C++ compilers and archiver for all targets - cc: HashMap, - cxx: HashMap, - ar: HashMap, - ranlib: HashMap, + cc: RefCell>, + cxx: RefCell>, + ar: RefCell>, + ranlib: RefCell>, // Miscellaneous // allow bidirectional lookups: both name -> path and path -> name crates: HashMap, Crate>, @@ -451,10 +452,10 @@ impl Build { miri_info, rustfmt_info, in_tree_llvm_info, - cc: HashMap::new(), - cxx: HashMap::new(), - ar: HashMap::new(), - ranlib: HashMap::new(), + cc: RefCell::new(HashMap::new()), + cxx: RefCell::new(HashMap::new()), + ar: RefCell::new(HashMap::new()), + ranlib: RefCell::new(HashMap::new()), crates: HashMap::new(), crate_paths: HashMap::new(), is_sudo, @@ -482,7 +483,7 @@ impl Build { } build.verbose("finding compilers"); - cc_detect::find(&mut build); + cc_detect::find(&build); // When running `setup`, the profile is about to change, so any requirements we have now may // be different on the next invocation. Don't check for them until the next time x.py is // run. This is ok because `setup` never runs any build commands, so it won't fail if commands are missing. @@ -1103,16 +1104,22 @@ impl Build { } /// Returns the path to the C compiler for the target specified. - fn cc(&self, target: TargetSelection) -> &Path { - self.cc[&target].path() + fn cc(&self, target: TargetSelection) -> PathBuf { + if self.config.dry_run() { + return PathBuf::new(); + } + self.cc.borrow()[&target].path().into() } /// Returns a list of flags to pass to the C compiler for the target /// specified. fn cflags(&self, target: TargetSelection, which: GitRepo, c: CLang) -> Vec { + if self.config.dry_run() { + return Vec::new(); + } let base = match c { - CLang::C => &self.cc[&target], - CLang::Cxx => &self.cxx[&target], + CLang::C => self.cc.borrow()[&target].clone(), + CLang::Cxx => self.cxx.borrow()[&target].clone(), }; // Filter out -O and /O (the optimization flags) that we picked up from @@ -1153,19 +1160,28 @@ impl Build { } /// Returns the path to the `ar` archive utility for the target specified. - fn ar(&self, target: TargetSelection) -> Option<&Path> { - self.ar.get(&target).map(|p| &**p) + fn ar(&self, target: TargetSelection) -> Option { + if self.config.dry_run() { + return None; + } + self.ar.borrow().get(&target).cloned() } /// Returns the path to the `ranlib` utility for the target specified. - fn ranlib(&self, target: TargetSelection) -> Option<&Path> { - self.ranlib.get(&target).map(|p| &**p) + fn ranlib(&self, target: TargetSelection) -> Option { + if self.config.dry_run() { + return None; + } + self.ranlib.borrow().get(&target).cloned() } /// Returns the path to the C++ compiler for the target specified. - fn cxx(&self, target: TargetSelection) -> Result<&Path, String> { - match self.cxx.get(&target) { - Some(p) => Ok(p.path()), + fn cxx(&self, target: TargetSelection) -> Result { + if self.config.dry_run() { + return Ok(PathBuf::new()); + } + match self.cxx.borrow().get(&target) { + Some(p) => Ok(p.path().into()), None => { Err(format!("target `{}` is not configured as a host, only as a target", target)) } @@ -1173,21 +1189,24 @@ impl Build { } /// Returns the path to the linker for the given target if it needs to be overridden. - fn linker(&self, target: TargetSelection) -> Option<&Path> { - if let Some(linker) = self.config.target_config.get(&target).and_then(|c| c.linker.as_ref()) + fn linker(&self, target: TargetSelection) -> Option { + if self.config.dry_run() { + return Some(PathBuf::new()); + } + if let Some(linker) = self.config.target_config.get(&target).and_then(|c| c.linker.clone()) { Some(linker) } else if target.contains("vxworks") { // need to use CXX compiler as linker to resolve the exception functions // that are only existed in CXX libraries - Some(self.cxx[&target].path()) + Some(self.cxx.borrow()[&target].path().into()) } else if target != self.config.build && util::use_host_linker(target) && !target.contains("msvc") { Some(self.cc(target)) } else if self.config.use_lld && !self.is_fuse_ld_lld(target) && self.build == target { - Some(&self.initial_lld) + Some(self.initial_lld.clone()) } else { None } diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index 19e595650cf9d..4752b1f7ea1e4 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -605,7 +605,7 @@ fn configure_cmake( } let (cc, cxx) = match builder.config.llvm_clang_cl { - Some(ref cl) => (cl.as_ref(), cl.as_ref()), + Some(ref cl) => (cl.into(), cl.into()), None => (builder.cc(target), builder.cxx(target).unwrap()), }; @@ -656,9 +656,9 @@ fn configure_cmake( .define("CMAKE_CXX_COMPILER_LAUNCHER", ccache); } } - cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc)) - .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx)) - .define("CMAKE_ASM_COMPILER", sanitize_cc(cc)); + cfg.define("CMAKE_C_COMPILER", sanitize_cc(&cc)) + .define("CMAKE_CXX_COMPILER", sanitize_cc(&cxx)) + .define("CMAKE_ASM_COMPILER", sanitize_cc(&cc)); } cfg.build_arg("-j").build_arg(builder.jobs().to_string()); @@ -698,7 +698,7 @@ fn configure_cmake( if ar.is_absolute() { // LLVM build breaks if `CMAKE_AR` is a relative path, for some reason it // tries to resolve this path in the LLVM build directory. - cfg.define("CMAKE_AR", sanitize_cc(ar)); + cfg.define("CMAKE_AR", sanitize_cc(&ar)); } } @@ -706,7 +706,7 @@ fn configure_cmake( if ranlib.is_absolute() { // LLVM build breaks if `CMAKE_RANLIB` is a relative path, for some reason it // tries to resolve this path in the LLVM build directory. - cfg.define("CMAKE_RANLIB", sanitize_cc(ranlib)); + cfg.define("CMAKE_RANLIB", sanitize_cc(&ranlib)); } } diff --git a/src/bootstrap/render_tests.rs b/src/bootstrap/render_tests.rs index 06ab820953d08..98a468c883df1 100644 --- a/src/bootstrap/render_tests.rs +++ b/src/bootstrap/render_tests.rs @@ -7,7 +7,7 @@ //! to reimplement all the rendering logic in this module because of that. use crate::builder::Builder; -use std::io::{BufRead, BufReader, Write}; +use std::io::{BufRead, BufReader, Read, Write}; use std::process::{ChildStdout, Command, Stdio}; use std::time::Duration; use termcolor::{Color, ColorSpec, WriteColor}; @@ -20,15 +20,15 @@ pub(crate) fn add_flags_and_try_run_tests(builder: &Builder<'_>, cmd: &mut Comma } cmd.args(&["-Z", "unstable-options", "--format", "json"]); - try_run_tests(builder, cmd) + try_run_tests(builder, cmd, false) } -pub(crate) fn try_run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool { +pub(crate) fn try_run_tests(builder: &Builder<'_>, cmd: &mut Command, stream: bool) -> bool { if builder.config.dry_run() { return true; } - if !run_tests(builder, cmd) { + if !run_tests(builder, cmd, stream) { if builder.fail_fast { crate::detail_exit_macro!(1); } else { @@ -41,7 +41,7 @@ pub(crate) fn try_run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool { } } -fn run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool { +fn run_tests(builder: &Builder<'_>, cmd: &mut Command, stream: bool) -> bool { cmd.stdout(Stdio::piped()); builder.verbose(&format!("running: {cmd:?}")); @@ -50,7 +50,12 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool { // This runs until the stdout of the child is closed, which means the child exited. We don't // run this on another thread since the builder is not Sync. - Renderer::new(process.stdout.take().unwrap(), builder).render_all(); + let renderer = Renderer::new(process.stdout.take().unwrap(), builder); + if stream { + renderer.stream_all(); + } else { + renderer.render_all(); + } let result = process.wait_with_output().unwrap(); if !result.status.success() && builder.is_verbose() { @@ -112,6 +117,23 @@ impl<'a> Renderer<'a> { } } + /// Renders the stdout characters one by one + fn stream_all(mut self) { + let mut buffer = [0; 1]; + loop { + match self.stdout.read(&mut buffer) { + Ok(0) => break, + Ok(_) => { + let mut stdout = std::io::stdout(); + stdout.write_all(&buffer).unwrap(); + let _ = stdout.flush(); + } + Err(err) if err.kind() == std::io::ErrorKind::UnexpectedEof => break, + Err(err) => panic!("failed to read output of test runner: {err}"), + } + } + } + fn render_test_outcome(&mut self, outcome: Outcome<'_>, test: &TestOutcome) { self.executed_tests += 1; diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index c604c63a4dd76..e13f3f0bd5eb7 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -176,6 +176,14 @@ pub fn setup(config: &Config, profile: Profile) { ); } + if profile == Profile::Tools { + eprintln!(); + eprintln!( + "note: the `tools` profile sets up the `stage2` toolchain (use \ + `rustup toolchain link 'name' host/build/stage2` to use rustc)" + ) + } + let path = &config.config.clone().unwrap_or(PathBuf::from("config.toml")); setup_config_toml(path, profile, config); } diff --git a/src/bootstrap/synthetic_targets.rs b/src/bootstrap/synthetic_targets.rs new file mode 100644 index 0000000000000..7eeac9025c9b7 --- /dev/null +++ b/src/bootstrap/synthetic_targets.rs @@ -0,0 +1,82 @@ +//! In some cases, parts of bootstrap need to change part of a target spec just for one or a few +//! steps. Adding these targets to rustc proper would "leak" this implementation detail of +//! bootstrap, and would make it more complex to apply additional changes if the need arises. +//! +//! To address that problem, this module implements support for "synthetic targets". Synthetic +//! targets are custom target specs generated using builtin target specs as their base. You can use +//! one of the target specs already defined in this module, or create new ones by adding a new step +//! that calls create_synthetic_target. + +use crate::builder::{Builder, ShouldRun, Step}; +use crate::config::TargetSelection; +use crate::Compiler; +use std::process::{Command, Stdio}; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub(crate) struct MirOptPanicAbortSyntheticTarget { + pub(crate) compiler: Compiler, + pub(crate) base: TargetSelection, +} + +impl Step for MirOptPanicAbortSyntheticTarget { + type Output = TargetSelection; + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = false; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.never() + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + create_synthetic_target(builder, self.compiler, "miropt-abort", self.base, |spec| { + spec.insert("panic-strategy".into(), "abort".into()); + }) + } +} + +fn create_synthetic_target( + builder: &Builder<'_>, + compiler: Compiler, + suffix: &str, + base: TargetSelection, + customize: impl FnOnce(&mut serde_json::Map), +) -> TargetSelection { + if base.contains("synthetic") { + // This check is not strictly needed, but nothing currently needs recursive synthetic + // targets. If the need arises, removing this in the future *SHOULD* be safe. + panic!("cannot create synthetic targets with other synthetic targets as their base"); + } + + let name = format!("{base}-synthetic-{suffix}"); + let path = builder.out.join("synthetic-target-specs").join(format!("{name}.json")); + std::fs::create_dir_all(path.parent().unwrap()).unwrap(); + + if builder.config.dry_run() { + std::fs::write(&path, b"dry run\n").unwrap(); + return TargetSelection::create_synthetic(&name, path.to_str().unwrap()); + } + + let mut cmd = Command::new(builder.rustc(compiler)); + cmd.arg("--target").arg(base.rustc_target_arg()); + cmd.args(["-Zunstable-options", "--print", "target-spec-json"]); + cmd.stdout(Stdio::piped()); + + let output = cmd.spawn().unwrap().wait_with_output().unwrap(); + if !output.status.success() { + panic!("failed to gather the target spec for {base}"); + } + + let mut spec: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap(); + let spec_map = spec.as_object_mut().unwrap(); + + // The `is-builtin` attribute of a spec needs to be removed, otherwise rustc will complain. + spec_map.remove("is-builtin"); + + customize(spec_map); + + std::fs::write(&path, &serde_json::to_vec_pretty(&spec).unwrap()).unwrap(); + let target = TargetSelection::create_synthetic(&name, path.to_str().unwrap()); + crate::cc_detect::find_target(builder, target); + + target +} diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index f31ba946099f5..13a10b0d3a506 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -23,6 +23,7 @@ use crate::doc::DocumentationFormat; use crate::flags::Subcommand; use crate::llvm; use crate::render_tests::add_flags_and_try_run_tests; +use crate::synthetic_targets::MirOptPanicAbortSyntheticTarget; use crate::tool::{self, SourceType, Tool}; use crate::toolstate::ToolState; use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var, output, t, up_to_date}; @@ -30,6 +31,22 @@ use crate::{envify, CLang, DocTests, GitRepo, Mode}; const ADB_TEST_DIR: &str = "/data/local/tmp/work"; +// mir-opt tests have different variants depending on whether a target is 32bit or 64bit, and +// blessing them requires blessing with each target. To aid developers, when blessing the mir-opt +// test suite the corresponding target of the opposite pointer size is also blessed. +// +// This array serves as the known mappings between 32bit and 64bit targets. If you're developing on +// a target where a target with the opposite pointer size exists, feel free to add it here. +const MIR_OPT_BLESS_TARGET_MAPPING: &[(&str, &str)] = &[ + // (32bit, 64bit) + ("i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu"), + ("i686-unknown-linux-musl", "x86_64-unknown-linux-musl"), + ("i686-pc-windows-msvc", "x86_64-pc-windows-msvc"), + ("i686-pc-windows-gnu", "x86_64-pc-windows-gnu"), + ("i686-apple-darwin", "x86_64-apple-darwin"), + ("i686-apple-darwin", "aarch64-apple-darwin"), +]; + fn try_run(builder: &Builder<'_>, cmd: &mut Command) -> bool { if !builder.fail_fast { if !builder.try_run(cmd) { @@ -1035,7 +1052,7 @@ impl Step for RustdocGUI { } let _time = util::timeit(&builder); - crate::render_tests::try_run_tests(builder, &mut cmd); + crate::render_tests::try_run_tests(builder, &mut cmd, true); } } @@ -1261,8 +1278,6 @@ default_test!(RunPassValgrind { suite: "run-pass-valgrind" }); -default_test!(MirOpt { path: "tests/mir-opt", mode: "mir-opt", suite: "mir-opt" }); - default_test!(Codegen { path: "tests/codegen", mode: "codegen", suite: "codegen" }); default_test!(CodegenUnits { @@ -1299,6 +1314,91 @@ host_test!(RunMakeFullDeps { default_test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly" }); +// For the mir-opt suite we do not use macros, as we need custom behavior when blessing. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct MirOpt { + pub compiler: Compiler, + pub target: TargetSelection, +} + +impl Step for MirOpt { + type Output = (); + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = false; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.suite_path("tests/mir-opt") + } + + fn make_run(run: RunConfig<'_>) { + let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); + run.builder.ensure(MirOpt { compiler, target: run.target }); + } + + fn run(self, builder: &Builder<'_>) { + let run = |target| { + builder.ensure(Compiletest { + compiler: self.compiler, + target: target, + mode: "mir-opt", + suite: "mir-opt", + path: "tests/mir-opt", + compare_mode: None, + }) + }; + + // We use custom logic to bless the mir-opt suite: mir-opt tests have multiple variants + // (32bit vs 64bit, and panic=abort vs panic=unwind), and all of them needs to be blessed. + // When blessing, we try best-effort to also bless the other variants, to aid developers. + if builder.config.cmd.bless() { + let targets = MIR_OPT_BLESS_TARGET_MAPPING + .iter() + .filter(|(target_32bit, target_64bit)| { + *target_32bit == &*self.target.triple || *target_64bit == &*self.target.triple + }) + .next() + .map(|(target_32bit, target_64bit)| { + let target_32bit = TargetSelection::from_user(target_32bit); + let target_64bit = TargetSelection::from_user(target_64bit); + + // Running compiletest requires a C compiler to be available, but it might not + // have been detected by bootstrap if the target we're testing wasn't in the + // --target flags. + if !builder.cc.borrow().contains_key(&target_32bit) { + crate::cc_detect::find_target(builder, target_32bit); + } + if !builder.cc.borrow().contains_key(&target_64bit) { + crate::cc_detect::find_target(builder, target_64bit); + } + + vec![target_32bit, target_64bit] + }) + .unwrap_or_else(|| { + eprintln!( + "\ +Note that not all variants of mir-opt tests are going to be blessed, as no mapping between +a 32bit and a 64bit target was found for {target}. +You can add that mapping by changing MIR_OPT_BLESS_TARGET_MAPPING in src/bootstrap/test.rs", + target = self.target, + ); + vec![self.target] + }); + + for target in targets { + run(target); + + let panic_abort_target = builder.ensure(MirOptPanicAbortSyntheticTarget { + compiler: self.compiler, + base: target, + }); + run(panic_abort_target); + } + } else { + run(self.target); + } + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] struct Compiletest { compiler: Compiler, @@ -1667,7 +1767,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the // Note that if we encounter `PATH` we make sure to append to our own `PATH` // rather than stomp over it. if target.contains("msvc") { - for &(ref k, ref v) in builder.cc[&target].env() { + for &(ref k, ref v) in builder.cc.borrow()[&target].env() { if k != "PATH" { cmd.env(k, v); } @@ -1692,7 +1792,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--adb-path").arg("adb"); cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR); - if target.contains("android") { + if target.contains("android") && !builder.config.dry_run() { // Assume that cc for this target comes from the android sysroot cmd.arg("--android-cross-path") .arg(builder.cc(target).parent().unwrap().parent().unwrap()); @@ -1732,7 +1832,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the suite, mode, &compiler.host, target )); let _time = util::timeit(&builder); - crate::render_tests::try_run_tests(builder, &mut cmd); + crate::render_tests::try_run_tests(builder, &mut cmd, false); if let Some(compare_mode) = compare_mode { cmd.arg("--compare-mode").arg(compare_mode); @@ -1755,7 +1855,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the suite, mode, compare_mode, &compiler.host, target )); let _time = util::timeit(&builder); - crate::render_tests::try_run_tests(builder, &mut cmd); + crate::render_tests::try_run_tests(builder, &mut cmd, false); } } } diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 962cbf758d4d5..96341b69df046 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -855,7 +855,7 @@ impl<'a> Builder<'a> { if compiler.host.contains("msvc") { let curpaths = env::var_os("PATH").unwrap_or_default(); let curpaths = env::split_paths(&curpaths).collect::>(); - for &(ref k, ref v) in self.cc[&compiler.host].env() { + for &(ref k, ref v) in self.cc.borrow()[&compiler.host].env() { if k != "PATH" { continue; } diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index 413b31282f7c9..75aa0c2b2a275 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.16.6 \ No newline at end of file +0.16.7 \ No newline at end of file diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 1041d5026690f..8de638dde4fbf 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -31,8 +31,8 @@ Supported values can also be discovered by running `rustc --print code-models`. ## codegen-units -This flag controls how many code generation units the crate is split into. It -takes an integer greater than 0. +This flag controls the maximum number of code generation units the crate is +split into. It takes an integer greater than 0. When a crate is split into multiple codegen units, LLVM is able to process them in parallel. Increasing parallelism may speed up compile times, but may diff --git a/src/doc/rustdoc/src/how-to-read-rustdoc.md b/src/doc/rustdoc/src/how-to-read-rustdoc.md index ccd77fb17e938..55cce8ab57080 100644 --- a/src/doc/rustdoc/src/how-to-read-rustdoc.md +++ b/src/doc/rustdoc/src/how-to-read-rustdoc.md @@ -105,6 +105,11 @@ will match these queries: But it *does not* match `Result` or `Result>`. +Function signature searches also support arrays and slices. The explicit name +`primitive:slice` and `primitive:array` can be used to match a slice +or array of bytes, while square brackets `[u8]` will match either one. Empty +square brackets, `[]`, will match any slice regardless of what it contains. + ### Shortcuts Pressing `S` while focused elsewhere on the page will move focus to the diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 3aa98da1c803a..870cfa93058aa 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -158,13 +158,13 @@ pub(crate) fn try_inline_glob( .filter_map(|child| child.res.opt_def_id()) .collect(); let mut items = build_module_items(cx, did, visited, inlined_names, Some(&reexports)); - items.drain_filter(|item| { + items.retain(|item| { if let Some(name) = item.name { // If an item with the same type and name already exists, // it takes priority over the inlined stuff. - !inlined_names.insert((item.type_(), name)) + inlined_names.insert((item.type_(), name)) } else { - false + true } }); Some(items) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index baffee0964da9..5bd9389a400af 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -53,15 +53,12 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::Mutability; -use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::middle::stability; -use rustc_middle::ty::{ParamEnv, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_span::{ symbol::{sym, Symbol}, BytePos, FileName, RealFileName, }; -use rustc_trait_selection::traits::ObligationCtxt; use serde::ser::{SerializeMap, SerializeSeq}; use serde::{Serialize, Serializer}; @@ -1115,47 +1112,15 @@ fn render_assoc_items<'a, 'cx: 'a>( containing_item: &'a clean::Item, it: DefId, what: AssocItemRender<'a>, - aliased_type: Option, ) -> impl fmt::Display + 'a + Captures<'cx> { let mut derefs = DefIdSet::default(); derefs.insert(it); display_fn(move |f| { - render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs, aliased_type); + render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs); Ok(()) }) } -/// Check whether `impl_def_id` may apply to *some instantiation* of `item_def_id`. -fn is_valid_impl_for(tcx: TyCtxt<'_>, item_def_id: DefId, impl_def_id: DefId) -> bool { - let infcx = tcx.infer_ctxt().intercrate(true).build(); - let ocx = ObligationCtxt::new(&infcx); - let param_env = ParamEnv::empty(); - - let alias_substs = infcx.fresh_substs_for_item(rustc_span::DUMMY_SP, item_def_id); - let alias_ty = tcx.type_of(item_def_id).subst(tcx, alias_substs); - let alias_bounds = tcx.predicates_of(item_def_id).instantiate(tcx, alias_substs); - - let impl_substs = infcx.fresh_substs_for_item(rustc_span::DUMMY_SP, impl_def_id); - let impl_self_ty = tcx.type_of(impl_def_id).subst(tcx, impl_substs); - let impl_bounds = tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs); - - if ocx.eq(&ObligationCause::dummy(), param_env, impl_self_ty, alias_ty).is_err() { - return false; - } - ocx.register_obligations( - alias_bounds - .iter() - .chain(impl_bounds) - .map(|(p, _)| Obligation::new(tcx, ObligationCause::dummy(), param_env, p)), - ); - - let errors = ocx.select_where_possible(); - errors.is_empty() -} - -// If `aliased_type` is `Some`, it means `it` is a type alias and `aliased_type` is the "actual" -// type aliased behind `it`. It is used to check whether or not the implementation of the aliased -// type can be displayed on the alias doc page. fn render_assoc_items_inner( mut w: &mut dyn fmt::Write, cx: &mut Context<'_>, @@ -1163,28 +1128,12 @@ fn render_assoc_items_inner( it: DefId, what: AssocItemRender<'_>, derefs: &mut DefIdSet, - aliased_type: Option, ) { info!("Documenting associated items of {:?}", containing_item.name); let shared = Rc::clone(&cx.shared); let cache = &shared.cache; - let empty = Vec::new(); - let v = match cache.impls.get(&it) { - Some(v) => v, - None => &empty, - }; - let v2 = match aliased_type { - Some(aliased_type) => cache.impls.get(&aliased_type).unwrap_or(&empty), - None => &empty, - }; - if v.is_empty() && v2.is_empty() { - return; - } - let mut saw_impls = FxHashSet::default(); - let (non_trait, traits): (Vec<_>, _) = - v.iter().chain(v2).partition(|i| i.inner_impl().trait_.is_none()); - let tcx = cx.tcx(); - let is_alias = aliased_type.is_some(); + let Some(v) = cache.impls.get(&it) else { return }; + let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); if !non_trait.is_empty() { let mut tmp_buf = Buffer::html(); let (render_mode, id, class_html) = match what { @@ -1216,12 +1165,6 @@ fn render_assoc_items_inner( }; let mut impls_buf = Buffer::html(); for i in &non_trait { - if !saw_impls.insert(i.def_id()) { - continue; - } - if is_alias && !is_valid_impl_for(tcx, it, i.def_id()) { - continue; - } render_impl( &mut impls_buf, cx, @@ -1250,14 +1193,9 @@ fn render_assoc_items_inner( if !traits.is_empty() { let deref_impl = traits.iter().find(|t| t.trait_did() == cx.tcx().lang_items().deref_trait()); - if let Some(impl_) = deref_impl && - (!is_alias || is_valid_impl_for(tcx, it, impl_.def_id())) - { + if let Some(impl_) = deref_impl { let has_deref_mut = - traits.iter().any(|t| { - t.trait_did() == cx.tcx().lang_items().deref_mut_trait() && - (!is_alias || is_valid_impl_for(tcx, it, t.def_id())) - }); + traits.iter().any(|t| t.trait_did() == cx.tcx().lang_items().deref_mut_trait()); render_deref_methods(&mut w, cx, impl_, containing_item, has_deref_mut, derefs); } @@ -1267,14 +1205,10 @@ fn render_assoc_items_inner( return; } - let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = traits - .into_iter() - .filter(|t| saw_impls.insert(t.def_id())) - .partition(|t| t.inner_impl().kind.is_auto()); - let (blanket_impl, concrete): (Vec<&Impl>, _) = concrete - .into_iter() - .filter(|t| !is_alias || is_valid_impl_for(tcx, it, t.def_id())) - .partition(|t| t.inner_impl().kind.is_blanket()); + let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = + traits.into_iter().partition(|t| t.inner_impl().kind.is_auto()); + let (blanket_impl, concrete): (Vec<&Impl>, _) = + concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket()); render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl); } @@ -1313,10 +1247,10 @@ fn render_deref_methods( return; } } - render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs, None); + render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs); } else if let Some(prim) = target.primitive_type() { if let Some(&did) = cache.primitive_locations.get(&prim) { - render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs, None); + render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs); } } } @@ -2006,8 +1940,6 @@ pub(crate) fn small_url_encode(s: String) -> String { // While the same is not true for hashes, rustdoc only needs to be // consistent with itself when encoding them. st += "+"; - } else if b == b'%' { - st += "%%"; } else { write!(st, "%{:02X}", b).unwrap(); } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 01089ed348bfd..383e3c170881a 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -9,7 +9,6 @@ use rustc_middle::middle::stability; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use std::borrow::Borrow; use std::cell::{RefCell, RefMut}; use std::cmp::Ordering; use std::fmt; @@ -40,6 +39,110 @@ use crate::html::{highlight, static_files}; use askama::Template; use itertools::Itertools; +/// Generates an Askama template struct for rendering items with common methods. +/// +/// Usage: +/// ```ignore (illustrative) +/// item_template!( +/// #[template(path = "", /* additional values */)] +/// /* additional meta items */ +/// struct MyItem<'a, 'cx> { +/// cx: RefCell<&'a mut Context<'cx>>, +/// it: &'a clean::Item, +/// /* additional fields */ +/// }, +/// methods = [ /* method names (comma separated; refer to macro definition of `item_template_methods!()`) */ ] +/// ) +/// ``` +/// +/// NOTE: ensure that the generic lifetimes (`'a`, `'cx`) and +/// required fields (`cx`, `it`) are identical (in terms of order and definition). +macro_rules! item_template { + ( + $(#[$meta:meta])* + struct $name:ident<'a, 'cx> { + cx: RefCell<&'a mut Context<'cx>>, + it: &'a clean::Item, + $($field_name:ident: $field_ty:ty),*, + }, + methods = [$($methods:tt),* $(,)?] + ) => { + #[derive(Template)] + $(#[$meta])* + struct $name<'a, 'cx> { + cx: RefCell<&'a mut Context<'cx>>, + it: &'a clean::Item, + $($field_name: $field_ty),* + } + + impl<'a, 'cx: 'a> ItemTemplate<'a, 'cx> for $name<'a, 'cx> { + fn item_and_mut_cx(&self) -> (&'a clean::Item, RefMut<'_, &'a mut Context<'cx>>) { + (&self.it, self.cx.borrow_mut()) + } + } + + impl<'a, 'cx: 'a> $name<'a, 'cx> { + item_template_methods!($($methods)*); + } + }; +} + +/// Implement common methods for item template structs generated by `item_template!()`. +/// +/// NOTE: this macro is intended to be used only by `item_template!()`. +macro_rules! item_template_methods { + () => {}; + (document $($rest:tt)*) => { + fn document<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { + display_fn(move |f| { + let (item, mut cx) = self.item_and_mut_cx(); + let v = document(*cx, item, None, HeadingOffset::H2); + write!(f, "{v}") + }) + } + item_template_methods!($($rest)*); + }; + (document_type_layout $($rest:tt)*) => { + fn document_type_layout<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { + display_fn(move |f| { + let (item, cx) = self.item_and_mut_cx(); + let def_id = item.item_id.expect_def_id(); + let v = document_type_layout(*cx, def_id); + write!(f, "{v}") + }) + } + item_template_methods!($($rest)*); + }; + (render_attributes_in_pre $($rest:tt)*) => { + fn render_attributes_in_pre<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { + display_fn(move |f| { + let (item, cx) = self.item_and_mut_cx(); + let tcx = cx.tcx(); + let v = render_attributes_in_pre(item, "", tcx); + write!(f, "{v}") + }) + } + item_template_methods!($($rest)*); + }; + (render_assoc_items $($rest:tt)*) => { + fn render_assoc_items<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { + display_fn(move |f| { + let (item, mut cx) = self.item_and_mut_cx(); + let def_id = item.item_id.expect_def_id(); + let v = render_assoc_items(*cx, item, def_id, AssocItemRender::All); + write!(f, "{v}") + }) + } + item_template_methods!($($rest)*); + }; + ($method:ident $($rest:tt)*) => { + compile_error!(concat!("unknown method: ", stringify!($method))); + }; + ($token:tt $($rest:tt)*) => { + compile_error!(concat!("unexpected token: ", stringify!($token))); + }; +} + const ITEM_TABLE_OPEN: &str = "
    "; const ITEM_TABLE_CLOSE: &str = "
"; const ITEM_TABLE_ROW_OPEN: &str = "
  • "; @@ -222,49 +325,6 @@ trait ItemTemplate<'a, 'cx: 'a>: askama::Template + fmt::Display { fn item_and_mut_cx(&self) -> (&'a clean::Item, RefMut<'_, &'a mut Context<'cx>>); } -fn item_template_document<'a: 'b, 'b, 'cx: 'a>( - templ: &'b impl ItemTemplate<'a, 'cx>, -) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { - display_fn(move |f| { - let (item, mut cx) = templ.item_and_mut_cx(); - let v = document(*cx, item, None, HeadingOffset::H2); - write!(f, "{v}") - }) -} - -fn item_template_document_type_layout<'a: 'b, 'b, 'cx: 'a>( - templ: &'b impl ItemTemplate<'a, 'cx>, -) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { - display_fn(move |f| { - let (item, cx) = templ.item_and_mut_cx(); - let def_id = item.item_id.expect_def_id(); - let v = document_type_layout(*cx, def_id); - write!(f, "{v}") - }) -} - -fn item_template_render_attributes_in_pre<'a: 'b, 'b, 'cx: 'a>( - templ: &'b impl ItemTemplate<'a, 'cx>, -) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { - display_fn(move |f| { - let (item, cx) = templ.item_and_mut_cx(); - let tcx = cx.tcx(); - let v = render_attributes_in_pre(item, "", tcx); - write!(f, "{v}") - }) -} - -fn item_template_render_assoc_items<'a: 'b, 'b, 'cx: 'a>( - templ: &'b impl ItemTemplate<'a, 'cx>, -) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { - display_fn(move |f| { - let (item, mut cx) = templ.item_and_mut_cx(); - let def_id = item.item_id.expect_def_id(); - let v = render_assoc_items(*cx, item, def_id, AssocItemRender::All, None); - write!(f, "{v}") - }) -} - fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: &[clean::Item]) { write!(w, "{}", document(cx, item, None, HeadingOffset::H2)); @@ -893,11 +953,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: } // If there are methods directly on this trait object, render them here. - write!( - w, - "{}", - render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All, None) - ); + write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All)); let cloned_shared = Rc::clone(&cx.shared); let cache = &cloned_shared.cache; @@ -1129,12 +1185,8 @@ fn item_trait_alias( // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - write!( - w, - "{}", - render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All, None) - ) - .unwrap(); + write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All)) + .unwrap(); } fn item_opaque_ty( @@ -1162,12 +1214,8 @@ fn item_opaque_ty( // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - write!( - w, - "{}", - render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All, None) - ) - .unwrap(); + write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All)) + .unwrap(); } fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Typedef) { @@ -1191,28 +1239,24 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea write!(w, "{}", document(cx, it, None, HeadingOffset::H2)); let def_id = it.item_id.expect_def_id(); - write!( - w, - "{}", - render_assoc_items(cx, it, def_id, AssocItemRender::All, t.type_.def_id(&cx.cache())) - ); + // Render any items associated directly to this alias, as otherwise they + // won't be visible anywhere in the docs. It would be nice to also show + // associated items from the aliased type (see discussion in #32077), but + // we need #14072 to make sense of the generics. + write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)); write!(w, "{}", document_type_layout(cx, def_id)); } fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Union) { - #[derive(Template)] - #[template(path = "item_union.html")] - struct ItemUnion<'a, 'cx> { - cx: RefCell<&'a mut Context<'cx>>, - it: &'a clean::Item, - s: &'a clean::Union, - } - - impl<'a, 'cx: 'a> ItemTemplate<'a, 'cx> for ItemUnion<'a, 'cx> { - fn item_and_mut_cx(&self) -> (&'a clean::Item, RefMut<'_, &'a mut Context<'cx>>) { - (self.it, self.cx.borrow_mut()) - } - } + item_template!( + #[template(path = "item_union.html")] + struct ItemUnion<'a, 'cx> { + cx: RefCell<&'a mut Context<'cx>>, + it: &'a clean::Item, + s: &'a clean::Union, + }, + methods = [document, document_type_layout, render_attributes_in_pre, render_assoc_items] + ); impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { fn render_union<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { @@ -1222,6 +1266,7 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean: write!(f, "{v}") }) } + fn document_field<'b>( &'b self, field: &'a clean::Item, @@ -1232,10 +1277,12 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean: write!(f, "{v}") }) } + fn stability_field(&self, field: &clean::Item) -> Option { let cx = self.cx.borrow(); field.stability_class(cx.tcx()) } + fn print_ty<'b>( &'b self, ty: &'a clean::Type, @@ -1435,7 +1482,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: write!(w, ""); } let def_id = it.item_id.expect_def_id(); - write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All, None)); + write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)); write!(w, "{}", document_type_layout(cx, def_id)); } @@ -1478,7 +1525,7 @@ fn item_primitive(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Ite let def_id = it.item_id.expect_def_id(); write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) { - write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All, None)).unwrap(); + write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)).unwrap(); } else { // We handle the "reference" primitive type on its own because we only want to list // implementations on generic types. @@ -1583,7 +1630,7 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean } } let def_id = it.item_id.expect_def_id(); - write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All, None)); + write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)); write!(w, "{}", document_type_layout(cx, def_id)); } @@ -1618,12 +1665,8 @@ fn item_foreign_type(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean:: }); write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); - write!( - w, - "{}", - render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All, None) - ) - .unwrap(); + write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All)) + .unwrap(); } fn item_keyword(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) { diff --git a/src/librustdoc/html/static/js/externs.js b/src/librustdoc/html/static/js/externs.js index 8b931f74e600a..f697abd07765a 100644 --- a/src/librustdoc/html/static/js/externs.js +++ b/src/librustdoc/html/static/js/externs.js @@ -53,7 +53,7 @@ let ParsedQuery; * parent: (Object|null|undefined), * path: string, * ty: (Number|null|number), - * type: (Array|null) + * type: FunctionSearchType? * }} */ let Row; @@ -135,7 +135,7 @@ let RawFunctionType; /** * @typedef {{ * inputs: Array, - * outputs: Array, + * output: Array, * }} */ let FunctionSearchType; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 6da51ea0a55e7..a184b7b705e96 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1077,6 +1077,10 @@ function preLoadCss(cssUrl) { -> vec or String, enum:Cow -> bool)", "You can look for items with an exact name by putting double quotes around \ your request: \"string\"", + "Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)", "Look for items inside another one by searching for a path: vec::Vec", ].map(x => "

    " + x + "

    ").join(""); const div_infos = document.createElement("div"); diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 62afe40bb3155..25259971eff2f 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -208,6 +208,46 @@ function initSearch(rawSearchIndex) { let typeNameIdMap; const ALIASES = new Map(); + /** + * Special type name IDs for searching by array. + */ + let typeNameIdOfArray; + /** + * Special type name IDs for searching by slice. + */ + let typeNameIdOfSlice; + /** + * Special type name IDs for searching by both array and slice (`[]` syntax). + */ + let typeNameIdOfArrayOrSlice; + + /** + * Add an item to the type Name->ID map, or, if one already exists, use it. + * Returns the number. If name is "" or null, return -1 (pure generic). + * + * This is effectively string interning, so that function matching can be + * done more quickly. Two types with the same name but different item kinds + * get the same ID. + * + * @param {string} name + * + * @returns {integer} + */ + function buildTypeMapIndex(name) { + + if (name === "" || name === null) { + return -1; + } + + if (typeNameIdMap.has(name)) { + return typeNameIdMap.get(name); + } else { + const id = typeNameIdMap.size; + typeNameIdMap.set(name, id); + return id; + } + } + function isWhitespace(c) { return " \t\n\r".indexOf(c) !== -1; } @@ -217,7 +257,7 @@ function initSearch(rawSearchIndex) { } function isEndCharacter(c) { - return ",>-".indexOf(c) !== -1; + return ",>-]".indexOf(c) !== -1; } function isStopCharacter(c) { @@ -346,6 +386,35 @@ function initSearch(rawSearchIndex) { if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) { throw ["You cannot have more than one element if you use quotes"]; } + const typeFilter = parserState.typeFilter; + parserState.typeFilter = null; + if (name === "!") { + if (typeFilter !== null && typeFilter !== "primitive") { + throw [ + "Invalid search type: primitive never type ", + "!", + " and ", + typeFilter, + " both specified", + ]; + } + if (generics.length !== 0) { + throw [ + "Never type ", + "!", + " does not accept generic parameters", + ]; + } + return { + name: "never", + id: -1, + fullPath: ["never"], + pathWithoutLast: [], + pathLast: "never", + generics: [], + typeFilter: "primitive", + }; + } const pathSegments = name.split("::"); if (pathSegments.length > 1) { for (let i = 0, len = pathSegments.length; i < len; ++i) { @@ -359,6 +428,13 @@ function initSearch(rawSearchIndex) { } throw ["Unexpected ", "::::"]; } + + if (pathSegment === "!") { + pathSegments[i] = "never"; + if (i !== 0) { + throw ["Never type ", "!", " is not associated item"]; + } + } } } // In case we only have something like `

    `, there is no name. @@ -369,8 +445,6 @@ function initSearch(rawSearchIndex) { if (isInGenerics) { parserState.genericsElems += 1; } - const typeFilter = parserState.typeFilter; - parserState.typeFilter = null; return { name: name, id: -1, @@ -419,10 +493,11 @@ function initSearch(rawSearchIndex) { break; } if (foundExclamation !== -1) { - if (start <= (end - 2)) { + if (foundExclamation !== start && + isIdentCharacter(parserState.userQuery[foundExclamation - 1]) + ) { throw ["Cannot have associated items in macros"]; } else { - // if start == end - 1, we got the never type // while the never type has no associated macros, we still // can parse a path like that foundExclamation = -1; @@ -438,7 +513,10 @@ function initSearch(rawSearchIndex) { end = parserState.pos; } // if start == end - 1, we got the never type - if (foundExclamation !== -1 && start <= (end - 2)) { + if (foundExclamation !== -1 && + foundExclamation !== start && + isIdentCharacter(parserState.userQuery[foundExclamation - 1]) + ) { if (parserState.typeFilter === null) { parserState.typeFilter = "macro"; } else if (parserState.typeFilter !== "macro") { @@ -466,35 +544,64 @@ function initSearch(rawSearchIndex) { let start = parserState.pos; let end; - // We handle the strings on their own mostly to make code easier to follow. - if (parserState.userQuery[parserState.pos] === "\"") { - start += 1; - getStringElem(query, parserState, isInGenerics); - end = parserState.pos - 1; + if (parserState.userQuery[parserState.pos] === "[") { + parserState.pos += 1; + getItemsBefore(query, parserState, generics, "]"); + const typeFilter = parserState.typeFilter; + if (typeFilter !== null && typeFilter !== "primitive") { + throw [ + "Invalid search type: primitive ", + "[]", + " and ", + typeFilter, + " both specified", + ]; + } + parserState.typeFilter = null; + parserState.totalElems += 1; + if (isInGenerics) { + parserState.genericsElems += 1; + } + elems.push({ + name: "[]", + id: -1, + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics, + typeFilter: "primitive", + }); } else { - end = getIdentEndPosition(parserState); - } - if (parserState.pos < parserState.length && - parserState.userQuery[parserState.pos] === "<" - ) { - if (start >= end) { - throw ["Found generics without a path"]; + // We handle the strings on their own mostly to make code easier to follow. + if (parserState.userQuery[parserState.pos] === "\"") { + start += 1; + getStringElem(query, parserState, isInGenerics); + end = parserState.pos - 1; + } else { + end = getIdentEndPosition(parserState); } - parserState.pos += 1; - getItemsBefore(query, parserState, generics, ">"); - } - if (start >= end && generics.length === 0) { - return; + if (parserState.pos < parserState.length && + parserState.userQuery[parserState.pos] === "<" + ) { + if (start >= end) { + throw ["Found generics without a path"]; + } + parserState.pos += 1; + getItemsBefore(query, parserState, generics, ">"); + } + if (start >= end && generics.length === 0) { + return; + } + elems.push( + createQueryElement( + query, + parserState, + parserState.userQuery.slice(start, end), + generics, + isInGenerics + ) + ); } - elems.push( - createQueryElement( - query, - parserState, - parserState.userQuery.slice(start, end), - generics, - isInGenerics - ) - ); } /** @@ -518,6 +625,17 @@ function initSearch(rawSearchIndex) { const oldTypeFilter = parserState.typeFilter; parserState.typeFilter = null; + let extra = ""; + if (endChar === ">") { + extra = "<"; + } else if (endChar === "]") { + extra = "["; + } else if (endChar === "") { + extra = "->"; + } else { + extra = endChar; + } + while (parserState.pos < parserState.length) { const c = parserState.userQuery[parserState.pos]; if (c === endChar) { @@ -547,14 +665,6 @@ function initSearch(rawSearchIndex) { foundStopChar = true; continue; } else if (isEndCharacter(c)) { - let extra = ""; - if (endChar === ">") { - extra = "<"; - } else if (endChar === "") { - extra = "->"; - } else { - extra = endChar; - } throw ["Unexpected ", c, " after ", extra]; } if (!foundStopChar) { @@ -581,9 +691,9 @@ function initSearch(rawSearchIndex) { } const posBefore = parserState.pos; start = parserState.pos; - getNextElem(query, parserState, elems, endChar === ">"); + getNextElem(query, parserState, elems, endChar !== ""); if (endChar !== "" && parserState.pos >= parserState.length) { - throw ["Unclosed ", "<"]; + throw ["Unclosed ", extra]; } // This case can be encountered if `getNextElem` encountered a "stop character" right // from the start. For example if you have `,,` or `<>`. In this case, we simply move up @@ -594,7 +704,7 @@ function initSearch(rawSearchIndex) { foundStopChar = false; } if (parserState.pos >= parserState.length && endChar !== "") { - throw ["Unclosed ", "<"]; + throw ["Unclosed ", extra]; } // We are either at the end of the string or on the `endChar` character, let's move forward // in any case. @@ -779,7 +889,8 @@ function initSearch(rawSearchIndex) { * * ident = *(ALPHA / DIGIT / "_") * path = ident *(DOUBLE-COLON ident) [!] - * arg = [type-filter *WS COLON *WS] path [generics] + * slice = OPEN-SQUARE-BRACKET [ nonempty-arg-list ] CLOSE-SQUARE-BRACKET + * arg = [type-filter *WS COLON *WS] (path [generics] / slice) * type-sep = COMMA/WS *(COMMA/WS) * nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep) * generics = OPEN-ANGLE-BRACKET [ nonempty-arg-list ] *(type-sep) @@ -821,6 +932,8 @@ function initSearch(rawSearchIndex) { * * OPEN-ANGLE-BRACKET = "<" * CLOSE-ANGLE-BRACKET = ">" + * OPEN-SQUARE-BRACKET = "[" + * CLOSE-SQUARE-BRACKET = "]" * COLON = ":" * DOUBLE-COLON = "::" * QUOTE = %x22 @@ -1103,98 +1216,182 @@ function initSearch(rawSearchIndex) { } /** - * This function checks if the object (`row`) generics match the given type (`elem`) - * generics. If there are no generics on `row`, `defaultDistance` is returned. + * This function checks generics in search query `queryElem` can all be found in the + * search index (`fnType`), * - * @param {Row} row - The object to check. - * @param {QueryElement} elem - The element from the parsed query. + * @param {FunctionType} fnType - The object to check. + * @param {QueryElement} queryElem - The element from the parsed query. * - * @return {boolean} - Returns true if a match, false otherwise. + * @return {boolean} - Returns true if a match, false otherwise. */ - function checkGenerics(row, elem) { - if (row.generics.length === 0 || elem.generics.length === 0) { - return false; - } - // This function is called if the names match, but we need to make - // sure that all generics match as well. - // + function checkGenerics(fnType, queryElem) { + return unifyFunctionTypes(fnType.generics, queryElem.generics); + } + /** + * This function checks if a list of search query `queryElems` can all be found in the + * search index (`fnTypes`). + * + * @param {Array} fnTypes - The objects to check. + * @param {Array} queryElems - The elements from the parsed query. + * + * @return {boolean} - Returns true if a match, false otherwise. + */ + function unifyFunctionTypes(fnTypes, queryElems) { // This search engine implements order-agnostic unification. There // should be no missing duplicates (generics have "bag semantics"), // and the row is allowed to have extras. - if (elem.generics.length > 0 && row.generics.length >= elem.generics.length) { - const elems = new Map(); - const addEntryToElems = function addEntryToElems(entry) { - if (entry.id === -1) { - // Pure generic, needs to check into it. - for (const inner_entry of entry.generics) { - addEntryToElems(inner_entry); - } - return; + if (queryElems.length === 0) { + return true; + } + if (!fnTypes || fnTypes.length === 0) { + return false; + } + /** + * @type Map + */ + const queryElemSet = new Map(); + const addQueryElemToQueryElemSet = function addQueryElemToQueryElemSet(queryElem) { + let currentQueryElemList; + if (queryElemSet.has(queryElem.id)) { + currentQueryElemList = queryElemSet.get(queryElem.id); + } else { + currentQueryElemList = []; + queryElemSet.set(queryElem.id, currentQueryElemList); + } + currentQueryElemList.push(queryElem); + }; + for (const queryElem of queryElems) { + addQueryElemToQueryElemSet(queryElem); + } + /** + * @type Map + */ + const fnTypeSet = new Map(); + const addFnTypeToFnTypeSet = function addFnTypeToFnTypeSet(fnType) { + // Pure generic, or an item that's not matched by any query elems. + // Try [unboxing] it. + // + // [unboxing]: + // http://ndmitchell.com/downloads/slides-hoogle_fast_type_searching-09_aug_2008.pdf + const queryContainsArrayOrSliceElem = queryElemSet.has(typeNameIdOfArrayOrSlice); + if (fnType.id === -1 || !( + queryElemSet.has(fnType.id) || + (fnType.id === typeNameIdOfSlice && queryContainsArrayOrSliceElem) || + (fnType.id === typeNameIdOfArray && queryContainsArrayOrSliceElem) + )) { + for (const innerFnType of fnType.generics) { + addFnTypeToFnTypeSet(innerFnType); } - let currentEntryElems; - if (elems.has(entry.id)) { - currentEntryElems = elems.get(entry.id); - } else { - currentEntryElems = []; - elems.set(entry.id, currentEntryElems); + return; + } + let currentQueryElemList = queryElemSet.get(fnType.id) || []; + let matchIdx = currentQueryElemList.findIndex(queryElem => { + return typePassesFilter(queryElem.typeFilter, fnType.ty) && + checkGenerics(fnType, queryElem); + }); + if (matchIdx === -1 && + (fnType.id === typeNameIdOfSlice || fnType.id === typeNameIdOfArray) && + queryContainsArrayOrSliceElem + ) { + currentQueryElemList = queryElemSet.get(typeNameIdOfArrayOrSlice) || []; + matchIdx = currentQueryElemList.findIndex(queryElem => { + return typePassesFilter(queryElem.typeFilter, fnType.ty) && + checkGenerics(fnType, queryElem); + }); + } + // None of the query elems match the function type. + // Try [unboxing] it. + if (matchIdx === -1) { + for (const innerFnType of fnType.generics) { + addFnTypeToFnTypeSet(innerFnType); } - currentEntryElems.push(entry); - }; - for (const entry of row.generics) { - addEntryToElems(entry); - } - // We need to find the type that matches the most to remove it in order - // to move forward. - const handleGeneric = generic => { - if (!elems.has(generic.id)) { - return false; + return; + } + let currentFnTypeList; + if (fnTypeSet.has(fnType.id)) { + currentFnTypeList = fnTypeSet.get(fnType.id); + } else { + currentFnTypeList = []; + fnTypeSet.set(fnType.id, currentFnTypeList); + } + currentFnTypeList.push(fnType); + }; + for (const fnType of fnTypes) { + addFnTypeToFnTypeSet(fnType); + } + const doHandleQueryElemList = (currentFnTypeList, queryElemList) => { + if (queryElemList.length === 0) { + return true; + } + // Multiple items in one list might match multiple items in another. + // Since an item with fewer generics can match an item with more, we + // need to check all combinations for a potential match. + const queryElem = queryElemList.pop(); + const l = currentFnTypeList.length; + for (let i = 0; i < l; i += 1) { + const fnType = currentFnTypeList[i]; + if (!typePassesFilter(queryElem.typeFilter, fnType.ty)) { + continue; } - const matchElems = elems.get(generic.id); - const matchIdx = matchElems.findIndex(tmp_elem => { - if (generic.generics.length > 0 && !checkGenerics(tmp_elem, generic)) { - return false; + if (queryElem.generics.length === 0 || checkGenerics(fnType, queryElem)) { + currentFnTypeList.splice(i, 1); + const result = doHandleQueryElemList(currentFnTypeList, queryElemList); + if (result) { + return true; } - return typePassesFilter(generic.typeFilter, tmp_elem.ty); - }); - if (matchIdx === -1) { - return false; + currentFnTypeList.splice(i, 0, fnType); } - matchElems.splice(matchIdx, 1); - if (matchElems.length === 0) { - elems.delete(generic.id); + } + return false; + }; + const handleQueryElemList = (id, queryElemList) => { + if (!fnTypeSet.has(id)) { + if (id === typeNameIdOfArrayOrSlice) { + return handleQueryElemList(typeNameIdOfSlice, queryElemList) || + handleQueryElemList(typeNameIdOfArray, queryElemList); } - return true; - }; - // To do the right thing with type filters, we first process generics - // that have them, removing matching ones from the "bag," then do the - // ones with no type filter, which can match any entry regardless of its - // own type. - for (const generic of elem.generics) { - if (generic.typeFilter !== -1 && !handleGeneric(generic)) { - return false; + return false; + } + const currentFnTypeList = fnTypeSet.get(id); + if (currentFnTypeList.length < queryElemList.length) { + // It's not possible for all the query elems to find a match. + return false; + } + const result = doHandleQueryElemList(currentFnTypeList, queryElemList); + if (result) { + // Found a solution. + // Any items that weren't used for it can be unboxed, and might form + // part of the solution for another item. + for (const innerFnType of currentFnTypeList) { + addFnTypeToFnTypeSet(innerFnType); } + fnTypeSet.delete(id); } - for (const generic of elem.generics) { - if (generic.typeFilter === -1 && !handleGeneric(generic)) { - return false; + return result; + }; + let queryElemSetSize = -1; + while (queryElemSetSize !== queryElemSet.size) { + queryElemSetSize = queryElemSet.size; + for (const [id, queryElemList] of queryElemSet) { + if (handleQueryElemList(id, queryElemList)) { + queryElemSet.delete(id); } } - return true; } - return false; + return queryElemSetSize === 0; } /** * This function checks if the object (`row`) matches the given type (`elem`) and its * generics (if any). * - * @param {Row} row + * @param {Array} list * @param {QueryElement} elem - The element from the parsed query. * * @return {boolean} - Returns true if found, false otherwise. */ - function checkIfInGenerics(row, elem) { - for (const entry of row.generics) { + function checkIfInList(list, elem) { + for (const entry of list) { if (checkType(entry, elem)) { return true; } @@ -1214,10 +1411,15 @@ function initSearch(rawSearchIndex) { function checkType(row, elem) { if (row.id === -1) { // This is a pure "generic" search, no need to run other checks. - return row.generics.length > 0 ? checkIfInGenerics(row, elem) : false; + return row.generics.length > 0 ? checkIfInList(row.generics, elem) : false; } - if (row.id === elem.id && typePassesFilter(elem.typeFilter, row.ty)) { + const matchesExact = row.id === elem.id; + const matchesArrayOrSlice = elem.id === typeNameIdOfArrayOrSlice && + (row.id === typeNameIdOfSlice || row.id === typeNameIdOfArray); + + if ((matchesExact || matchesArrayOrSlice) && + typePassesFilter(elem.typeFilter, row.ty)) { if (elem.generics.length > 0) { return checkGenerics(row, elem); } @@ -1227,59 +1429,7 @@ function initSearch(rawSearchIndex) { // If the current item does not match, try [unboxing] the generic. // [unboxing]: // https://ndmitchell.com/downloads/slides-hoogle_fast_type_searching-09_aug_2008.pdf - return checkIfInGenerics(row, elem); - } - - /** - * This function checks if the object (`row`) has an argument with the given type (`elem`). - * - * @param {Row} row - * @param {QueryElement} elem - The element from the parsed query. - * @param {Array} skipPositions - Do not return one of these positions. - * - * @return {integer} - Returns the position of the match, or -1 if none. - */ - function findArg(row, elem, skipPositions) { - if (row && row.type && row.type.inputs && row.type.inputs.length > 0) { - let i = 0; - for (const input of row.type.inputs) { - if (skipPositions.indexOf(i) !== -1) { - i += 1; - continue; - } - if (checkType(input, elem)) { - return i; - } - i += 1; - } - } - return -1; - } - - /** - * This function checks if the object (`row`) returns the given type (`elem`). - * - * @param {Row} row - * @param {QueryElement} elem - The element from the parsed query. - * @param {Array} skipPositions - Do not return one of these positions. - * - * @return {integer} - Returns the position of the matching item, or -1 if none. - */ - function checkReturned(row, elem, skipPositions) { - if (row && row.type && row.type.output.length > 0) { - let i = 0; - for (const ret_ty of row.type.output) { - if (skipPositions.indexOf(i) !== -1) { - i += 1; - continue; - } - if (checkType(ret_ty, elem)) { - return i; - } - i += 1; - } - } - return -1; + return checkIfInList(row.generics, elem); } function checkPath(contains, ty, maxEditDistance) { @@ -1480,14 +1630,14 @@ function initSearch(rawSearchIndex) { const fullId = row.id; const searchWord = searchWords[pos]; - const in_args = findArg(row, elem, []); - if (in_args !== -1) { + const in_args = row.type && row.type.inputs && checkIfInList(row.type.inputs, elem); + if (in_args) { // path_dist is 0 because no parent path information is currently stored // in the search index addIntoResults(results_in_args, fullId, pos, -1, 0, 0, maxEditDistance); } - const returned = checkReturned(row, elem, []); - if (returned !== -1) { + const returned = row.type && row.type.output && checkIfInList(row.type.output, elem); + if (returned) { addIntoResults(results_returned, fullId, pos, -1, 0, 0, maxEditDistance); } @@ -1543,32 +1693,15 @@ function initSearch(rawSearchIndex) { * @param {Object} results */ function handleArgs(row, pos, results) { - if (!row || (filterCrates !== null && row.crate !== filterCrates)) { + if (!row || (filterCrates !== null && row.crate !== filterCrates) || !row.type) { return; } // If the result is too "bad", we return false and it ends this search. - function checkArgs(elems, callback) { - const skipPositions = []; - for (const elem of elems) { - // There is more than one parameter to the query so all checks should be "exact" - const position = callback( - row, - elem, - skipPositions - ); - if (position !== -1) { - skipPositions.push(position); - } else { - return false; - } - } - return true; - } - if (!checkArgs(parsedQuery.elems, findArg)) { + if (!unifyFunctionTypes(row.type.inputs, parsedQuery.elems)) { return; } - if (!checkArgs(parsedQuery.returned, checkReturned)) { + if (!unifyFunctionTypes(row.type.output, parsedQuery.returned)) { return; } @@ -1655,12 +1788,9 @@ function initSearch(rawSearchIndex) { elem = parsedQuery.returned[0]; for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { row = searchIndex[i]; - in_returned = checkReturned( - row, - elem, - [] - ); - if (in_returned !== -1) { + in_returned = row.type && + unifyFunctionTypes(row.type.output, parsedQuery.returned); + if (in_returned) { addIntoResults( results_others, row.id, @@ -2082,34 +2212,6 @@ function initSearch(rawSearchIndex) { filterCrates); } - /** - * Add an item to the type Name->ID map, or, if one already exists, use it. - * Returns the number. If name is "" or null, return -1 (pure generic). - * - * This is effectively string interning, so that function matching can be - * done more quickly. Two types with the same name but different item kinds - * get the same ID. - * - * @param {Map} typeNameIdMap - * @param {string} name - * - * @returns {integer} - */ - function buildTypeMapIndex(typeNameIdMap, name) { - - if (name === "" || name === null) { - return -1; - } - - if (typeNameIdMap.has(name)) { - return typeNameIdMap.get(name); - } else { - const id = typeNameIdMap.size; - typeNameIdMap.set(name, id); - return id; - } - } - /** * Convert a list of RawFunctionType / ID to object-based FunctionType. * @@ -2128,7 +2230,7 @@ function initSearch(rawSearchIndex) { * * @return {Array} */ - function buildItemSearchTypeAll(types, lowercasePaths, typeNameIdMap) { + function buildItemSearchTypeAll(types, lowercasePaths) { const PATH_INDEX_DATA = 0; const GENERICS_DATA = 1; return types.map(type => { @@ -2140,15 +2242,14 @@ function initSearch(rawSearchIndex) { pathIndex = type[PATH_INDEX_DATA]; generics = buildItemSearchTypeAll( type[GENERICS_DATA], - lowercasePaths, - typeNameIdMap + lowercasePaths ); } return { // `0` is used as a sentinel because it's fewer bytes than `null` id: pathIndex === 0 ? -1 - : buildTypeMapIndex(typeNameIdMap, lowercasePaths[pathIndex - 1].name), + : buildTypeMapIndex(lowercasePaths[pathIndex - 1].name), ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, generics: generics, }; @@ -2171,7 +2272,7 @@ function initSearch(rawSearchIndex) { * * @return {null|FunctionSearchType} */ - function buildFunctionSearchType(functionSearchType, lowercasePaths, typeNameIdMap) { + function buildFunctionSearchType(functionSearchType, lowercasePaths) { const INPUTS_DATA = 0; const OUTPUT_DATA = 1; // `0` is used as a sentinel because it's fewer bytes than `null` @@ -2184,15 +2285,14 @@ function initSearch(rawSearchIndex) { inputs = [{ id: pathIndex === 0 ? -1 - : buildTypeMapIndex(typeNameIdMap, lowercasePaths[pathIndex - 1].name), + : buildTypeMapIndex(lowercasePaths[pathIndex - 1].name), ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, generics: [], }]; } else { inputs = buildItemSearchTypeAll( functionSearchType[INPUTS_DATA], - lowercasePaths, - typeNameIdMap + lowercasePaths ); } if (functionSearchType.length > 1) { @@ -2201,15 +2301,14 @@ function initSearch(rawSearchIndex) { output = [{ id: pathIndex === 0 ? -1 - : buildTypeMapIndex(typeNameIdMap, lowercasePaths[pathIndex - 1].name), + : buildTypeMapIndex(lowercasePaths[pathIndex - 1].name), ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, generics: [], }]; } else { output = buildItemSearchTypeAll( functionSearchType[OUTPUT_DATA], - lowercasePaths, - typeNameIdMap + lowercasePaths ); } } else { @@ -2233,6 +2332,12 @@ function initSearch(rawSearchIndex) { let currentIndex = 0; let id = 0; + // Initialize type map indexes for primitive list types + // that can be searched using `[]` syntax. + typeNameIdOfArray = buildTypeMapIndex("array"); + typeNameIdOfSlice = buildTypeMapIndex("slice"); + typeNameIdOfArrayOrSlice = buildTypeMapIndex("[]"); + for (const crate in rawSearchIndex) { if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) { continue; @@ -2363,8 +2468,7 @@ function initSearch(rawSearchIndex) { parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, type: buildFunctionSearchType( itemFunctionSearchTypes[i], - lowercasePaths, - typeNameIdMap + lowercasePaths ), id: id, normalizedName: word.indexOf("_") === -1 ? word : word.replace(/_/g, ""), diff --git a/src/librustdoc/html/templates/item_union.html b/src/librustdoc/html/templates/item_union.html index c219670051332..a01457971c178 100644 --- a/src/librustdoc/html/templates/item_union.html +++ b/src/librustdoc/html/templates/item_union.html @@ -1,8 +1,8 @@

    
    -    {{ self::item_template_render_attributes_in_pre(self.borrow()) | safe }}
    +    {{ self.render_attributes_in_pre() | safe }}
         {{ self.render_union() | safe }}
     
    -{{ self::item_template_document(self.borrow()) | safe }} +{{ self.document() | safe }} {% if self.fields_iter().peek().is_some() %}

    Fields§ @@ -19,5 +19,5 @@

    {{ self.document_field(field) | safe }} {% endfor %} {% endif %} -{{ self::item_template_render_assoc_items(self.borrow()) | safe }} -{{ self::item_template_document_type_layout(self.borrow()) | safe }} +{{ self.render_assoc_items() | safe }} +{{ self.document_type_layout() | safe }} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 12c622e026f1e..a8cd0ec453ed7 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -6,7 +6,6 @@ #![feature(array_methods)] #![feature(assert_matches)] #![feature(box_patterns)] -#![feature(drain_filter)] #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] #![feature(lazy_cell)] diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 96fe720630ccd..1b46c42fa4cf1 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -131,6 +131,15 @@ pub enum PanicStrategy { Abort, } +impl PanicStrategy { + pub(crate) fn for_miropt_test_tools(&self) -> miropt_test_tools::PanicStrategy { + match self { + PanicStrategy::Unwind => miropt_test_tools::PanicStrategy::Unwind, + PanicStrategy::Abort => miropt_test_tools::PanicStrategy::Abort, + } + } +} + /// Configuration for compiletest #[derive(Debug, Default, Clone)] pub struct Config { @@ -572,7 +581,7 @@ pub struct TargetCfg { #[serde(rename = "target-endian", default)] endian: Endian, #[serde(rename = "panic-strategy", default)] - panic: PanicStrategy, + pub(crate) panic: PanicStrategy, } impl TargetCfg { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 6582b534488a8..7c6668b1c5ddf 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3565,6 +3565,7 @@ impl<'test> TestCx<'test> { let files = miropt_test_tools::files_for_miropt_test( &self.testpaths.file, self.config.get_pointer_width(), + self.config.target_cfg().panic.for_miropt_test_tools(), ); let mut out = Vec::new(); @@ -3582,25 +3583,24 @@ impl<'test> TestCx<'test> { } fn check_mir_dump(&self) { - let test_file_contents = fs::read_to_string(&self.testpaths.file).unwrap(); - let test_dir = self.testpaths.file.parent().unwrap(); let test_crate = self.testpaths.file.file_stem().unwrap().to_str().unwrap().replace("-", "_"); - let mut bit_width = String::new(); - if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") { - bit_width = format!(".{}bit", self.config.get_pointer_width()); - } + let suffix = miropt_test_tools::output_file_suffix( + &self.testpaths.file, + self.config.get_pointer_width(), + self.config.target_cfg().panic.for_miropt_test_tools(), + ); if self.config.bless { for e in - glob(&format!("{}/{}.*{}.mir", test_dir.display(), test_crate, bit_width)).unwrap() + glob(&format!("{}/{}.*{}.mir", test_dir.display(), test_crate, suffix)).unwrap() { std::fs::remove_file(e.unwrap()).unwrap(); } for e in - glob(&format!("{}/{}.*{}.diff", test_dir.display(), test_crate, bit_width)).unwrap() + glob(&format!("{}/{}.*{}.diff", test_dir.display(), test_crate, suffix)).unwrap() { std::fs::remove_file(e.unwrap()).unwrap(); } @@ -3609,6 +3609,7 @@ impl<'test> TestCx<'test> { let files = miropt_test_tools::files_for_miropt_test( &self.testpaths.file, self.config.get_pointer_width(), + self.config.target_cfg().panic.for_miropt_test_tools(), ); for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file, passes: _ } in files diff --git a/src/tools/generate-windows-sys/src/arm_shim.rs b/src/tools/generate-windows-sys/src/arm_shim.rs new file mode 100644 index 0000000000000..17c2ccb223cce --- /dev/null +++ b/src/tools/generate-windows-sys/src/arm_shim.rs @@ -0,0 +1,20 @@ +// Begin of ARM32 shim +// The raw content of this file should be processed by `generate-windows-sys` +// to be merged with the generated binding. It is not supposed to be used as +// a normal Rust module. +cfg_if::cfg_if! { +if #[cfg(target_arch = "arm")] { +#[repr(C)] +pub struct WSADATA { + pub wVersion: u16, + pub wHighVersion: u16, + pub szDescription: [u8; 257], + pub szSystemStatus: [u8; 129], + pub iMaxSockets: u16, + pub iMaxUdpDg: u16, + pub lpVendorInfo: PSTR, +} +pub enum CONTEXT {} +} +} +// End of ARM32 shim diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs index 91d981462e816..65e480715ee20 100644 --- a/src/tools/generate-windows-sys/src/main.rs +++ b/src/tools/generate-windows-sys/src/main.rs @@ -11,6 +11,9 @@ const PRELUDE: &str = r#"// This file is autogenerated. // ignore-tidy-filelength "#; +/// This is a shim for the ARM (32-bit) architecture, which is no longer supported by windows-rs. +const ARM_SHIM: &str = include_str!("arm_shim.rs"); + fn main() -> io::Result<()> { let mut path: PathBuf = std::env::args_os().nth(1).expect("a path to the rust repository is required").into(); @@ -32,6 +35,7 @@ fn main() -> io::Result<()> { let mut f = std::fs::File::create(&path)?; f.write_all(PRELUDE.as_bytes())?; f.write_all(bindings.as_bytes())?; + f.write_all(ARM_SHIM.as_bytes())?; Ok(()) } diff --git a/src/tools/miri/tests/pass/btreemap.rs b/src/tools/miri/tests/pass/btreemap.rs index b7c0406becc4d..1213f81a6f128 100644 --- a/src/tools/miri/tests/pass/btreemap.rs +++ b/src/tools/miri/tests/pass/btreemap.rs @@ -1,7 +1,7 @@ //@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows //@compile-flags: -Zmiri-strict-provenance -#![feature(btree_drain_filter)] +#![feature(btree_extract_if)] use std::collections::{BTreeMap, BTreeSet}; use std::mem; @@ -49,8 +49,8 @@ pub fn main() { } test_all_refs(&mut 13, b.values_mut()); - // Test forgetting the drain. - let mut d = b.drain_filter(|_, i| *i < 30); + // Test forgetting the extractor. + let mut d = b.extract_if(|_, i| *i < 30); d.next().unwrap(); mem::forget(d); } diff --git a/src/tools/miropt-test-tools/src/lib.rs b/src/tools/miropt-test-tools/src/lib.rs index f86c3ce0afeaa..e33ecfe8eab24 100644 --- a/src/tools/miropt-test-tools/src/lib.rs +++ b/src/tools/miropt-test-tools/src/lib.rs @@ -1,4 +1,5 @@ use std::fs; +use std::path::Path; pub struct MiroptTestFiles { pub expected_file: std::path::PathBuf, @@ -8,18 +9,52 @@ pub struct MiroptTestFiles { pub passes: Vec, } -pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec { +pub enum PanicStrategy { + Unwind, + Abort, +} + +pub fn output_file_suffix( + testfile: &Path, + bit_width: u32, + panic_strategy: PanicStrategy, +) -> String { + let mut each_bit_width = false; + let mut each_panic_strategy = false; + for line in fs::read_to_string(testfile).unwrap().lines() { + if line == "// EMIT_MIR_FOR_EACH_BIT_WIDTH" { + each_bit_width = true; + } + if line == "// EMIT_MIR_FOR_EACH_PANIC_STRATEGY" { + each_panic_strategy = true; + } + } + + let mut suffix = String::new(); + if each_bit_width { + suffix.push_str(&format!(".{}bit", bit_width)); + } + if each_panic_strategy { + match panic_strategy { + PanicStrategy::Unwind => suffix.push_str(".panic-unwind"), + PanicStrategy::Abort => suffix.push_str(".panic-abort"), + } + } + suffix +} + +pub fn files_for_miropt_test( + testfile: &std::path::Path, + bit_width: u32, + panic_strategy: PanicStrategy, +) -> Vec { let mut out = Vec::new(); let test_file_contents = fs::read_to_string(&testfile).unwrap(); let test_dir = testfile.parent().unwrap(); let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace('-', "_"); - let bit_width = if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") { - format!(".{}bit", bit_width) - } else { - String::new() - }; + let suffix = output_file_suffix(testfile, bit_width, panic_strategy); for l in test_file_contents.lines() { if l.starts_with("// EMIT_MIR ") { @@ -37,7 +72,7 @@ pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec< passes.push(trimmed.split('.').last().unwrap().to_owned()); let test_against = format!("{}.after.mir", trimmed); from_file = format!("{}.before.mir", trimmed); - expected_file = format!("{}{}.diff", trimmed, bit_width); + expected_file = format!("{}{}.diff", trimmed, suffix); assert!(test_names.next().is_none(), "two mir pass names specified for MIR diff"); to_file = Some(test_against); } else if let Some(first_pass) = test_names.next() { @@ -51,7 +86,7 @@ pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec< assert!(test_names.next().is_none(), "three mir pass names specified for MIR diff"); expected_file = - format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass); + format!("{}{}.{}-{}.diff", test_name, suffix, first_pass, second_pass); let second_file = format!("{}.{}.mir", test_name, second_pass); from_file = format!("{}.{}.mir", test_name, first_pass); to_file = Some(second_file); @@ -64,7 +99,7 @@ pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec< let extension = cap.get(1).unwrap().as_str(); expected_file = - format!("{}{}{}", test_name.trim_end_matches(extension), bit_width, extension,); + format!("{}{}{}", test_name.trim_end_matches(extension), suffix, extension,); from_file = test_name.to_string(); assert!(test_names.next().is_none(), "two mir pass names specified for MIR dump"); to_file = None; diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js index b26480f668b37..af1bc05ddb248 100644 --- a/src/tools/rustdoc-gui/tester.js +++ b/src/tools/rustdoc-gui/tester.js @@ -201,8 +201,8 @@ async function main(argv) { try { // This is more convenient that setting fields one by one. const args = [ - "--variable", "DOC_PATH", opts["doc_folder"], "--enable-fail-on-js-error", - "--allow-file-access-from-files", + "--variable", "DOC_PATH", opts["doc_folder"].split("\\").join("/"), + "--enable-fail-on-js-error", "--allow-file-access-from-files", ]; if (opts["debug"]) { debug = true; diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 9979dfbd56a12..ac2056bcc855a 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -108,6 +108,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "adler", "ahash", "aho-corasick", + "allocator-api2", // FIXME: only appears in Cargo.lock due to https://github.com/rust-lang/cargo/issues/10801 "annotate-snippets", "ansi_term", "ar_archive_writer", diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs index 2f6918510e8bf..c307bcb93902d 100644 --- a/src/tools/tidy/src/mir_opt_tests.rs +++ b/src/tools/tidy/src/mir_opt_tests.rs @@ -1,5 +1,6 @@ //! Tidy check to ensure that mir opt directories do not have stale files or dashes in file names +use miropt_test_tools::PanicStrategy; use std::collections::HashSet; use std::path::{Path, PathBuf}; @@ -24,8 +25,10 @@ fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) { for file in rs_files { for bw in [32, 64] { - for output_file in miropt_test_tools::files_for_miropt_test(&file, bw) { - output_files.remove(&output_file.expected_file); + for ps in [PanicStrategy::Unwind, PanicStrategy::Abort] { + for output_file in miropt_test_tools::files_for_miropt_test(&file, bw, ps) { + output_files.remove(&output_file.expected_file); + } } } } diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 5c6a94877884d..55bf38110a6d5 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -10,7 +10,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. -const ISSUES_ENTRY_LIMIT: usize = 1898; +const ISSUES_ENTRY_LIMIT: usize = 1896; const ROOT_ENTRY_LIMIT: usize = 870; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir new file mode 100644 index 0000000000000..6351d58f7d2ac --- /dev/null +++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir @@ -0,0 +1,64 @@ +// MIR for `main` after SimplifyCfg-elaborate-drops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/array_index_is_temporary.rs:+0:11: +0:11 + let mut _1: [u32; 3]; // in scope 0 at $DIR/array_index_is_temporary.rs:+1:9: +1:14 + let mut _4: &mut usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+3:25: +3:31 + let mut _5: u32; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:12: +4:29 + let mut _6: *mut usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:25: +4:26 + let _7: usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:7: +4:8 + let mut _8: usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:5: +4:9 + let mut _9: bool; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:5: +4:9 + scope 1 { + debug x => _1; // in scope 1 at $DIR/array_index_is_temporary.rs:+1:9: +1:14 + let mut _2: usize; // in scope 1 at $DIR/array_index_is_temporary.rs:+2:9: +2:14 + scope 2 { + debug y => _2; // in scope 2 at $DIR/array_index_is_temporary.rs:+2:9: +2:14 + let _3: *mut usize; // in scope 2 at $DIR/array_index_is_temporary.rs:+3:9: +3:10 + scope 3 { + debug z => _3; // in scope 3 at $DIR/array_index_is_temporary.rs:+3:9: +3:10 + scope 4 { + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/array_index_is_temporary.rs:+1:9: +1:14 + _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array_index_is_temporary.rs:+1:17: +1:29 + StorageLive(_2); // scope 1 at $DIR/array_index_is_temporary.rs:+2:9: +2:14 + _2 = const 1_usize; // scope 1 at $DIR/array_index_is_temporary.rs:+2:17: +2:18 + StorageLive(_3); // scope 2 at $DIR/array_index_is_temporary.rs:+3:9: +3:10 + StorageLive(_4); // scope 2 at $DIR/array_index_is_temporary.rs:+3:25: +3:31 + _4 = &mut _2; // scope 2 at $DIR/array_index_is_temporary.rs:+3:25: +3:31 + _3 = &raw mut (*_4); // scope 2 at $DIR/array_index_is_temporary.rs:+3:25: +3:31 + StorageDead(_4); // scope 2 at $DIR/array_index_is_temporary.rs:+3:31: +3:32 + StorageLive(_5); // scope 3 at $DIR/array_index_is_temporary.rs:+4:12: +4:29 + StorageLive(_6); // scope 4 at $DIR/array_index_is_temporary.rs:+4:25: +4:26 + _6 = _3; // scope 4 at $DIR/array_index_is_temporary.rs:+4:25: +4:26 + _5 = foo(move _6) -> [return: bb1, unwind unreachable]; // scope 4 at $DIR/array_index_is_temporary.rs:+4:21: +4:27 + // mir::Constant + // + span: $DIR/array_index_is_temporary.rs:17:21: 17:24 + // + literal: Const { ty: unsafe fn(*mut usize) -> u32 {foo}, val: Value() } + } + + bb1: { + StorageDead(_6); // scope 4 at $DIR/array_index_is_temporary.rs:+4:26: +4:27 + StorageLive(_7); // scope 3 at $DIR/array_index_is_temporary.rs:+4:7: +4:8 + _7 = _2; // scope 3 at $DIR/array_index_is_temporary.rs:+4:7: +4:8 + _8 = Len(_1); // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:9 + _9 = Lt(_7, _8); // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:9 + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb2, unwind unreachable]; // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:9 + } + + bb2: { + _1[_7] = move _5; // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:29 + StorageDead(_5); // scope 3 at $DIR/array_index_is_temporary.rs:+4:28: +4:29 + StorageDead(_7); // scope 3 at $DIR/array_index_is_temporary.rs:+4:29: +4:30 + _0 = const (); // scope 0 at $DIR/array_index_is_temporary.rs:+0:11: +5:2 + StorageDead(_3); // scope 2 at $DIR/array_index_is_temporary.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/array_index_is_temporary.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/array_index_is_temporary.rs:+5:1: +5:2 + return; // scope 0 at $DIR/array_index_is_temporary.rs:+5:2: +5:2 + } +} diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir rename to tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir diff --git a/tests/mir-opt/array_index_is_temporary.rs b/tests/mir-opt/array_index_is_temporary.rs index 702b9c70e592a..950429fb6bca4 100644 --- a/tests/mir-opt/array_index_is_temporary.rs +++ b/tests/mir-opt/array_index_is_temporary.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Retagging (from Stacked Borrows) relies on the array index being a fresh // temporary, so that side-effects cannot change it. // Test that this is indeed the case. diff --git a/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-abort.mir new file mode 100644 index 0000000000000..2c0a3af73027e --- /dev/null +++ b/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-abort.mir @@ -0,0 +1,80 @@ +// MIR for `main` before ElaborateDrops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/box_expr.rs:+0:11: +0:11 + let _1: std::boxed::Box; // in scope 0 at $DIR/box_expr.rs:+1:9: +1:10 + let mut _2: usize; // in scope 0 at $DIR/box_expr.rs:+2:5: +2:23 + let mut _3: usize; // in scope 0 at $DIR/box_expr.rs:+2:5: +2:23 + let mut _4: *mut u8; // in scope 0 at $DIR/box_expr.rs:+2:5: +2:23 + let mut _5: std::boxed::Box; // in scope 0 at $DIR/box_expr.rs:+2:5: +2:23 + let _6: (); // in scope 0 at $DIR/box_expr.rs:+3:5: +3:12 + let mut _7: std::boxed::Box; // in scope 0 at $DIR/box_expr.rs:+3:10: +3:11 + scope 1 { + debug x => _1; // in scope 1 at $DIR/box_expr.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/box_expr.rs:+1:9: +1:10 + _2 = SizeOf(S); // scope 2 at $DIR/box_expr.rs:+2:5: +2:23 + _3 = AlignOf(S); // scope 2 at $DIR/box_expr.rs:+2:5: +2:23 + _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind: bb9]; // scope 2 at $DIR/box_expr.rs:+2:5: +2:23 + // mir::Constant + // + span: $DIR/box_expr.rs:8:5: 8:23 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value() } + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/box_expr.rs:+2:5: +2:23 + _5 = ShallowInitBox(move _4, S); // scope 0 at $DIR/box_expr.rs:+2:5: +2:23 + (*_5) = S::new() -> [return: bb2, unwind: bb8]; // scope 0 at $DIR/box_expr.rs:+2:14: +2:22 + // mir::Constant + // + span: $DIR/box_expr.rs:8:14: 8:20 + // + literal: Const { ty: fn() -> S {S::new}, val: Value() } + } + + bb2: { + _1 = move _5; // scope 0 at $DIR/box_expr.rs:+2:5: +2:23 + drop(_5) -> [return: bb3, unwind: bb9]; // scope 0 at $DIR/box_expr.rs:+2:22: +2:23 + } + + bb3: { + StorageDead(_5); // scope 0 at $DIR/box_expr.rs:+2:22: +2:23 + StorageLive(_6); // scope 1 at $DIR/box_expr.rs:+3:5: +3:12 + StorageLive(_7); // scope 1 at $DIR/box_expr.rs:+3:10: +3:11 + _7 = move _1; // scope 1 at $DIR/box_expr.rs:+3:10: +3:11 + _6 = std::mem::drop::>(move _7) -> [return: bb4, unwind: bb6]; // scope 1 at $DIR/box_expr.rs:+3:5: +3:12 + // mir::Constant + // + span: $DIR/box_expr.rs:9:5: 9:9 + // + literal: Const { ty: fn(Box) {std::mem::drop::>}, val: Value() } + } + + bb4: { + StorageDead(_7); // scope 1 at $DIR/box_expr.rs:+3:11: +3:12 + StorageDead(_6); // scope 1 at $DIR/box_expr.rs:+3:12: +3:13 + _0 = const (); // scope 0 at $DIR/box_expr.rs:+0:11: +4:2 + drop(_1) -> [return: bb5, unwind: bb9]; // scope 0 at $DIR/box_expr.rs:+4:1: +4:2 + } + + bb5: { + StorageDead(_1); // scope 0 at $DIR/box_expr.rs:+4:1: +4:2 + return; // scope 0 at $DIR/box_expr.rs:+4:2: +4:2 + } + + bb6 (cleanup): { + drop(_7) -> [return: bb7, unwind terminate]; // scope 1 at $DIR/box_expr.rs:+3:11: +3:12 + } + + bb7 (cleanup): { + drop(_1) -> [return: bb9, unwind terminate]; // scope 0 at $DIR/box_expr.rs:+4:1: +4:2 + } + + bb8 (cleanup): { + drop(_5) -> [return: bb9, unwind terminate]; // scope 0 at $DIR/box_expr.rs:+2:22: +2:23 + } + + bb9 (cleanup): { + resume; // scope 0 at $DIR/box_expr.rs:+0:1: +4:2 + } +} diff --git a/tests/mir-opt/box_expr.main.ElaborateDrops.before.mir b/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir similarity index 100% rename from tests/mir-opt/box_expr.main.ElaborateDrops.before.mir rename to tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir diff --git a/tests/mir-opt/box_expr.rs b/tests/mir-opt/box_expr.rs index ad3670b5dd403..780420bda9fca 100644 --- a/tests/mir-opt/box_expr.rs +++ b/tests/mir-opt/box_expr.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![feature(rustc_attrs, stmt_expr_attributes)] diff --git a/tests/mir-opt/combine_array_len.norm2.InstSimplify.panic-abort.diff b/tests/mir-opt/combine_array_len.norm2.InstSimplify.panic-abort.diff new file mode 100644 index 0000000000000..33dd4a9026506 --- /dev/null +++ b/tests/mir-opt/combine_array_len.norm2.InstSimplify.panic-abort.diff @@ -0,0 +1,77 @@ +- // MIR for `norm2` before InstSimplify ++ // MIR for `norm2` after InstSimplify + + fn norm2(_1: [f32; 2]) -> f32 { + debug x => _1; // in scope 0 at $DIR/combine_array_len.rs:+0:10: +0:11 + let mut _0: f32; // return place in scope 0 at $DIR/combine_array_len.rs:+0:26: +0:29 + let _2: f32; // in scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10 + let _3: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16 + let mut _4: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + let mut _5: bool; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + let _7: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:15: +2:16 + let mut _8: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17 + let mut _9: bool; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17 + let mut _10: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:8 + let mut _11: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:6 + let mut _12: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:7: +3:8 + let mut _13: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:14 + let mut _14: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:12 + let mut _15: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:13: +3:14 + scope 1 { + debug a => _2; // in scope 1 at $DIR/combine_array_len.rs:+1:9: +1:10 + let _6: f32; // in scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10 + scope 2 { + debug b => _6; // in scope 2 at $DIR/combine_array_len.rs:+2:9: +2:10 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16 + _3 = const 0_usize; // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16 +- _4 = Len(_1); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 ++ _4 = const 2_usize; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + _5 = Lt(_3, _4); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + } + + bb1: { + _2 = _1[_3]; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + StorageDead(_3); // scope 0 at $DIR/combine_array_len.rs:+1:17: +1:18 + StorageLive(_6); // scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10 + StorageLive(_7); // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16 + _7 = const 1_usize; // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16 +- _8 = Len(_1); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 ++ _8 = const 2_usize; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + _9 = Lt(_7, _8); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + } + + bb2: { + _6 = _1[_7]; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + StorageDead(_7); // scope 1 at $DIR/combine_array_len.rs:+2:17: +2:18 + StorageLive(_10); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8 + StorageLive(_11); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6 + _11 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6 + StorageLive(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + _12 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + _10 = Mul(move _11, move _12); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8 + StorageDead(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + StorageDead(_11); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + StorageLive(_13); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14 + StorageLive(_14); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12 + _14 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12 + StorageLive(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + _15 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + _13 = Mul(move _14, move _15); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14 + StorageDead(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + StorageDead(_14); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + _0 = Add(move _10, move _13); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:14 + StorageDead(_13); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + StorageDead(_10); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + StorageDead(_6); // scope 1 at $DIR/combine_array_len.rs:+4:1: +4:2 + StorageDead(_2); // scope 0 at $DIR/combine_array_len.rs:+4:1: +4:2 + return; // scope 0 at $DIR/combine_array_len.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/combine_array_len.norm2.InstSimplify.diff b/tests/mir-opt/combine_array_len.norm2.InstSimplify.panic-unwind.diff similarity index 100% rename from tests/mir-opt/combine_array_len.norm2.InstSimplify.diff rename to tests/mir-opt/combine_array_len.norm2.InstSimplify.panic-unwind.diff diff --git a/tests/mir-opt/combine_array_len.rs b/tests/mir-opt/combine_array_len.rs index 970cafafcf042..e971ab4781eee 100644 --- a/tests/mir-opt/combine_array_len.rs +++ b/tests/mir-opt/combine_array_len.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: InstSimplify // EMIT_MIR combine_array_len.norm2.InstSimplify.diff diff --git a/tests/mir-opt/combine_clone_of_primitives.rs b/tests/mir-opt/combine_clone_of_primitives.rs index 1deee9dd6d2f2..c19f9ee105ffe 100644 --- a/tests/mir-opt/combine_clone_of_primitives.rs +++ b/tests/mir-opt/combine_clone_of_primitives.rs @@ -1,5 +1,5 @@ // unit-test: InstSimplify -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR combine_clone_of_primitives.{impl#0}-clone.InstSimplify.diff diff --git a/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-abort.diff b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-abort.diff new file mode 100644 index 0000000000000..6ca960935ba57 --- /dev/null +++ b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-abort.diff @@ -0,0 +1,74 @@ +- // MIR for `::clone` before InstSimplify ++ // MIR for `::clone` after InstSimplify + + fn ::clone(_1: &MyThing) -> MyThing { + debug self => _1; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 + let mut _0: MyThing; // return place in scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 + let mut _2: T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + let mut _3: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + let _4: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + let mut _5: u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + let mut _6: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + let _7: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + let mut _8: [f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + let mut _9: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + let _10: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + StorageLive(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + StorageLive(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + _4 = &((*_1).0: T); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 +- _3 = &(*_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 ++ _3 = _4; // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + _2 = ::clone(move _3) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + // mir::Constant + // + span: $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + // + literal: Const { ty: for<'a> fn(&'a T) -> T {::clone}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:8: 8:9 + StorageLive(_5); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + StorageLive(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + StorageLive(_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + _7 = &((*_1).1: u64); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 +- _6 = &(*_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 +- _5 = ::clone(move _6) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 +- // mir::Constant +- // + span: $DIR/combine_clone_of_primitives.rs:9:5: 9:11 +- // + literal: Const { ty: for<'a> fn(&'a u64) -> u64 {::clone}, val: Value() } ++ _6 = _7; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 ++ _5 = (*_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 ++ goto -> bb2; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + } + + bb2: { + StorageDead(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:10: 9:11 + StorageLive(_8); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + StorageLive(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + StorageLive(_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + _10 = &((*_1).2: [f32; 3]); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 +- _9 = &(*_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 +- _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 +- // mir::Constant +- // + span: $DIR/combine_clone_of_primitives.rs:10:5: 10:16 +- // + literal: Const { ty: for<'a> fn(&'a [f32; 3]) -> [f32; 3] {<[f32; 3] as Clone>::clone}, val: Value() } ++ _9 = _10; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 ++ _8 = (*_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 ++ goto -> bb3; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + } + + bb3: { + StorageDead(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:15: 10:16 + _0 = MyThing:: { v: move _2, i: move _5, a: move _8 }; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 + StorageDead(_8); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + StorageDead(_5); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + StorageDead(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + StorageDead(_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + StorageDead(_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + StorageDead(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + return; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:15: +0:15 + } + } + diff --git a/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.diff b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff similarity index 100% rename from tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.diff rename to tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/aggregate.foo.ConstProp.diff b/tests/mir-opt/const_prop/aggregate.foo.ConstProp.panic-abort.diff similarity index 100% rename from tests/mir-opt/const_prop/aggregate.foo.ConstProp.diff rename to tests/mir-opt/const_prop/aggregate.foo.ConstProp.panic-abort.diff diff --git a/tests/mir-opt/const_prop/aggregate.foo.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/aggregate.foo.ConstProp.panic-unwind.diff new file mode 100644 index 0000000000000..6ac460db86f81 --- /dev/null +++ b/tests/mir-opt/const_prop/aggregate.foo.ConstProp.panic-unwind.diff @@ -0,0 +1,55 @@ +- // MIR for `foo` before ConstProp ++ // MIR for `foo` after ConstProp + + fn foo(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/aggregate.rs:+0:8: +0:9 + let mut _0: (); // return place in scope 0 at $DIR/aggregate.rs:+0:15: +0:15 + let _2: i32; // in scope 0 at $DIR/aggregate.rs:+2:9: +2:14 + let mut _3: i32; // in scope 0 at $DIR/aggregate.rs:+2:17: +2:25 + let mut _4: (i32, u8); // in scope 0 at $DIR/aggregate.rs:+2:17: +2:23 + let mut _5: u8; // in scope 0 at $DIR/aggregate.rs:+2:21: +2:22 + let mut _7: i32; // in scope 0 at $DIR/aggregate.rs:+3:18: +3:26 + let mut _8: (u8, i32); // in scope 0 at $DIR/aggregate.rs:+3:18: +3:24 + let mut _9: u8; // in scope 0 at $DIR/aggregate.rs:+3:19: +3:20 + scope 1 { + debug first => _2; // in scope 1 at $DIR/aggregate.rs:+2:9: +2:14 + let _6: i32; // in scope 1 at $DIR/aggregate.rs:+3:9: +3:15 + scope 2 { + debug second => _6; // in scope 2 at $DIR/aggregate.rs:+3:9: +3:15 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/aggregate.rs:+2:9: +2:14 + StorageLive(_3); // scope 0 at $DIR/aggregate.rs:+2:17: +2:25 + StorageLive(_4); // scope 0 at $DIR/aggregate.rs:+2:17: +2:23 + StorageLive(_5); // scope 0 at $DIR/aggregate.rs:+2:21: +2:22 + _5 = _1; // scope 0 at $DIR/aggregate.rs:+2:21: +2:22 + _4 = (const 0_i32, move _5); // scope 0 at $DIR/aggregate.rs:+2:17: +2:23 + StorageDead(_5); // scope 0 at $DIR/aggregate.rs:+2:22: +2:23 +- _3 = (_4.0: i32); // scope 0 at $DIR/aggregate.rs:+2:17: +2:25 +- _2 = Add(move _3, const 1_i32); // scope 0 at $DIR/aggregate.rs:+2:17: +2:29 ++ _3 = const 0_i32; // scope 0 at $DIR/aggregate.rs:+2:17: +2:25 ++ _2 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+2:17: +2:29 + StorageDead(_3); // scope 0 at $DIR/aggregate.rs:+2:28: +2:29 + StorageDead(_4); // scope 0 at $DIR/aggregate.rs:+2:29: +2:30 + StorageLive(_6); // scope 1 at $DIR/aggregate.rs:+3:9: +3:15 + StorageLive(_7); // scope 1 at $DIR/aggregate.rs:+3:18: +3:26 + StorageLive(_8); // scope 1 at $DIR/aggregate.rs:+3:18: +3:24 + StorageLive(_9); // scope 1 at $DIR/aggregate.rs:+3:19: +3:20 + _9 = _1; // scope 1 at $DIR/aggregate.rs:+3:19: +3:20 + _8 = (move _9, const 1_i32); // scope 1 at $DIR/aggregate.rs:+3:18: +3:24 + StorageDead(_9); // scope 1 at $DIR/aggregate.rs:+3:23: +3:24 +- _7 = (_8.1: i32); // scope 1 at $DIR/aggregate.rs:+3:18: +3:26 +- _6 = Add(move _7, const 2_i32); // scope 1 at $DIR/aggregate.rs:+3:18: +3:30 ++ _7 = const 1_i32; // scope 1 at $DIR/aggregate.rs:+3:18: +3:26 ++ _6 = const 3_i32; // scope 1 at $DIR/aggregate.rs:+3:18: +3:30 + StorageDead(_7); // scope 1 at $DIR/aggregate.rs:+3:29: +3:30 + StorageDead(_8); // scope 1 at $DIR/aggregate.rs:+3:30: +3:31 + _0 = const (); // scope 0 at $DIR/aggregate.rs:+0:15: +4:2 + StorageDead(_6); // scope 1 at $DIR/aggregate.rs:+4:1: +4:2 + StorageDead(_2); // scope 0 at $DIR/aggregate.rs:+4:1: +4:2 + return; // scope 0 at $DIR/aggregate.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/const_prop/aggregate.foo.PreCodegen.after.mir b/tests/mir-opt/const_prop/aggregate.foo.PreCodegen.after.panic-abort.mir similarity index 100% rename from tests/mir-opt/const_prop/aggregate.foo.PreCodegen.after.mir rename to tests/mir-opt/const_prop/aggregate.foo.PreCodegen.after.panic-abort.mir diff --git a/tests/mir-opt/const_prop/aggregate.foo.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/const_prop/aggregate.foo.PreCodegen.after.panic-unwind.mir new file mode 100644 index 0000000000000..2ef6d74e52846 --- /dev/null +++ b/tests/mir-opt/const_prop/aggregate.foo.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,49 @@ +// MIR for `foo` after PreCodegen + +fn foo(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/aggregate.rs:+0:8: +0:9 + let mut _0: (); // return place in scope 0 at $DIR/aggregate.rs:+0:15: +0:15 + let _2: i32; // in scope 0 at $DIR/aggregate.rs:+2:9: +2:14 + let mut _3: i32; // in scope 0 at $DIR/aggregate.rs:+2:17: +2:25 + let mut _4: (i32, u8); // in scope 0 at $DIR/aggregate.rs:+2:17: +2:23 + let mut _5: u8; // in scope 0 at $DIR/aggregate.rs:+2:21: +2:22 + let mut _7: i32; // in scope 0 at $DIR/aggregate.rs:+3:18: +3:26 + let mut _8: (u8, i32); // in scope 0 at $DIR/aggregate.rs:+3:18: +3:24 + let mut _9: u8; // in scope 0 at $DIR/aggregate.rs:+3:19: +3:20 + scope 1 { + debug first => _2; // in scope 1 at $DIR/aggregate.rs:+2:9: +2:14 + let _6: i32; // in scope 1 at $DIR/aggregate.rs:+3:9: +3:15 + scope 2 { + debug second => _6; // in scope 2 at $DIR/aggregate.rs:+3:9: +3:15 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/aggregate.rs:+2:9: +2:14 + StorageLive(_3); // scope 0 at $DIR/aggregate.rs:+2:17: +2:25 + StorageLive(_4); // scope 0 at $DIR/aggregate.rs:+2:17: +2:23 + StorageLive(_5); // scope 0 at $DIR/aggregate.rs:+2:21: +2:22 + _5 = _1; // scope 0 at $DIR/aggregate.rs:+2:21: +2:22 + _4 = (const 0_i32, move _5); // scope 0 at $DIR/aggregate.rs:+2:17: +2:23 + StorageDead(_5); // scope 0 at $DIR/aggregate.rs:+2:22: +2:23 + _3 = const 0_i32; // scope 0 at $DIR/aggregate.rs:+2:17: +2:25 + _2 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+2:17: +2:29 + StorageDead(_3); // scope 0 at $DIR/aggregate.rs:+2:28: +2:29 + StorageDead(_4); // scope 0 at $DIR/aggregate.rs:+2:29: +2:30 + StorageLive(_6); // scope 1 at $DIR/aggregate.rs:+3:9: +3:15 + StorageLive(_7); // scope 1 at $DIR/aggregate.rs:+3:18: +3:26 + StorageLive(_8); // scope 1 at $DIR/aggregate.rs:+3:18: +3:24 + StorageLive(_9); // scope 1 at $DIR/aggregate.rs:+3:19: +3:20 + _9 = _1; // scope 1 at $DIR/aggregate.rs:+3:19: +3:20 + _8 = (move _9, const 1_i32); // scope 1 at $DIR/aggregate.rs:+3:18: +3:24 + StorageDead(_9); // scope 1 at $DIR/aggregate.rs:+3:23: +3:24 + _7 = const 1_i32; // scope 1 at $DIR/aggregate.rs:+3:18: +3:26 + _6 = const 3_i32; // scope 1 at $DIR/aggregate.rs:+3:18: +3:30 + StorageDead(_7); // scope 1 at $DIR/aggregate.rs:+3:29: +3:30 + StorageDead(_8); // scope 1 at $DIR/aggregate.rs:+3:30: +3:31 + _0 = const (); // scope 0 at $DIR/aggregate.rs:+0:15: +4:2 + StorageDead(_6); // scope 1 at $DIR/aggregate.rs:+4:1: +4:2 + StorageDead(_2); // scope 0 at $DIR/aggregate.rs:+4:1: +4:2 + return; // scope 0 at $DIR/aggregate.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/const_prop/aggregate.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/aggregate.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..130c0a8d38c86 --- /dev/null +++ b/tests/mir-opt/const_prop/aggregate.main.ConstProp.panic-abort.diff @@ -0,0 +1,44 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/aggregate.rs:+0:11: +0:11 + let _1: u8; // in scope 0 at $DIR/aggregate.rs:+1:9: +1:10 + let mut _2: u8; // in scope 0 at $DIR/aggregate.rs:+1:13: +1:24 + let mut _3: (i32, u8, i32); // in scope 0 at $DIR/aggregate.rs:+1:13: +1:22 + let _4: (); // in scope 0 at $DIR/aggregate.rs:+2:5: +2:11 + let mut _5: u8; // in scope 0 at $DIR/aggregate.rs:+2:9: +2:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/aggregate.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/aggregate.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/aggregate.rs:+1:13: +1:24 + StorageLive(_3); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22 + _3 = (const 0_i32, const 1_u8, const 2_i32); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22 +- _2 = (_3.1: u8); // scope 0 at $DIR/aggregate.rs:+1:13: +1:24 +- _1 = Add(move _2, const 0_u8); // scope 0 at $DIR/aggregate.rs:+1:13: +1:28 ++ _2 = const 1_u8; // scope 0 at $DIR/aggregate.rs:+1:13: +1:24 ++ _1 = const 1_u8; // scope 0 at $DIR/aggregate.rs:+1:13: +1:28 + StorageDead(_2); // scope 0 at $DIR/aggregate.rs:+1:27: +1:28 + StorageDead(_3); // scope 0 at $DIR/aggregate.rs:+1:28: +1:29 + StorageLive(_4); // scope 1 at $DIR/aggregate.rs:+2:5: +2:11 + StorageLive(_5); // scope 1 at $DIR/aggregate.rs:+2:9: +2:10 +- _5 = _1; // scope 1 at $DIR/aggregate.rs:+2:9: +2:10 ++ _5 = const 1_u8; // scope 1 at $DIR/aggregate.rs:+2:9: +2:10 + _4 = foo(move _5) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/aggregate.rs:+2:5: +2:11 + // mir::Constant + // + span: $DIR/aggregate.rs:9:5: 9:8 + // + literal: Const { ty: fn(u8) {foo}, val: Value() } + } + + bb1: { + StorageDead(_5); // scope 1 at $DIR/aggregate.rs:+2:10: +2:11 + StorageDead(_4); // scope 1 at $DIR/aggregate.rs:+2:11: +2:12 + _0 = const (); // scope 0 at $DIR/aggregate.rs:+0:11: +3:2 + StorageDead(_1); // scope 0 at $DIR/aggregate.rs:+3:1: +3:2 + return; // scope 0 at $DIR/aggregate.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/const_prop/aggregate.main.ConstProp.diff b/tests/mir-opt/const_prop/aggregate.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/aggregate.main.ConstProp.diff rename to tests/mir-opt/const_prop/aggregate.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.panic-abort.mir b/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..06243db8b7e80 --- /dev/null +++ b/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.panic-abort.mir @@ -0,0 +1,39 @@ +// MIR for `main` after PreCodegen + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/aggregate.rs:+0:11: +0:11 + let _1: u8; // in scope 0 at $DIR/aggregate.rs:+1:9: +1:10 + let mut _2: u8; // in scope 0 at $DIR/aggregate.rs:+1:13: +1:24 + let mut _3: (i32, u8, i32); // in scope 0 at $DIR/aggregate.rs:+1:13: +1:22 + let _4: (); // in scope 0 at $DIR/aggregate.rs:+2:5: +2:11 + let mut _5: u8; // in scope 0 at $DIR/aggregate.rs:+2:9: +2:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/aggregate.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/aggregate.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/aggregate.rs:+1:13: +1:24 + StorageLive(_3); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22 + _3 = (const 0_i32, const 1_u8, const 2_i32); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22 + _2 = const 1_u8; // scope 0 at $DIR/aggregate.rs:+1:13: +1:24 + _1 = const 1_u8; // scope 0 at $DIR/aggregate.rs:+1:13: +1:28 + StorageDead(_2); // scope 0 at $DIR/aggregate.rs:+1:27: +1:28 + StorageDead(_3); // scope 0 at $DIR/aggregate.rs:+1:28: +1:29 + StorageLive(_4); // scope 1 at $DIR/aggregate.rs:+2:5: +2:11 + StorageLive(_5); // scope 1 at $DIR/aggregate.rs:+2:9: +2:10 + _5 = const 1_u8; // scope 1 at $DIR/aggregate.rs:+2:9: +2:10 + _4 = foo(move _5) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/aggregate.rs:+2:5: +2:11 + // mir::Constant + // + span: $DIR/aggregate.rs:9:5: 9:8 + // + literal: Const { ty: fn(u8) {foo}, val: Value() } + } + + bb1: { + StorageDead(_5); // scope 1 at $DIR/aggregate.rs:+2:10: +2:11 + StorageDead(_4); // scope 1 at $DIR/aggregate.rs:+2:11: +2:12 + _0 = const (); // scope 0 at $DIR/aggregate.rs:+0:11: +3:2 + StorageDead(_1); // scope 0 at $DIR/aggregate.rs:+3:1: +3:2 + return; // scope 0 at $DIR/aggregate.rs:+3:2: +3:2 + } +} diff --git a/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir b/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir rename to tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.panic-unwind.mir diff --git a/tests/mir-opt/const_prop/aggregate.rs b/tests/mir-opt/const_prop/aggregate.rs index ed5a4ab594d5c..62cd3dd688982 100644 --- a/tests/mir-opt/const_prop/aggregate.rs +++ b/tests/mir-opt/const_prop/aggregate.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // compile-flags: -O diff --git a/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.panic-abort.diff new file mode 100644 index 0000000000000..0859a1671da8b --- /dev/null +++ b/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.panic-abort.diff @@ -0,0 +1,39 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/array_index.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/array_index.rs:+1:9: +1:10 + let mut _2: [u32; 4]; // in scope 0 at $DIR/array_index.rs:+1:18: +1:30 + let _3: usize; // in scope 0 at $DIR/array_index.rs:+1:31: +1:32 + let mut _4: usize; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33 + let mut _5: bool; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33 + scope 1 { + debug x => _1; // in scope 1 at $DIR/array_index.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/array_index.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:30 + _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:+1:18: +1:30 + StorageLive(_3); // scope 0 at $DIR/array_index.rs:+1:31: +1:32 + _3 = const 2_usize; // scope 0 at $DIR/array_index.rs:+1:31: +1:32 +- _4 = Len(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:33 +- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33 +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 + } + + bb1: { +- _1 = _2[_3]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 + StorageDead(_3); // scope 0 at $DIR/array_index.rs:+1:33: +1:34 + StorageDead(_2); // scope 0 at $DIR/array_index.rs:+1:33: +1:34 + _0 = const (); // scope 0 at $DIR/array_index.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2 + return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff rename to tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.panic-abort.diff new file mode 100644 index 0000000000000..0859a1671da8b --- /dev/null +++ b/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.panic-abort.diff @@ -0,0 +1,39 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/array_index.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/array_index.rs:+1:9: +1:10 + let mut _2: [u32; 4]; // in scope 0 at $DIR/array_index.rs:+1:18: +1:30 + let _3: usize; // in scope 0 at $DIR/array_index.rs:+1:31: +1:32 + let mut _4: usize; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33 + let mut _5: bool; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33 + scope 1 { + debug x => _1; // in scope 1 at $DIR/array_index.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/array_index.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:30 + _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:+1:18: +1:30 + StorageLive(_3); // scope 0 at $DIR/array_index.rs:+1:31: +1:32 + _3 = const 2_usize; // scope 0 at $DIR/array_index.rs:+1:31: +1:32 +- _4 = Len(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:33 +- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33 +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 + } + + bb1: { +- _1 = _2[_3]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 + StorageDead(_3); // scope 0 at $DIR/array_index.rs:+1:33: +1:34 + StorageDead(_2); // scope 0 at $DIR/array_index.rs:+1:33: +1:34 + _0 = const (); // scope 0 at $DIR/array_index.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2 + return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff rename to tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/array_index.rs b/tests/mir-opt/const_prop/array_index.rs index f36cf22134866..f85d23b9789eb 100644 --- a/tests/mir-opt/const_prop/array_index.rs +++ b/tests/mir-opt/const_prop/array_index.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // EMIT_MIR_FOR_EACH_BIT_WIDTH diff --git a/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..5ec96b440b9c5 --- /dev/null +++ b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.panic-abort.diff @@ -0,0 +1,53 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10 + let mut _3: i32; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 + let mut _4: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + let mut _5: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + let mut _6: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + let mut _7: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + scope 1 { + debug y => _1; // in scope 1 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11 + scope 2 { + debug _z => _2; // in scope 2 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10 + _1 = const 0_i32; // scope 0 at $DIR/bad_op_div_by_zero.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11 + StorageLive(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 +- _3 = _1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 +- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 +- assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> [success: bb1, unwind unreachable]; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 ++ _4 = const true; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ assert(!const true, "attempt to divide `{}` by zero", const 1_i32) -> [success: bb1, unwind unreachable]; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + } + + bb1: { +- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 +- _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 +- _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 +- assert(!move _7, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ _5 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ _6 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ _7 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + } + + bb2: { + _2 = Div(const 1_i32, move _3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + StorageDead(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 + _0 = const (); // scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +3:2 + StorageDead(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2 + StorageDead(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2 + return; // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff rename to tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/bad_op_div_by_zero.rs b/tests/mir-opt/const_prop/bad_op_div_by_zero.rs index 38f1a993dc03a..963084bf7e5bf 100644 --- a/tests/mir-opt/const_prop/bad_op_div_by_zero.rs +++ b/tests/mir-opt/const_prop/bad_op_div_by_zero.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // EMIT_MIR bad_op_div_by_zero.main.ConstProp.diff #[allow(unconditional_panic)] diff --git a/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..fa9a2a09ba3d7 --- /dev/null +++ b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.panic-abort.diff @@ -0,0 +1,53 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/bad_op_mod_by_zero.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10 + let mut _3: i32; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 + let mut _4: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + let mut _5: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + let mut _6: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + let mut _7: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + scope 1 { + debug y => _1; // in scope 1 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11 + scope 2 { + debug _z => _2; // in scope 2 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10 + _1 = const 0_i32; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11 + StorageLive(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 +- _3 = _1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 +- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 +- assert(!move _4, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> [success: bb1, unwind unreachable]; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 ++ _4 = const true; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> [success: bb1, unwind unreachable]; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + } + + bb1: { +- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 +- _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 +- _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 +- assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ _5 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ _6 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ _7 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + } + + bb2: { + _2 = Rem(const 1_i32, move _3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + StorageDead(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 + _0 = const (); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+0:11: +3:2 + StorageDead(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2 + StorageDead(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2 + return; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff rename to tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs b/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs index 93d558250eaf1..9d7d2aa10443e 100644 --- a/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs +++ b/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs @@ -1,5 +1,5 @@ // unit-test: ConstProp -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR bad_op_mod_by_zero.main.ConstProp.diff #[allow(unconditional_panic)] fn main() { diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-abort.diff new file mode 100644 index 0000000000000..ebe38a8f29403 --- /dev/null +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-abort.diff @@ -0,0 +1,57 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+0:11: +0:11 + let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35 + let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + scope 1 { + debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + scope 2 { + let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + scope 3 { + debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + // mir::Constant + // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:9:25: 9:35 + // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) } + _3 = &(*_9); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35 + StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36 + StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _7 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _8 = const false; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + } + + bb1: { +- _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _5 = (*_1)[3 of 4]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 + _0 = const (); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 + StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 + StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2 + return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff rename to tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-abort.diff new file mode 100644 index 0000000000000..ebe38a8f29403 --- /dev/null +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-abort.diff @@ -0,0 +1,57 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+0:11: +0:11 + let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35 + let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + scope 1 { + debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + scope 2 { + let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + scope 3 { + debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + // mir::Constant + // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:9:25: 9:35 + // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) } + _3 = &(*_9); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35 + StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36 + StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _7 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _8 = const false; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + } + + bb1: { +- _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _5 = (*_1)[3 of 4]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 + _0 = const (); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 + StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 + StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2 + return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff rename to tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs index ef148d16dc2f7..7931c4f02ae67 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs @@ -1,5 +1,5 @@ // unit-test: ConstProp -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Zmir-enable-passes=+NormalizeArrayLen // EMIT_MIR_FOR_EACH_BIT_WIDTH diff --git a/tests/mir-opt/const_prop/boxes.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/boxes.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..2cc0b98acfdfc --- /dev/null +++ b/tests/mir-opt/const_prop/boxes.main.ConstProp.panic-abort.diff @@ -0,0 +1,56 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/boxes.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/boxes.rs:+1:9: +1:10 + let mut _2: i32; // in scope 0 at $DIR/boxes.rs:+1:13: +2:18 + let mut _3: std::boxed::Box; // in scope 0 at $DIR/boxes.rs:+1:14: +2:18 + let mut _4: usize; // in scope 0 at $DIR/boxes.rs:+1:14: +2:18 + let mut _5: usize; // in scope 0 at $DIR/boxes.rs:+1:14: +2:18 + let mut _6: *mut u8; // in scope 0 at $DIR/boxes.rs:+1:14: +2:18 + let mut _7: std::boxed::Box; // in scope 0 at $DIR/boxes.rs:+1:14: +2:18 + let mut _8: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +2:18 + let mut _9: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +2:18 + scope 1 { + debug x => _1; // in scope 1 at $DIR/boxes.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/boxes.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/boxes.rs:+1:13: +2:18 + StorageLive(_3); // scope 0 at $DIR/boxes.rs:+1:14: +2:18 +- _4 = SizeOf(i32); // scope 2 at $DIR/boxes.rs:+1:14: +2:18 +- _5 = AlignOf(i32); // scope 2 at $DIR/boxes.rs:+1:14: +2:18 ++ _4 = const 4_usize; // scope 2 at $DIR/boxes.rs:+1:14: +2:18 ++ _5 = const 4_usize; // scope 2 at $DIR/boxes.rs:+1:14: +2:18 + _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $DIR/boxes.rs:+1:14: +2:18 + // mir::Constant + // + span: $DIR/boxes.rs:13:14: 14:18 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value() } + } + + bb1: { + StorageLive(_7); // scope 0 at $DIR/boxes.rs:+1:14: +2:18 + _7 = ShallowInitBox(move _6, i32); // scope 0 at $DIR/boxes.rs:+1:14: +2:18 + _8 = (((_7.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const i32); // scope 0 at $DIR/boxes.rs:+2:14: +2:16 + (*_8) = const 42_i32; // scope 0 at $DIR/boxes.rs:+2:14: +2:16 + _3 = move _7; // scope 0 at $DIR/boxes.rs:+1:14: +2:18 + StorageDead(_7); // scope 0 at $DIR/boxes.rs:+2:17: +2:18 + _9 = (((_3.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:13: +2:18 + _2 = (*_9); // scope 0 at $DIR/boxes.rs:+1:13: +2:18 + _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/boxes.rs:+1:13: +3:12 + StorageDead(_2); // scope 0 at $DIR/boxes.rs:+3:11: +3:12 + drop(_3) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/boxes.rs:+3:12: +3:13 + } + + bb2: { + StorageDead(_3); // scope 0 at $DIR/boxes.rs:+3:12: +3:13 + _0 = const (); // scope 0 at $DIR/boxes.rs:+0:11: +4:2 + StorageDead(_1); // scope 0 at $DIR/boxes.rs:+4:1: +4:2 + return; // scope 0 at $DIR/boxes.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/const_prop/boxes.main.ConstProp.diff b/tests/mir-opt/const_prop/boxes.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/boxes.main.ConstProp.diff rename to tests/mir-opt/const_prop/boxes.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/boxes.rs b/tests/mir-opt/const_prop/boxes.rs index 66e8c24d4324d..9407759cb127b 100644 --- a/tests/mir-opt/const_prop/boxes.rs +++ b/tests/mir-opt/const_prop/boxes.rs @@ -1,7 +1,7 @@ // unit-test: ConstProp // compile-flags: -O // ignore-emscripten compiled with panic=abort by default -// ignore-wasm32 +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // ignore-wasm64 #![feature(rustc_attrs, stmt_expr_attributes)] diff --git a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..ba318d8eb35c1 --- /dev/null +++ b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff @@ -0,0 +1,28 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/checked_add.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/checked_add.rs:+1:9: +1:10 + let mut _2: (u32, bool); // in scope 0 at $DIR/checked_add.rs:+1:18: +1:23 + scope 1 { + debug x => _1; // in scope 1 at $DIR/checked_add.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/checked_add.rs:+1:9: +1:10 +- _2 = CheckedAdd(const 1_u32, const 1_u32); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 +- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 ++ _2 = const (2_u32, false); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 + } + + bb1: { +- _1 = move (_2.0: u32); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 ++ _1 = const 2_u32; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 + _0 = const (); // scope 0 at $DIR/checked_add.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/checked_add.rs:+2:1: +2:2 + return; // scope 0 at $DIR/checked_add.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/checked_add.main.ConstProp.diff b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/checked_add.main.ConstProp.diff rename to tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/checked_add.rs b/tests/mir-opt/const_prop/checked_add.rs index 007defd10379c..fd40876cbc221 100644 --- a/tests/mir-opt/const_prop/checked_add.rs +++ b/tests/mir-opt/const_prop/checked_add.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // compile-flags: -C overflow-checks=on diff --git a/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..1999a128c63bf --- /dev/null +++ b/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.panic-abort.diff @@ -0,0 +1,44 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +0:11 + let _1: usize; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10 + let mut _2: *const i32; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30 + let _3: &i32; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 + let _4: (); // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12 + let mut _5: usize; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11 + scope 1 { + debug x => _1; // in scope 1 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10 + StorageLive(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30 + StorageLive(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 + _3 = const _; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 + // mir::Constant + // + span: $DIR/const_prop_fails_gracefully.rs:9:13: 9:16 + // + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) } + _2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 + _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:39 + StorageDead(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:38: +2:39 + StorageDead(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:39: +2:40 + StorageLive(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12 + StorageLive(_5); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11 + _5 = _1; // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11 + _4 = read(move _5) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12 + // mir::Constant + // + span: $DIR/const_prop_fails_gracefully.rs:10:5: 10:9 + // + literal: Const { ty: fn(usize) {read}, val: Value() } + } + + bb1: { + StorageDead(_5); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:11: +3:12 + StorageDead(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:12: +3:13 + _0 = const (); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +4:2 + StorageDead(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:1: +4:2 + return; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff rename to tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/const_prop_fails_gracefully.rs b/tests/mir-opt/const_prop/const_prop_fails_gracefully.rs index 44d4878424dd8..c92831f926d3c 100644 --- a/tests/mir-opt/const_prop/const_prop_fails_gracefully.rs +++ b/tests/mir-opt/const_prop/const_prop_fails_gracefully.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp #[inline(never)] fn read(_: usize) { } diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..0ed292674338f --- /dev/null +++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-abort.diff @@ -0,0 +1,31 @@ +- // MIR for `hello` before ConstProp ++ // MIR for `hello` after ConstProp + + fn hello() -> () { + let mut _0: (); // return place in scope 0 at $DIR/control_flow_simplification.rs:+0:14: +0:14 + let mut _1: bool; // in scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 + let mut _2: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + + bb0: { + StorageLive(_1); // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 + _1 = const _; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 +- switchInt(move _1) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 ++ switchInt(const false) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 + } + + bb1: { + _2 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value() } + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + + bb2: { + StorageDead(_1); // scope 0 at $DIR/control_flow_simplification.rs:+3:5: +3:6 + return; // scope 0 at $DIR/control_flow_simplification.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff rename to tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir b/tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.panic-abort.mir similarity index 100% rename from tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir rename to tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.panic-abort.mir diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.panic-unwind.mir b/tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.panic-unwind.mir new file mode 100644 index 0000000000000..9f7528f0ce170 --- /dev/null +++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.panic-unwind.mir @@ -0,0 +1,9 @@ +// MIR for `hello` before PreCodegen + +fn hello() -> () { + let mut _0: (); // return place in scope 0 at $DIR/control_flow_simplification.rs:+0:14: +0:14 + + bb0: { + return; // scope 0 at $DIR/control_flow_simplification.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/const_prop/control_flow_simplification.rs b/tests/mir-opt/const_prop/control_flow_simplification.rs index b2ca045e89f98..21d727b3e50d9 100644 --- a/tests/mir-opt/const_prop/control_flow_simplification.rs +++ b/tests/mir-opt/const_prop/control_flow_simplification.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // compile-flags: -Zmir-opt-level=1 diff --git a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..a58d29d2fe17b --- /dev/null +++ b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff @@ -0,0 +1,33 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/indirect.rs:+0:11: +0:11 + let _1: u8; // in scope 0 at $DIR/indirect.rs:+1:9: +1:10 + let mut _2: u8; // in scope 0 at $DIR/indirect.rs:+1:13: +1:25 + let mut _3: (u8, bool); // in scope 0 at $DIR/indirect.rs:+1:13: +1:29 + scope 1 { + debug x => _1; // in scope 1 at $DIR/indirect.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/indirect.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/indirect.rs:+1:13: +1:25 +- _2 = const 2_u32 as u8 (IntToInt); // scope 0 at $DIR/indirect.rs:+1:13: +1:25 +- _3 = CheckedAdd(_2, const 1_u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29 +- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/indirect.rs:+1:13: +1:29 ++ _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:25 ++ _3 = const (3_u8, false); // scope 0 at $DIR/indirect.rs:+1:13: +1:29 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/indirect.rs:+1:13: +1:29 + } + + bb1: { +- _1 = move (_3.0: u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29 ++ _1 = const 3_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:29 + StorageDead(_2); // scope 0 at $DIR/indirect.rs:+1:28: +1:29 + _0 = const (); // scope 0 at $DIR/indirect.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/indirect.rs:+2:1: +2:2 + return; // scope 0 at $DIR/indirect.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/indirect.main.ConstProp.diff b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/indirect.main.ConstProp.diff rename to tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/indirect.rs b/tests/mir-opt/const_prop/indirect.rs index 46fd8082d308c..72af6cd95b8db 100644 --- a/tests/mir-opt/const_prop/indirect.rs +++ b/tests/mir-opt/const_prop/indirect.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // compile-flags: -C overflow-checks=on diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..951de4c3e33ca --- /dev/null +++ b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff @@ -0,0 +1,39 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inherit_overflow.rs:+0:11: +0:11 + let mut _1: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + let mut _2: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + let mut _3: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + scope 1 { + } + scope 2 (inlined ::add) { // at $DIR/inherit_overflow.rs:9:13: 9:47 + debug self => _2; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + debug other => _3; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + let mut _4: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageLive(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + _2 = const u8::MAX; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageLive(_3); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + _3 = const 1_u8; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 +- _4 = CheckedAdd(_2, _3); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL +- assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL ++ _4 = const (0_u8, true); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL ++ assert(!const true, "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + } + + bb1: { +- _1 = move (_4.0: u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL ++ _1 = const 0_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + StorageDead(_3); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageDead(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:47: +3:48 + _0 = const (); // scope 0 at $DIR/inherit_overflow.rs:+0:11: +4:2 + return; // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.diff b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.diff rename to tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/inherit_overflow.rs b/tests/mir-opt/const_prop/inherit_overflow.rs index 4e905d00d4d92..6ebd364121ab7 100644 --- a/tests/mir-opt/const_prop/inherit_overflow.rs +++ b/tests/mir-opt/const_prop/inherit_overflow.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // compile-flags: -Zmir-enable-passes=+Inline diff --git a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..061fd39e8b07e --- /dev/null +++ b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff @@ -0,0 +1,23 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_66971.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 + let mut _2: ((), u8, u8); // in scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 + _2 = (const (), const 0_u8, const 0_u8); // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 + _1 = encode(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 + // mir::Constant + // + span: $DIR/issue_66971.rs:18:5: 18:11 + // + literal: Const { ty: fn(((), u8, u8)) {encode}, val: Value() } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/issue_66971.rs:+1:22: +1:23 + return; // scope 0 at $DIR/issue_66971.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/issue_66971.main.ConstProp.diff rename to tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/issue_66971.rs b/tests/mir-opt/const_prop/issue_66971.rs index af95c9ca28389..a0242ec633f9e 100644 --- a/tests/mir-opt/const_prop/issue_66971.rs +++ b/tests/mir-opt/const_prop/issue_66971.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // compile-flags: -Z mir-opt-level=3 diff --git a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..99844045bb5e7 --- /dev/null +++ b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff @@ -0,0 +1,28 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_67019.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/issue_67019.rs:+1:5: +1:20 + let mut _2: ((u8, u8),); // in scope 0 at $DIR/issue_67019.rs:+1:10: +1:19 + let mut _3: (u8, u8); // in scope 0 at $DIR/issue_67019.rs:+1:11: +1:17 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_67019.rs:+1:10: +1:19 + StorageLive(_3); // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17 +- _3 = (const 1_u8, const 2_u8); // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17 ++ _3 = const (1_u8, 2_u8); // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17 + _2 = (move _3,); // scope 0 at $DIR/issue_67019.rs:+1:10: +1:19 + StorageDead(_3); // scope 0 at $DIR/issue_67019.rs:+1:18: +1:19 + _1 = test(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/issue_67019.rs:+1:5: +1:20 + // mir::Constant + // + span: $DIR/issue_67019.rs:13:5: 13:9 + // + literal: Const { ty: fn(((u8, u8),)) {test}, val: Value() } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/issue_67019.rs:+1:19: +1:20 + return; // scope 0 at $DIR/issue_67019.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/issue_67019.main.ConstProp.diff rename to tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/issue_67019.rs b/tests/mir-opt/const_prop/issue_67019.rs index 08c7d4805d615..66b577f5b5f80 100644 --- a/tests/mir-opt/const_prop/issue_67019.rs +++ b/tests/mir-opt/const_prop/issue_67019.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // compile-flags: -Z mir-opt-level=3 diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.panic-abort.diff new file mode 100644 index 0000000000000..6794cfd81df12 --- /dev/null +++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.panic-abort.diff @@ -0,0 +1,39 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/large_array_index.rs:+0:11: +0:11 + let _1: u8; // in scope 0 at $DIR/large_array_index.rs:+2:9: +2:10 + let mut _2: [u8; 5000]; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + let _3: usize; // in scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 + let mut _4: usize; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + let mut _5: bool; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + scope 1 { + debug x => _1; // in scope 1 at $DIR/large_array_index.rs:+2:9: +2:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/large_array_index.rs:+2:9: +2:10 + StorageLive(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + _2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 + _3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 +- _4 = Len(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _5 = const true; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + } + + bb1: { +- _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _1 = _2[2 of 3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 + StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 + _0 = const (); // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2 + StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2 + return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff rename to tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.panic-abort.diff new file mode 100644 index 0000000000000..6794cfd81df12 --- /dev/null +++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.panic-abort.diff @@ -0,0 +1,39 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/large_array_index.rs:+0:11: +0:11 + let _1: u8; // in scope 0 at $DIR/large_array_index.rs:+2:9: +2:10 + let mut _2: [u8; 5000]; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + let _3: usize; // in scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 + let mut _4: usize; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + let mut _5: bool; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + scope 1 { + debug x => _1; // in scope 1 at $DIR/large_array_index.rs:+2:9: +2:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/large_array_index.rs:+2:9: +2:10 + StorageLive(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + _2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 + _3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 +- _4 = Len(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _5 = const true; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + } + + bb1: { +- _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _1 = _2[2 of 3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 + StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 + _0 = const (); // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2 + StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2 + return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff rename to tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/large_array_index.rs b/tests/mir-opt/const_prop/large_array_index.rs index 0876445bf2ceb..6c03fe9d9c2f7 100644 --- a/tests/mir-opt/const_prop/large_array_index.rs +++ b/tests/mir-opt/const_prop/large_array_index.rs @@ -1,5 +1,5 @@ // unit-test: ConstProp -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Zmir-enable-passes=+NormalizeArrayLen // EMIT_MIR_FOR_EACH_BIT_WIDTH diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..b9da74e30b094 --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.panic-abort.diff @@ -0,0 +1,35 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+0:11: +0:11 + let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14 + let _2: i32; // in scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14 + _1 = foo() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:29: +1:34 + // mir::Constant + // + span: $DIR/mutable_variable_aggregate_partial_read.rs:6:29: 6:32 + // + literal: Const { ty: fn() -> (i32, i32) {foo}, val: Value() } + } + + bb1: { + (_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+2:5: +2:13 + (_1.0: i32) = const 42_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+3:5: +3:13 + StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10 +- _2 = (_1.1: i32); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:13: +4:16 ++ _2 = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:13: +4:16 + _0 = const (); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+0:11: +5:2 + StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:1: +5:2 + return; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff rename to tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs index 0e823e9dc0845..30ea5714ae49a 100644 --- a/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // EMIT_MIR mutable_variable_aggregate_partial_read.main.ConstProp.diff diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..b090dfc92b64d --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff @@ -0,0 +1,53 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10 + let mut _3: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + scope 1 { + debug a => _1; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10 + let mut _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + scope 2 { + debug x => _2; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + let _4: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + scope 3 { + debug y => _4; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + let _5: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 + scope 4 { + debug z => _5; // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10 + _1 = foo() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:13: +1:18 + // mir::Constant + // + span: $DIR/mutable_variable_unprop_assign.rs:6:13: 6:16 + // + literal: Const { ty: fn() -> i32 {foo}, val: Value() } + } + + bb1: { + StorageLive(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 +- _2 = (const 1_i32, const 2_i32); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 ++ _2 = const (1_i32, 2_i32); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + _3 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + (_2.1: i32) = move _3; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12 + StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + StorageLive(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + _4 = (_2.1: i32); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16 + StorageLive(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 +- _5 = (_2.0: i32); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 ++ _5 = const 1_i32; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 + _0 = const (); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +6:2 + StorageDead(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + return; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:2: +6:2 + } + } + diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff rename to tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs index 5577f78a96363..4e7c0597a29f3 100644 --- a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs +++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // EMIT_MIR mutable_variable_unprop_assign.main.ConstProp.diff diff --git a/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.panic-abort.diff new file mode 100644 index 0000000000000..24c78ab992f15 --- /dev/null +++ b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.panic-abort.diff @@ -0,0 +1,44 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/repeat.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/repeat.rs:+1:9: +1:10 + let mut _2: u32; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + let mut _3: [u32; 8]; // in scope 0 at $DIR/repeat.rs:+1:18: +1:25 + let _4: usize; // in scope 0 at $DIR/repeat.rs:+1:26: +1:27 + let mut _5: usize; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + let mut _6: bool; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + scope 1 { + debug x => _1; // in scope 1 at $DIR/repeat.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/repeat.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 + StorageLive(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:25 + _3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:+1:18: +1:25 + StorageLive(_4); // scope 0 at $DIR/repeat.rs:+1:26: +1:27 + _4 = const 2_usize; // scope 0 at $DIR/repeat.rs:+1:26: +1:27 +- _5 = Len(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _6 = const true; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 + } + + bb1: { +- _2 = _3[_4]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- _1 = Add(move _2, const 0_u32); // scope 0 at $DIR/repeat.rs:+1:18: +1:32 ++ _2 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _1 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:32 + StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32 + StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 + StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 + _0 = const (); // scope 0 at $DIR/repeat.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2 + return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff rename to tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.panic-abort.diff new file mode 100644 index 0000000000000..24c78ab992f15 --- /dev/null +++ b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.panic-abort.diff @@ -0,0 +1,44 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/repeat.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/repeat.rs:+1:9: +1:10 + let mut _2: u32; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + let mut _3: [u32; 8]; // in scope 0 at $DIR/repeat.rs:+1:18: +1:25 + let _4: usize; // in scope 0 at $DIR/repeat.rs:+1:26: +1:27 + let mut _5: usize; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + let mut _6: bool; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + scope 1 { + debug x => _1; // in scope 1 at $DIR/repeat.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/repeat.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 + StorageLive(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:25 + _3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:+1:18: +1:25 + StorageLive(_4); // scope 0 at $DIR/repeat.rs:+1:26: +1:27 + _4 = const 2_usize; // scope 0 at $DIR/repeat.rs:+1:26: +1:27 +- _5 = Len(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _6 = const true; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 + } + + bb1: { +- _2 = _3[_4]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- _1 = Add(move _2, const 0_u32); // scope 0 at $DIR/repeat.rs:+1:18: +1:32 ++ _2 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _1 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:32 + StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32 + StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 + StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 + _0 = const (); // scope 0 at $DIR/repeat.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2 + return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff rename to tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/repeat.rs b/tests/mir-opt/const_prop/repeat.rs index 9c11dbc5b6694..21dba84af375c 100644 --- a/tests/mir-opt/const_prop/repeat.rs +++ b/tests/mir-opt/const_prop/repeat.rs @@ -1,5 +1,5 @@ // unit-test: ConstProp -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Zmir-enable-passes=+NormalizeArrayLen // EMIT_MIR_FOR_EACH_BIT_WIDTH diff --git a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..e0daf107522d4 --- /dev/null +++ b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff @@ -0,0 +1,21 @@ +- // MIR for `add` before ConstProp ++ // MIR for `add` after ConstProp + + fn add() -> u32 { + let mut _0: u32; // return place in scope 0 at $DIR/return_place.rs:+0:13: +0:16 + let mut _1: (u32, bool); // in scope 0 at $DIR/return_place.rs:+1:5: +1:10 + + bb0: { +- _1 = CheckedAdd(const 2_u32, const 2_u32); // scope 0 at $DIR/return_place.rs:+1:5: +1:10 +- assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 ++ _1 = const (4_u32, false); // scope 0 at $DIR/return_place.rs:+1:5: +1:10 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 + } + + bb1: { +- _0 = move (_1.0: u32); // scope 0 at $DIR/return_place.rs:+1:5: +1:10 ++ _0 = const 4_u32; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 + return; // scope 0 at $DIR/return_place.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/return_place.add.ConstProp.diff b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/return_place.add.ConstProp.diff rename to tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir new file mode 100644 index 0000000000000..58b2acfbad2a1 --- /dev/null +++ b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir @@ -0,0 +1,16 @@ +// MIR for `add` before PreCodegen + +fn add() -> u32 { + let mut _0: u32; // return place in scope 0 at $DIR/return_place.rs:+0:13: +0:16 + let mut _1: (u32, bool); // in scope 0 at $DIR/return_place.rs:+1:5: +1:10 + + bb0: { + _1 = const (4_u32, false); // scope 0 at $DIR/return_place.rs:+1:5: +1:10 + assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 + } + + bb1: { + _0 = const 4_u32; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 + return; // scope 0 at $DIR/return_place.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir similarity index 100% rename from tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir rename to tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir diff --git a/tests/mir-opt/const_prop/return_place.rs b/tests/mir-opt/const_prop/return_place.rs index 0e68309f036d4..0576b02a84562 100644 --- a/tests/mir-opt/const_prop/return_place.rs +++ b/tests/mir-opt/const_prop/return_place.rs @@ -1,5 +1,5 @@ // unit-test: ConstProp -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -C overflow-checks=on // EMIT_MIR return_place.add.ConstProp.diff diff --git a/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..11bbe9da10f87 --- /dev/null +++ b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.panic-abort.diff @@ -0,0 +1,34 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/scalar_literal_propagation.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10 + let _2: (); // in scope 0 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 + let mut _3: u32; // in scope 0 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10 + _1 = const 1_u32; // scope 0 at $DIR/scalar_literal_propagation.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 + StorageLive(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 +- _3 = _1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 ++ _3 = const 1_u32; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 + _2 = consume(move _3) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 + // mir::Constant + // + span: $DIR/scalar_literal_propagation.rs:6:5: 6:12 + // + literal: Const { ty: fn(u32) {consume}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:14: +2:15 + StorageDead(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:15: +2:16 + _0 = const (); // scope 0 at $DIR/scalar_literal_propagation.rs:+0:11: +3:2 + StorageDead(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+3:1: +3:2 + return; // scope 0 at $DIR/scalar_literal_propagation.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff rename to tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/scalar_literal_propagation.rs b/tests/mir-opt/const_prop/scalar_literal_propagation.rs index fc33cc2d021f1..dfe41e6145bdd 100644 --- a/tests/mir-opt/const_prop/scalar_literal_propagation.rs +++ b/tests/mir-opt/const_prop/scalar_literal_propagation.rs @@ -1,5 +1,5 @@ // unit-test: ConstProp -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR scalar_literal_propagation.main.ConstProp.diff fn main() { let x = 1; diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-abort.diff new file mode 100644 index 0000000000000..cd8ee121a2571 --- /dev/null +++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-abort.diff @@ -0,0 +1,50 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/slice_len.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _2: &[u32]; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:30 + let mut _3: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + let _4: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + let _5: [u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:7: +1:19 + let _6: usize; // in scope 0 at $DIR/slice_len.rs:+1:31: +1:32 + let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30 + StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _9 = const _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + // mir::Constant + // + span: $DIR/slice_len.rs:8:6: 8:19 + // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) } + _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + StorageDead(_3); // scope 0 at $DIR/slice_len.rs:+1:18: +1:19 + StorageLive(_6); // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 + _6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 +- _7 = Len((*_2)); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 +- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _8 = const true; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + } + + bb1: { +- _1 = (*_2)[_6]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _1 = const 2_u32; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + StorageDead(_6); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_4); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_2); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_1); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + _0 = const (); // scope 0 at $DIR/slice_len.rs:+0:11: +2:2 + return; // scope 0 at $DIR/slice_len.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff rename to tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-abort.diff new file mode 100644 index 0000000000000..cd8ee121a2571 --- /dev/null +++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-abort.diff @@ -0,0 +1,50 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/slice_len.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _2: &[u32]; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:30 + let mut _3: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + let _4: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + let _5: [u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:7: +1:19 + let _6: usize; // in scope 0 at $DIR/slice_len.rs:+1:31: +1:32 + let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30 + StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _9 = const _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + // mir::Constant + // + span: $DIR/slice_len.rs:8:6: 8:19 + // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) } + _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + StorageDead(_3); // scope 0 at $DIR/slice_len.rs:+1:18: +1:19 + StorageLive(_6); // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 + _6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 +- _7 = Len((*_2)); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 +- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _8 = const true; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + } + + bb1: { +- _1 = (*_2)[_6]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _1 = const 2_u32; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + StorageDead(_6); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_4); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_2); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_1); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + _0 = const (); // scope 0 at $DIR/slice_len.rs:+0:11: +2:2 + return; // scope 0 at $DIR/slice_len.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff rename to tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/slice_len.rs b/tests/mir-opt/const_prop/slice_len.rs index 9821d1b1e9220..e91724536f918 100644 --- a/tests/mir-opt/const_prop/slice_len.rs +++ b/tests/mir-opt/const_prop/slice_len.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: ConstProp // compile-flags: -Zmir-enable-passes=+InstSimplify // EMIT_MIR_FOR_EACH_BIT_WIDTH diff --git a/tests/mir-opt/const_prop/switch_int.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/switch_int.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..e334faa15cb91 --- /dev/null +++ b/tests/mir-opt/const_prop/switch_int.main.ConstProp.panic-abort.diff @@ -0,0 +1,34 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/switch_int.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/switch_int.rs:+1:11: +1:12 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 + _1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 +- switchInt(_1) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 ++ switchInt(const 1_i32) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 + } + + bb1: { + _0 = foo(const -1_i32) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/switch_int.rs:+3:14: +3:21 + // mir::Constant + // + span: $DIR/switch_int.rs:12:14: 12:17 + // + literal: Const { ty: fn(i32) {foo}, val: Value() } + } + + bb2: { + _0 = foo(const 0_i32) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/switch_int.rs:+2:14: +2:20 + // mir::Constant + // + span: $DIR/switch_int.rs:11:14: 11:17 + // + literal: Const { ty: fn(i32) {foo}, val: Value() } + } + + bb3: { + StorageDead(_1); // scope 0 at $DIR/switch_int.rs:+5:1: +5:2 + return; // scope 0 at $DIR/switch_int.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/const_prop/switch_int.main.ConstProp.diff b/tests/mir-opt/const_prop/switch_int.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/switch_int.main.ConstProp.diff rename to tests/mir-opt/const_prop/switch_int.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.panic-abort.diff b/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.panic-abort.diff new file mode 100644 index 0000000000000..865dd488f001f --- /dev/null +++ b/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.panic-abort.diff @@ -0,0 +1,34 @@ +- // MIR for `main` before SimplifyConstCondition-after-const-prop ++ // MIR for `main` after SimplifyConstCondition-after-const-prop + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/switch_int.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/switch_int.rs:+1:11: +1:12 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 + _1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 +- switchInt(const 1_i32) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 ++ goto -> bb2; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 + } + + bb1: { + _0 = foo(const -1_i32) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/switch_int.rs:+3:14: +3:21 + // mir::Constant + // + span: $DIR/switch_int.rs:12:14: 12:17 + // + literal: Const { ty: fn(i32) {foo}, val: Value() } + } + + bb2: { + _0 = foo(const 0_i32) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/switch_int.rs:+2:14: +2:20 + // mir::Constant + // + span: $DIR/switch_int.rs:11:14: 11:17 + // + literal: Const { ty: fn(i32) {foo}, val: Value() } + } + + bb3: { + StorageDead(_1); // scope 0 at $DIR/switch_int.rs:+5:1: +5:2 + return; // scope 0 at $DIR/switch_int.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff b/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff rename to tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/switch_int.rs b/tests/mir-opt/const_prop/switch_int.rs index 7158ea4d2bd92..bf708c8298e16 100644 --- a/tests/mir-opt/const_prop/switch_int.rs +++ b/tests/mir-opt/const_prop/switch_int.rs @@ -1,6 +1,6 @@ // unit-test: ConstProp // compile-flags: -Zmir-enable-passes=+SimplifyConstCondition-after-const-prop -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #[inline(never)] fn foo(_: i32) { } diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..f9ae4da800b0e --- /dev/null +++ b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff @@ -0,0 +1,35 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/tuple_literal_propagation.rs:+0:11: +0:11 + let _1: (u32, u32); // in scope 0 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10 + let _2: (); // in scope 0 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15 + let mut _3: (u32, u32); // in scope 0 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10 +- _1 = (const 1_u32, const 2_u32); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19 ++ _1 = const (1_u32, 2_u32); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19 + StorageLive(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15 + StorageLive(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 +- _3 = _1; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 ++ _3 = const (1_u32, 2_u32); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 + _2 = consume(move _3) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15 + // mir::Constant + // + span: $DIR/tuple_literal_propagation.rs:7:5: 7:12 + // + literal: Const { ty: fn((u32, u32)) {consume}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:14: +3:15 + StorageDead(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:15: +3:16 + _0 = const (); // scope 0 at $DIR/tuple_literal_propagation.rs:+0:11: +4:2 + StorageDead(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+4:1: +4:2 + return; // scope 0 at $DIR/tuple_literal_propagation.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff rename to tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.rs b/tests/mir-opt/const_prop/tuple_literal_propagation.rs index f342ae2700e24..5890a343f26c3 100644 --- a/tests/mir-opt/const_prop/tuple_literal_propagation.rs +++ b/tests/mir-opt/const_prop/tuple_literal_propagation.rs @@ -1,5 +1,5 @@ // unit-test: ConstProp -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR tuple_literal_propagation.main.ConstProp.diff fn main() { let x = (1, 2); diff --git a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..00d22c9313e61 --- /dev/null +++ b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.panic-abort.diff @@ -0,0 +1,33 @@ +- // MIR for `f` before CopyProp ++ // MIR for `f` after CopyProp + + fn f() -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/borrowed_local.rs:+0:11: +0:15 + let mut _1: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _2: &u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _4: &u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _1 = const 5_u8; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _2 = &_1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _3 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _4 = &_3; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _0 = cmp_ref(_2, _4) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/borrowed_local.rs:+8:13: +8:45 + // mir::Constant + // + span: $DIR/borrowed_local.rs:24:29: 24:36 + // + literal: Const { ty: for<'a, 'b> fn(&'a u8, &'b u8) -> bool {cmp_ref}, val: Value() } + } + + bb1: { + _0 = opaque::(_3) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38 + // mir::Constant + // + span: $DIR/borrowed_local.rs:28:28: 28:34 + // + literal: Const { ty: fn(u8) -> bool {opaque::}, val: Value() } + } + + bb2: { + return; // scope 0 at $DIR/borrowed_local.rs:+15:13: +15:21 + } + } + diff --git a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff rename to tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/borrowed_local.rs b/tests/mir-opt/copy-prop/borrowed_local.rs index 9186da5af4845..a89b64441d0c8 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.rs +++ b/tests/mir-opt/copy-prop/borrowed_local.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: CopyProp #![feature(custom_mir, core_intrinsics)] diff --git a/tests/mir-opt/copy-prop/branch.foo.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/branch.foo.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..e52005cd457fd --- /dev/null +++ b/tests/mir-opt/copy-prop/branch.foo.CopyProp.panic-abort.diff @@ -0,0 +1,65 @@ +- // MIR for `foo` before CopyProp ++ // MIR for `foo` after CopyProp + + fn foo() -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/branch.rs:+0:13: +0:16 + let _1: i32; // in scope 0 at $DIR/branch.rs:+1:9: +1:10 + let mut _3: bool; // in scope 0 at $DIR/branch.rs:+3:16: +3:22 + let _4: i32; // in scope 0 at $DIR/branch.rs:+6:9: +6:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/branch.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/branch.rs:+3:9: +3:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/branch.rs:+3:9: +3:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/branch.rs:+1:9: +1:10 + _1 = val() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/branch.rs:+1:13: +1:18 + // mir::Constant + // + span: $DIR/branch.rs:14:13: 14:16 + // + literal: Const { ty: fn() -> i32 {val}, val: Value() } + } + + bb1: { + StorageLive(_2); // scope 1 at $DIR/branch.rs:+3:9: +3:10 + StorageLive(_3); // scope 1 at $DIR/branch.rs:+3:16: +3:22 + _3 = cond() -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/branch.rs:+3:16: +3:22 + // mir::Constant + // + span: $DIR/branch.rs:16:16: 16:20 + // + literal: Const { ty: fn() -> bool {cond}, val: Value() } + } + + bb2: { + switchInt(move _3) -> [0: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22 + } + + bb3: { + _2 = _1; // scope 1 at $DIR/branch.rs:+4:9: +4:10 + goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6 + } + + bb4: { + StorageLive(_4); // scope 1 at $DIR/branch.rs:+6:9: +6:14 + _4 = val() -> [return: bb5, unwind unreachable]; // scope 1 at $DIR/branch.rs:+6:9: +6:14 + // mir::Constant + // + span: $DIR/branch.rs:19:9: 19:12 + // + literal: Const { ty: fn() -> i32 {val}, val: Value() } + } + + bb5: { + StorageDead(_4); // scope 1 at $DIR/branch.rs:+6:14: +6:15 + _2 = _1; // scope 1 at $DIR/branch.rs:+7:9: +7:10 + goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6 + } + + bb6: { + StorageDead(_3); // scope 1 at $DIR/branch.rs:+8:5: +8:6 + _0 = _2; // scope 2 at $DIR/branch.rs:+10:5: +10:6 + StorageDead(_2); // scope 1 at $DIR/branch.rs:+11:1: +11:2 + StorageDead(_1); // scope 0 at $DIR/branch.rs:+11:1: +11:2 + return; // scope 0 at $DIR/branch.rs:+11:2: +11:2 + } + } + diff --git a/tests/mir-opt/copy-prop/branch.foo.CopyProp.diff b/tests/mir-opt/copy-prop/branch.foo.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/branch.foo.CopyProp.diff rename to tests/mir-opt/copy-prop/branch.foo.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/branch.rs b/tests/mir-opt/copy-prop/branch.rs index 0a2e16946345a..c8af1aa7bf9f7 100644 --- a/tests/mir-opt/copy-prop/branch.rs +++ b/tests/mir-opt/copy-prop/branch.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY //! Tests that we bail out when there are multiple assignments to the same local. // unit-test: CopyProp fn val() -> i32 { diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.panic-abort.diff similarity index 100% rename from tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff rename to tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.panic-abort.diff diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.panic-unwind.diff new file mode 100644 index 0000000000000..1c7b6494d6dcc --- /dev/null +++ b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.panic-unwind.diff @@ -0,0 +1,23 @@ +- // MIR for `arg_src` before CopyProp ++ // MIR for `arg_src` after CopyProp + + fn arg_src(_1: i32) -> i32 { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:12: +0:17 + let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30 + let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 + scope 1 { +- debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 ++ debug y => _0; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 +- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 ++ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 + _1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12 +- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 +- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..3c494af01c0a5 --- /dev/null +++ b/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.panic-abort.diff @@ -0,0 +1,28 @@ +- // MIR for `bar` before CopyProp ++ // MIR for `bar` after CopyProp + + fn bar(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13 + let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19 + let _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13 + let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13 + StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 + _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 + _2 = dummy(move _3) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13 + // mir::Constant + // + span: $DIR/copy_propagation_arg.rs:17:5: 17:10 + // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13 + StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 + _1 = const 5_u8; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10 + _0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.diff rename to tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.baz.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.baz.CopyProp.panic-abort.diff similarity index 100% rename from tests/mir-opt/copy-prop/copy_propagation_arg.baz.CopyProp.diff rename to tests/mir-opt/copy-prop/copy_propagation_arg.baz.CopyProp.panic-abort.diff diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.baz.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.baz.CopyProp.panic-unwind.diff new file mode 100644 index 0000000000000..7ab6ebb7d53e0 --- /dev/null +++ b/tests/mir-opt/copy-prop/copy_propagation_arg.baz.CopyProp.panic-unwind.diff @@ -0,0 +1,18 @@ +- // MIR for `baz` before CopyProp ++ // MIR for `baz` after CopyProp + + fn baz(_1: i32) -> i32 { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13 + let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:23: +0:26 + let mut _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + _1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10 + StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..5845be331a5e3 --- /dev/null +++ b/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.panic-abort.diff @@ -0,0 +1,28 @@ +- // MIR for `foo` before CopyProp ++ // MIR for `foo` after CopyProp + + fn foo(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13 + let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19 + let mut _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 + let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 + StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16 + _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16 + _2 = dummy(move _3) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 + // mir::Constant + // + span: $DIR/copy_propagation_arg.rs:12:9: 12:14 + // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17 + _1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17 + StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17 + _0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.diff rename to tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.rs b/tests/mir-opt/copy-prop/copy_propagation_arg.rs index 1b65dcb01ed36..671860da50d25 100644 --- a/tests/mir-opt/copy-prop/copy_propagation_arg.rs +++ b/tests/mir-opt/copy-prop/copy_propagation_arg.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Check that CopyProp does not propagate an assignment to a function argument // (doing so can break usages of the original argument value) // unit-test: CopyProp diff --git a/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..ab13676908525 --- /dev/null +++ b/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.panic-abort.diff @@ -0,0 +1,31 @@ +- // MIR for `f` before CopyProp ++ // MIR for `f` after CopyProp + + fn f(_1: NotCopy) -> () { + let mut _0: (); // return place in scope 0 at $DIR/custom_move_arg.rs:+0:19: +0:19 + let mut _2: NotCopy; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: NotCopy; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { +- _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL +- _0 = opaque::(move _1) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/custom_move_arg.rs:+3:9: +3:41 ++ _0 = opaque::(_1) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/custom_move_arg.rs:+3:9: +3:41 + // mir::Constant + // + span: $DIR/custom_move_arg.rs:16:24: 16:30 + // + literal: Const { ty: fn(NotCopy) {opaque::}, val: Value() } + } + + bb1: { +- _3 = move _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL +- _0 = opaque::(_3) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/custom_move_arg.rs:+7:9: +7:35 ++ _0 = opaque::(_1) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/custom_move_arg.rs:+7:9: +7:35 + // mir::Constant + // + span: $DIR/custom_move_arg.rs:20:24: 20:30 + // + literal: Const { ty: fn(NotCopy) {opaque::}, val: Value() } + } + + bb2: { + return; // scope 0 at $DIR/custom_move_arg.rs:+10:9: +10:17 + } + } + diff --git a/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff b/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff rename to tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/custom_move_arg.rs b/tests/mir-opt/copy-prop/custom_move_arg.rs index 29c368df82d8a..a90db08fa517a 100644 --- a/tests/mir-opt/copy-prop/custom_move_arg.rs +++ b/tests/mir-opt/copy-prop/custom_move_arg.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: CopyProp #![feature(custom_mir, core_intrinsics)] diff --git a/tests/mir-opt/copy-prop/cycle.main.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/cycle.main.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..37158af7648c3 --- /dev/null +++ b/tests/mir-opt/copy-prop/cycle.main.CopyProp.panic-abort.diff @@ -0,0 +1,60 @@ +- // MIR for `main` before CopyProp ++ // MIR for `main` after CopyProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/cycle.rs:+1:9: +1:14 + let mut _4: i32; // in scope 0 at $DIR/cycle.rs:+4:9: +4:10 + let _5: (); // in scope 0 at $DIR/cycle.rs:+6:5: +6:12 + let mut _6: i32; // in scope 0 at $DIR/cycle.rs:+6:10: +6:11 + scope 1 { + debug x => _1; // in scope 1 at $DIR/cycle.rs:+1:9: +1:14 + let _2: i32; // in scope 1 at $DIR/cycle.rs:+2:9: +2:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/cycle.rs:+2:9: +2:10 + let _3: i32; // in scope 2 at $DIR/cycle.rs:+3:9: +3:10 + scope 3 { +- debug z => _3; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10 ++ debug z => _2; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:14 + _1 = val() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/cycle.rs:+1:17: +1:22 + // mir::Constant + // + span: $DIR/cycle.rs:10:17: 10:20 + // + literal: Const { ty: fn() -> i32 {val}, val: Value() } + } + + bb1: { +- StorageLive(_2); // scope 1 at $DIR/cycle.rs:+2:9: +2:10 + _2 = _1; // scope 1 at $DIR/cycle.rs:+2:13: +2:14 +- StorageLive(_3); // scope 2 at $DIR/cycle.rs:+3:9: +3:10 +- _3 = _2; // scope 2 at $DIR/cycle.rs:+3:13: +3:14 +- StorageLive(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10 +- _4 = _3; // scope 3 at $DIR/cycle.rs:+4:9: +4:10 +- _1 = move _4; // scope 3 at $DIR/cycle.rs:+4:5: +4:10 +- StorageDead(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10 ++ _1 = _2; // scope 3 at $DIR/cycle.rs:+4:5: +4:10 + StorageLive(_5); // scope 3 at $DIR/cycle.rs:+6:5: +6:12 + StorageLive(_6); // scope 3 at $DIR/cycle.rs:+6:10: +6:11 + _6 = _1; // scope 3 at $DIR/cycle.rs:+6:10: +6:11 + _5 = std::mem::drop::(move _6) -> [return: bb2, unwind unreachable]; // scope 3 at $DIR/cycle.rs:+6:5: +6:12 + // mir::Constant + // + span: $DIR/cycle.rs:15:5: 15:9 + // + literal: Const { ty: fn(i32) {std::mem::drop::}, val: Value() } + } + + bb2: { + StorageDead(_6); // scope 3 at $DIR/cycle.rs:+6:11: +6:12 + StorageDead(_5); // scope 3 at $DIR/cycle.rs:+6:12: +6:13 + _0 = const (); // scope 0 at $DIR/cycle.rs:+0:11: +7:2 +- StorageDead(_3); // scope 2 at $DIR/cycle.rs:+7:1: +7:2 +- StorageDead(_2); // scope 1 at $DIR/cycle.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/cycle.rs:+7:1: +7:2 + return; // scope 0 at $DIR/cycle.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/copy-prop/cycle.main.CopyProp.diff b/tests/mir-opt/copy-prop/cycle.main.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/cycle.main.CopyProp.diff rename to tests/mir-opt/copy-prop/cycle.main.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/cycle.rs b/tests/mir-opt/copy-prop/cycle.rs index da70f6bec2ebf..56ec7539734fd 100644 --- a/tests/mir-opt/copy-prop/cycle.rs +++ b/tests/mir-opt/copy-prop/cycle.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY //! Tests that cyclic assignments don't hang CopyProp, and result in reasonable code. // unit-test: CopyProp fn val() -> i32 { diff --git a/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.panic-abort.mir b/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.panic-abort.mir new file mode 100644 index 0000000000000..8de0a56c58cd6 --- /dev/null +++ b/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.panic-abort.mir @@ -0,0 +1,29 @@ +// MIR for `f` after CopyProp + +fn f(_1: usize) -> usize { + debug a => _1; // in scope 0 at $DIR/dead_stores_79191.rs:+0:6: +0:11 + let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_79191.rs:+0:23: +0:28 + let _2: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10 + let mut _3: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+3:9: +3:10 + let mut _4: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+4:8: +4:9 + scope 1 { + debug b => _2; // in scope 1 at $DIR/dead_stores_79191.rs:+1:9: +1:10 + } + + bb0: { + _2 = _1; // scope 0 at $DIR/dead_stores_79191.rs:+1:13: +1:14 + _1 = const 5_usize; // scope 1 at $DIR/dead_stores_79191.rs:+2:5: +2:10 + _1 = _2; // scope 1 at $DIR/dead_stores_79191.rs:+3:5: +3:10 + StorageLive(_4); // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9 + _4 = _1; // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9 + _0 = id::(move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/dead_stores_79191.rs:+4:5: +4:10 + // mir::Constant + // + span: $DIR/dead_stores_79191.rs:13:5: 13:7 + // + literal: Const { ty: fn(usize) -> usize {id::}, val: Value() } + } + + bb1: { + StorageDead(_4); // scope 1 at $DIR/dead_stores_79191.rs:+4:9: +4:10 + return; // scope 0 at $DIR/dead_stores_79191.rs:+5:2: +5:2 + } +} diff --git a/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.mir b/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.mir rename to tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.panic-unwind.mir diff --git a/tests/mir-opt/copy-prop/dead_stores_79191.rs b/tests/mir-opt/copy-prop/dead_stores_79191.rs index 84453c55e3ef4..4260d35b19470 100644 --- a/tests/mir-opt/copy-prop/dead_stores_79191.rs +++ b/tests/mir-opt/copy-prop/dead_stores_79191.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: CopyProp fn id(x: T) -> T { diff --git a/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-abort.mir b/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-abort.mir new file mode 100644 index 0000000000000..606b94f3e70f4 --- /dev/null +++ b/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-abort.mir @@ -0,0 +1,29 @@ +// MIR for `f` after CopyProp + +fn f(_1: usize) -> usize { + debug a => _1; // in scope 0 at $DIR/dead_stores_better.rs:+0:10: +0:15 + let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_better.rs:+0:27: +0:32 + let _2: usize; // in scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10 + let mut _3: usize; // in scope 0 at $DIR/dead_stores_better.rs:+3:9: +3:10 + let mut _4: usize; // in scope 0 at $DIR/dead_stores_better.rs:+4:8: +4:9 + scope 1 { + debug b => _2; // in scope 1 at $DIR/dead_stores_better.rs:+1:9: +1:10 + } + + bb0: { + _2 = _1; // scope 0 at $DIR/dead_stores_better.rs:+1:13: +1:14 + _1 = const 5_usize; // scope 1 at $DIR/dead_stores_better.rs:+2:5: +2:10 + _1 = _2; // scope 1 at $DIR/dead_stores_better.rs:+3:5: +3:10 + StorageLive(_4); // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9 + _4 = _1; // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9 + _0 = id::(move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/dead_stores_better.rs:+4:5: +4:10 + // mir::Constant + // + span: $DIR/dead_stores_better.rs:17:5: 17:7 + // + literal: Const { ty: fn(usize) -> usize {id::}, val: Value() } + } + + bb1: { + StorageDead(_4); // scope 1 at $DIR/dead_stores_better.rs:+4:9: +4:10 + return; // scope 0 at $DIR/dead_stores_better.rs:+5:2: +5:2 + } +} diff --git a/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.mir b/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.mir rename to tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-unwind.mir diff --git a/tests/mir-opt/copy-prop/dead_stores_better.rs b/tests/mir-opt/copy-prop/dead_stores_better.rs index 87b916fd3ff84..c5962db6a40de 100644 --- a/tests/mir-opt/copy-prop/dead_stores_better.rs +++ b/tests/mir-opt/copy-prop/dead_stores_better.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // This is a copy of the `dead_stores_79191` test, except that we turn on DSE. This demonstrates // that that pass enables this one to do more optimizations. diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..701cdda0fceb5 --- /dev/null +++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff @@ -0,0 +1,138 @@ +- // MIR for `main` before CopyProp ++ // MIR for `main` after CopyProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_107511.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/issue_107511.rs:+1:9: +1:16 + let mut _3: std::ops::Range; // in scope 0 at $DIR/issue_107511.rs:+6:14: +6:24 + let mut _4: std::ops::Range; // in scope 0 at $DIR/issue_107511.rs:+6:14: +6:24 + let mut _5: usize; // in scope 0 at $DIR/issue_107511.rs:+6:17: +6:24 + let mut _6: &[i32]; // in scope 0 at $DIR/issue_107511.rs:+6:17: +6:24 + let mut _7: &[i32; 4]; // in scope 0 at $DIR/issue_107511.rs:+6:17: +6:24 + let mut _9: (); // in scope 0 at $DIR/issue_107511.rs:+0:1: +9:2 + let _10: (); // in scope 0 at $DIR/issue_107511.rs:+6:14: +6:24 + let mut _11: std::option::Option; // in scope 0 at $DIR/issue_107511.rs:+6:14: +6:24 + let mut _12: &mut std::ops::Range; // in scope 0 at $DIR/issue_107511.rs:+6:14: +6:24 + let mut _13: &mut std::ops::Range; // in scope 0 at $DIR/issue_107511.rs:+6:14: +6:24 + let mut _14: isize; // in scope 0 at $DIR/issue_107511.rs:+6:5: +8:6 + let mut _15: !; // in scope 0 at $DIR/issue_107511.rs:+6:5: +8:6 + let mut _17: i32; // in scope 0 at $DIR/issue_107511.rs:+7:16: +7:20 + let _18: usize; // in scope 0 at $DIR/issue_107511.rs:+7:18: +7:19 + let mut _19: usize; // in scope 0 at $DIR/issue_107511.rs:+7:16: +7:20 + let mut _20: bool; // in scope 0 at $DIR/issue_107511.rs:+7:16: +7:20 + scope 1 { + debug sum => _1; // in scope 1 at $DIR/issue_107511.rs:+1:9: +1:16 + let _2: [i32; 4]; // in scope 1 at $DIR/issue_107511.rs:+2:9: +2:10 + scope 2 { + debug a => _2; // in scope 2 at $DIR/issue_107511.rs:+2:9: +2:10 + let mut _8: std::ops::Range; // in scope 2 at $DIR/issue_107511.rs:+6:14: +6:24 + scope 3 { + debug iter => _8; // in scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + let _16: usize; // in scope 3 at $DIR/issue_107511.rs:+6:9: +6:10 + scope 4 { + debug i => _16; // in scope 4 at $DIR/issue_107511.rs:+6:9: +6:10 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue_107511.rs:+1:9: +1:16 + _1 = const 0_i32; // scope 0 at $DIR/issue_107511.rs:+1:19: +1:20 + StorageLive(_2); // scope 1 at $DIR/issue_107511.rs:+2:9: +2:10 + _2 = [const 0_i32, const 10_i32, const 20_i32, const 30_i32]; // scope 1 at $DIR/issue_107511.rs:+2:13: +2:28 + StorageLive(_3); // scope 2 at $DIR/issue_107511.rs:+6:14: +6:24 + StorageLive(_4); // scope 2 at $DIR/issue_107511.rs:+6:14: +6:24 + StorageLive(_5); // scope 2 at $DIR/issue_107511.rs:+6:17: +6:24 + StorageLive(_6); // scope 2 at $DIR/issue_107511.rs:+6:17: +6:24 + StorageLive(_7); // scope 2 at $DIR/issue_107511.rs:+6:17: +6:24 + _7 = &_2; // scope 2 at $DIR/issue_107511.rs:+6:17: +6:24 + _6 = move _7 as &[i32] (Pointer(Unsize)); // scope 2 at $DIR/issue_107511.rs:+6:17: +6:24 + StorageDead(_7); // scope 2 at $DIR/issue_107511.rs:+6:17: +6:18 + _5 = core::slice::::len(move _6) -> [return: bb1, unwind unreachable]; // scope 2 at $DIR/issue_107511.rs:+6:17: +6:24 + // mir::Constant + // + span: $DIR/issue_107511.rs:11:19: 11:22 + // + literal: Const { ty: for<'a> fn(&'a [i32]) -> usize {core::slice::::len}, val: Value() } + } + + bb1: { + StorageDead(_6); // scope 2 at $DIR/issue_107511.rs:+6:23: +6:24 + _4 = std::ops::Range:: { start: const 0_usize, end: move _5 }; // scope 2 at $DIR/issue_107511.rs:+6:14: +6:24 + StorageDead(_5); // scope 2 at $DIR/issue_107511.rs:+6:23: +6:24 + _3 = as IntoIterator>::into_iter(move _4) -> [return: bb2, unwind unreachable]; // scope 2 at $DIR/issue_107511.rs:+6:14: +6:24 + // mir::Constant + // + span: $DIR/issue_107511.rs:11:14: 11:24 + // + literal: Const { ty: fn(std::ops::Range) -> as IntoIterator>::IntoIter { as IntoIterator>::into_iter}, val: Value() } + } + + bb2: { + StorageDead(_4); // scope 2 at $DIR/issue_107511.rs:+6:23: +6:24 + StorageLive(_8); // scope 2 at $DIR/issue_107511.rs:+6:14: +6:24 + _8 = move _3; // scope 2 at $DIR/issue_107511.rs:+6:14: +6:24 + goto -> bb3; // scope 3 at $DIR/issue_107511.rs:+6:5: +8:6 + } + + bb3: { +- StorageLive(_10); // scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + StorageLive(_11); // scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + StorageLive(_12); // scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + StorageLive(_13); // scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + _13 = &mut _8; // scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + _12 = &mut (*_13); // scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + _11 = as Iterator>::next(move _12) -> [return: bb4, unwind unreachable]; // scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + // mir::Constant + // + span: $DIR/issue_107511.rs:11:14: 11:24 + // + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range) -> Option< as Iterator>::Item> { as Iterator>::next}, val: Value() } + } + + bb4: { + StorageDead(_12); // scope 3 at $DIR/issue_107511.rs:+6:23: +6:24 + _14 = discriminant(_11); // scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + switchInt(move _14) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + } + + bb5: { +- StorageLive(_16); // scope 3 at $DIR/issue_107511.rs:+6:9: +6:10 + _16 = ((_11 as Some).0: usize); // scope 3 at $DIR/issue_107511.rs:+6:9: +6:10 + StorageLive(_17); // scope 4 at $DIR/issue_107511.rs:+7:16: +7:20 +- StorageLive(_18); // scope 4 at $DIR/issue_107511.rs:+7:18: +7:19 +- _18 = _16; // scope 4 at $DIR/issue_107511.rs:+7:18: +7:19 + _19 = Len(_2); // scope 4 at $DIR/issue_107511.rs:+7:16: +7:20 +- _20 = Lt(_18, _19); // scope 4 at $DIR/issue_107511.rs:+7:16: +7:20 +- assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _18) -> [success: bb8, unwind unreachable]; // scope 4 at $DIR/issue_107511.rs:+7:16: +7:20 ++ _20 = Lt(_16, _19); // scope 4 at $DIR/issue_107511.rs:+7:16: +7:20 ++ assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _16) -> [success: bb8, unwind unreachable]; // scope 4 at $DIR/issue_107511.rs:+7:16: +7:20 + } + + bb6: { + unreachable; // scope 3 at $DIR/issue_107511.rs:+6:14: +6:24 + } + + bb7: { + _0 = const (); // scope 3 at $DIR/issue_107511.rs:+6:5: +8:6 + StorageDead(_13); // scope 3 at $DIR/issue_107511.rs:+8:5: +8:6 + StorageDead(_11); // scope 3 at $DIR/issue_107511.rs:+8:5: +8:6 +- StorageDead(_10); // scope 3 at $DIR/issue_107511.rs:+8:5: +8:6 + StorageDead(_8); // scope 2 at $DIR/issue_107511.rs:+8:5: +8:6 + StorageDead(_3); // scope 2 at $DIR/issue_107511.rs:+8:5: +8:6 + StorageDead(_2); // scope 1 at $DIR/issue_107511.rs:+9:1: +9:2 + StorageDead(_1); // scope 0 at $DIR/issue_107511.rs:+9:1: +9:2 + return; // scope 0 at $DIR/issue_107511.rs:+9:2: +9:2 + } + + bb8: { +- _17 = _2[_18]; // scope 4 at $DIR/issue_107511.rs:+7:16: +7:20 ++ _17 = _2[_16]; // scope 4 at $DIR/issue_107511.rs:+7:16: +7:20 + _1 = Add(_1, move _17); // scope 4 at $DIR/issue_107511.rs:+7:9: +7:20 + StorageDead(_17); // scope 4 at $DIR/issue_107511.rs:+7:19: +7:20 +- StorageDead(_18); // scope 4 at $DIR/issue_107511.rs:+7:20: +7:21 +- _10 = const (); // scope 4 at $DIR/issue_107511.rs:+6:25: +8:6 +- StorageDead(_16); // scope 3 at $DIR/issue_107511.rs:+8:5: +8:6 + StorageDead(_13); // scope 3 at $DIR/issue_107511.rs:+8:5: +8:6 + StorageDead(_11); // scope 3 at $DIR/issue_107511.rs:+8:5: +8:6 +- StorageDead(_10); // scope 3 at $DIR/issue_107511.rs:+8:5: +8:6 +- _9 = const (); // scope 3 at $DIR/issue_107511.rs:+6:5: +8:6 + goto -> bb3; // scope 3 at $DIR/issue_107511.rs:+6:5: +8:6 + } + } + diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/issue_107511.main.CopyProp.diff rename to tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/issue_107511.rs b/tests/mir-opt/copy-prop/issue_107511.rs index 2b00ff15581f1..ce6fcc17b5722 100644 --- a/tests/mir-opt/copy-prop/issue_107511.rs +++ b/tests/mir-opt/copy-prop/issue_107511.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: CopyProp // EMIT_MIR issue_107511.main.CopyProp.diff diff --git a/tests/mir-opt/copy-prop/move_arg.f.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/move_arg.f.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..b1ab5b542065c --- /dev/null +++ b/tests/mir-opt/copy-prop/move_arg.f.CopyProp.panic-abort.diff @@ -0,0 +1,40 @@ +- // MIR for `f` before CopyProp ++ // MIR for `f` after CopyProp + + fn f(_1: T) -> () { + debug a => _1; // in scope 0 at $DIR/move_arg.rs:+0:19: +0:20 + let mut _0: (); // return place in scope 0 at $DIR/move_arg.rs:+0:25: +0:25 + let _2: T; // in scope 0 at $DIR/move_arg.rs:+1:9: +1:10 + let _3: (); // in scope 0 at $DIR/move_arg.rs:+2:5: +2:12 + let mut _4: T; // in scope 0 at $DIR/move_arg.rs:+2:7: +2:8 + let mut _5: T; // in scope 0 at $DIR/move_arg.rs:+2:10: +2:11 + scope 1 { +- debug b => _2; // in scope 1 at $DIR/move_arg.rs:+1:9: +1:10 ++ debug b => _1; // in scope 1 at $DIR/move_arg.rs:+1:9: +1:10 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/move_arg.rs:+1:9: +1:10 +- _2 = _1; // scope 0 at $DIR/move_arg.rs:+1:13: +1:14 + StorageLive(_3); // scope 1 at $DIR/move_arg.rs:+2:5: +2:12 +- StorageLive(_4); // scope 1 at $DIR/move_arg.rs:+2:7: +2:8 +- _4 = _1; // scope 1 at $DIR/move_arg.rs:+2:7: +2:8 +- StorageLive(_5); // scope 1 at $DIR/move_arg.rs:+2:10: +2:11 +- _5 = _2; // scope 1 at $DIR/move_arg.rs:+2:10: +2:11 +- _3 = g::(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/move_arg.rs:+2:5: +2:12 ++ _3 = g::(_1, _1) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/move_arg.rs:+2:5: +2:12 + // mir::Constant + // + span: $DIR/move_arg.rs:8:5: 8:6 + // + literal: Const { ty: fn(T, T) {g::}, val: Value() } + } + + bb1: { +- StorageDead(_5); // scope 1 at $DIR/move_arg.rs:+2:11: +2:12 +- StorageDead(_4); // scope 1 at $DIR/move_arg.rs:+2:11: +2:12 + StorageDead(_3); // scope 1 at $DIR/move_arg.rs:+2:12: +2:13 + _0 = const (); // scope 0 at $DIR/move_arg.rs:+0:25: +3:2 +- StorageDead(_2); // scope 0 at $DIR/move_arg.rs:+3:1: +3:2 + return; // scope 0 at $DIR/move_arg.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/copy-prop/move_arg.f.CopyProp.diff b/tests/mir-opt/copy-prop/move_arg.f.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/move_arg.f.CopyProp.diff rename to tests/mir-opt/copy-prop/move_arg.f.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/move_arg.rs b/tests/mir-opt/copy-prop/move_arg.rs index f88d9a9e74bbf..a3a04e57bc1fa 100644 --- a/tests/mir-opt/copy-prop/move_arg.rs +++ b/tests/mir-opt/copy-prop/move_arg.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Test that we do not move multiple times from the same local. // unit-test: CopyProp diff --git a/tests/mir-opt/copy-prop/move_projection.f.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/move_projection.f.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..0871f64efedff --- /dev/null +++ b/tests/mir-opt/copy-prop/move_projection.f.CopyProp.panic-abort.diff @@ -0,0 +1,31 @@ +- // MIR for `f` before CopyProp ++ // MIR for `f` after CopyProp + + fn f(_1: Foo) -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/move_projection.rs:+0:17: +0:21 + let mut _2: Foo; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { +- _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL +- _3 = move (_2.0: u8); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL +- _0 = opaque::(move _1) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/move_projection.rs:+6:13: +6:44 ++ _3 = (_1.0: u8); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL ++ _0 = opaque::(_1) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/move_projection.rs:+6:13: +6:44 + // mir::Constant + // + span: $DIR/move_projection.rs:20:28: 20:34 + // + literal: Const { ty: fn(Foo) -> bool {opaque::}, val: Value() } + } + + bb1: { + _0 = opaque::(move _3) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/move_projection.rs:+9:13: +9:44 + // mir::Constant + // + span: $DIR/move_projection.rs:23:28: 23:34 + // + literal: Const { ty: fn(u8) -> bool {opaque::}, val: Value() } + } + + bb2: { + return; // scope 0 at $DIR/move_projection.rs:+12:13: +12:21 + } + } + diff --git a/tests/mir-opt/copy-prop/move_projection.f.CopyProp.diff b/tests/mir-opt/copy-prop/move_projection.f.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/move_projection.f.CopyProp.diff rename to tests/mir-opt/copy-prop/move_projection.f.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/move_projection.rs b/tests/mir-opt/copy-prop/move_projection.rs index c158c69e0cf8b..40f51ce8406a6 100644 --- a/tests/mir-opt/copy-prop/move_projection.rs +++ b/tests/mir-opt/copy-prop/move_projection.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: CopyProp #![feature(custom_mir, core_intrinsics)] diff --git a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..f4d8e4ed67db8 --- /dev/null +++ b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff @@ -0,0 +1,56 @@ +- // MIR for `demiraw` before CopyProp ++ // MIR for `demiraw` after CopyProp + + fn demiraw(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/reborrow.rs:+0:12: +0:17 + let mut _0: (); // return place in scope 0 at $DIR/reborrow.rs:+0:23: +0:23 + let _2: *mut u8; // in scope 0 at $DIR/reborrow.rs:+1:9: +1:10 + let mut _4: &mut u8; // in scope 0 at $DIR/reborrow.rs:+2:22: +2:29 + let _6: (); // in scope 0 at $DIR/reborrow.rs:+4:5: +4:14 + let mut _7: *mut u8; // in scope 0 at $DIR/reborrow.rs:+4:12: +4:13 + scope 1 { + debug a => _2; // in scope 1 at $DIR/reborrow.rs:+1:9: +1:10 + let _3: &mut u8; // in scope 1 at $DIR/reborrow.rs:+2:9: +2:10 + scope 2 { + debug b => _3; // in scope 2 at $DIR/reborrow.rs:+2:9: +2:10 + let _5: *mut u8; // in scope 2 at $DIR/reborrow.rs:+3:9: +3:10 + scope 4 { +- debug c => _5; // in scope 4 at $DIR/reborrow.rs:+3:9: +3:10 ++ debug c => _2; // in scope 4 at $DIR/reborrow.rs:+3:9: +3:10 + } + } + scope 3 { + } + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/reborrow.rs:+1:9: +1:10 + _2 = &raw mut _1; // scope 0 at $DIR/reborrow.rs:+1:13: +1:23 + StorageLive(_3); // scope 1 at $DIR/reborrow.rs:+2:9: +2:10 + StorageLive(_4); // scope 1 at $DIR/reborrow.rs:+2:22: +2:29 + _4 = &mut (*_2); // scope 3 at $DIR/reborrow.rs:+2:22: +2:29 + _3 = &mut (*_4); // scope 1 at $DIR/reborrow.rs:+2:22: +2:29 + StorageDead(_4); // scope 1 at $DIR/reborrow.rs:+2:31: +2:32 +- StorageLive(_5); // scope 2 at $DIR/reborrow.rs:+3:9: +3:10 +- _5 = _2; // scope 2 at $DIR/reborrow.rs:+3:13: +3:14 + StorageLive(_6); // scope 4 at $DIR/reborrow.rs:+4:5: +4:14 +- StorageLive(_7); // scope 4 at $DIR/reborrow.rs:+4:12: +4:13 +- _7 = _5; // scope 4 at $DIR/reborrow.rs:+4:12: +4:13 +- _6 = opaque::<*mut u8>(move _7) -> [return: bb1, unwind unreachable]; // scope 4 at $DIR/reborrow.rs:+4:5: +4:14 ++ _6 = opaque::<*mut u8>(_2) -> [return: bb1, unwind unreachable]; // scope 4 at $DIR/reborrow.rs:+4:5: +4:14 + // mir::Constant + // + span: $DIR/reborrow.rs:39:5: 39:11 + // + literal: Const { ty: fn(*mut u8) {opaque::<*mut u8>}, val: Value() } + } + + bb1: { +- StorageDead(_7); // scope 4 at $DIR/reborrow.rs:+4:13: +4:14 + StorageDead(_6); // scope 4 at $DIR/reborrow.rs:+4:14: +4:15 + _0 = const (); // scope 0 at $DIR/reborrow.rs:+0:23: +5:2 +- StorageDead(_5); // scope 2 at $DIR/reborrow.rs:+5:1: +5:2 + StorageDead(_3); // scope 1 at $DIR/reborrow.rs:+5:1: +5:2 +- StorageDead(_2); // scope 0 at $DIR/reborrow.rs:+5:1: +5:2 + return; // scope 0 at $DIR/reborrow.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.diff b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.diff rename to tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..3f34ec1600dac --- /dev/null +++ b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff @@ -0,0 +1,52 @@ +- // MIR for `miraw` before CopyProp ++ // MIR for `miraw` after CopyProp + + fn miraw(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/reborrow.rs:+0:10: +0:15 + let mut _0: (); // return place in scope 0 at $DIR/reborrow.rs:+0:21: +0:21 + let _2: *mut u8; // in scope 0 at $DIR/reborrow.rs:+1:9: +1:10 + let _5: (); // in scope 0 at $DIR/reborrow.rs:+4:5: +4:14 + let mut _6: *mut u8; // in scope 0 at $DIR/reborrow.rs:+4:12: +4:13 + scope 1 { + debug a => _2; // in scope 1 at $DIR/reborrow.rs:+1:9: +1:10 + let _3: *mut u8; // in scope 1 at $DIR/reborrow.rs:+2:9: +2:10 + scope 2 { + debug b => _3; // in scope 2 at $DIR/reborrow.rs:+2:9: +2:10 + let _4: *mut u8; // in scope 2 at $DIR/reborrow.rs:+3:9: +3:10 + scope 4 { +- debug c => _4; // in scope 4 at $DIR/reborrow.rs:+3:9: +3:10 ++ debug c => _2; // in scope 4 at $DIR/reborrow.rs:+3:9: +3:10 + } + } + scope 3 { + } + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/reborrow.rs:+1:9: +1:10 + _2 = &raw mut _1; // scope 0 at $DIR/reborrow.rs:+1:13: +1:23 + StorageLive(_3); // scope 1 at $DIR/reborrow.rs:+2:9: +2:10 + _3 = &raw mut (*_2); // scope 3 at $DIR/reborrow.rs:+2:22: +2:33 +- StorageLive(_4); // scope 2 at $DIR/reborrow.rs:+3:9: +3:10 +- _4 = _2; // scope 2 at $DIR/reborrow.rs:+3:13: +3:14 + StorageLive(_5); // scope 4 at $DIR/reborrow.rs:+4:5: +4:14 +- StorageLive(_6); // scope 4 at $DIR/reborrow.rs:+4:12: +4:13 +- _6 = _4; // scope 4 at $DIR/reborrow.rs:+4:12: +4:13 +- _5 = opaque::<*mut u8>(move _6) -> [return: bb1, unwind unreachable]; // scope 4 at $DIR/reborrow.rs:+4:5: +4:14 ++ _5 = opaque::<*mut u8>(_2) -> [return: bb1, unwind unreachable]; // scope 4 at $DIR/reborrow.rs:+4:5: +4:14 + // mir::Constant + // + span: $DIR/reborrow.rs:31:5: 31:11 + // + literal: Const { ty: fn(*mut u8) {opaque::<*mut u8>}, val: Value() } + } + + bb1: { +- StorageDead(_6); // scope 4 at $DIR/reborrow.rs:+4:13: +4:14 + StorageDead(_5); // scope 4 at $DIR/reborrow.rs:+4:14: +4:15 + _0 = const (); // scope 0 at $DIR/reborrow.rs:+0:21: +5:2 +- StorageDead(_4); // scope 2 at $DIR/reborrow.rs:+5:1: +5:2 + StorageDead(_3); // scope 1 at $DIR/reborrow.rs:+5:1: +5:2 +- StorageDead(_2); // scope 0 at $DIR/reborrow.rs:+5:1: +5:2 + return; // scope 0 at $DIR/reborrow.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.diff b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.diff rename to tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..59f87b5b911fe --- /dev/null +++ b/tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-abort.diff @@ -0,0 +1,50 @@ +- // MIR for `remut` before CopyProp ++ // MIR for `remut` after CopyProp + + fn remut(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/reborrow.rs:+0:10: +0:15 + let mut _0: (); // return place in scope 0 at $DIR/reborrow.rs:+0:21: +0:21 + let _2: &mut u8; // in scope 0 at $DIR/reborrow.rs:+1:9: +1:10 + let _5: (); // in scope 0 at $DIR/reborrow.rs:+4:5: +4:14 + let mut _6: &mut u8; // in scope 0 at $DIR/reborrow.rs:+4:12: +4:13 + scope 1 { + debug a => _2; // in scope 1 at $DIR/reborrow.rs:+1:9: +1:10 + let _3: &mut u8; // in scope 1 at $DIR/reborrow.rs:+2:9: +2:10 + scope 2 { + debug b => _3; // in scope 2 at $DIR/reborrow.rs:+2:9: +2:10 + let _4: &mut u8; // in scope 2 at $DIR/reborrow.rs:+3:9: +3:10 + scope 3 { +- debug c => _4; // in scope 3 at $DIR/reborrow.rs:+3:9: +3:10 ++ debug c => _2; // in scope 3 at $DIR/reborrow.rs:+3:9: +3:10 + } + } + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/reborrow.rs:+1:9: +1:10 + _2 = &mut _1; // scope 0 at $DIR/reborrow.rs:+1:13: +1:19 + StorageLive(_3); // scope 1 at $DIR/reborrow.rs:+2:9: +2:10 + _3 = &mut (*_2); // scope 1 at $DIR/reborrow.rs:+2:13: +2:20 +- StorageLive(_4); // scope 2 at $DIR/reborrow.rs:+3:9: +3:10 +- _4 = move _2; // scope 2 at $DIR/reborrow.rs:+3:13: +3:14 + StorageLive(_5); // scope 3 at $DIR/reborrow.rs:+4:5: +4:14 +- StorageLive(_6); // scope 3 at $DIR/reborrow.rs:+4:12: +4:13 +- _6 = move _4; // scope 3 at $DIR/reborrow.rs:+4:12: +4:13 +- _5 = opaque::<&mut u8>(move _6) -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/reborrow.rs:+4:5: +4:14 ++ _5 = opaque::<&mut u8>(move _2) -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/reborrow.rs:+4:5: +4:14 + // mir::Constant + // + span: $DIR/reborrow.rs:15:5: 15:11 + // + literal: Const { ty: fn(&mut u8) {opaque::<&mut u8>}, val: Value() } + } + + bb1: { +- StorageDead(_6); // scope 3 at $DIR/reborrow.rs:+4:13: +4:14 + StorageDead(_5); // scope 3 at $DIR/reborrow.rs:+4:14: +4:15 + _0 = const (); // scope 0 at $DIR/reborrow.rs:+0:21: +5:2 +- StorageDead(_4); // scope 2 at $DIR/reborrow.rs:+5:1: +5:2 + StorageDead(_3); // scope 1 at $DIR/reborrow.rs:+5:1: +5:2 +- StorageDead(_2); // scope 0 at $DIR/reborrow.rs:+5:1: +5:2 + return; // scope 0 at $DIR/reborrow.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/copy-prop/reborrow.remut.CopyProp.diff b/tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/reborrow.remut.CopyProp.diff rename to tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.panic-abort.diff new file mode 100644 index 0000000000000..08bb6d8b22b0a --- /dev/null +++ b/tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.panic-abort.diff @@ -0,0 +1,50 @@ +- // MIR for `reraw` before CopyProp ++ // MIR for `reraw` after CopyProp + + fn reraw(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/reborrow.rs:+0:10: +0:15 + let mut _0: (); // return place in scope 0 at $DIR/reborrow.rs:+0:21: +0:21 + let _2: &mut u8; // in scope 0 at $DIR/reborrow.rs:+1:9: +1:10 + let _5: (); // in scope 0 at $DIR/reborrow.rs:+4:5: +4:14 + let mut _6: &mut u8; // in scope 0 at $DIR/reborrow.rs:+4:12: +4:13 + scope 1 { + debug a => _2; // in scope 1 at $DIR/reborrow.rs:+1:9: +1:10 + let _3: *mut u8; // in scope 1 at $DIR/reborrow.rs:+2:9: +2:10 + scope 2 { + debug b => _3; // in scope 2 at $DIR/reborrow.rs:+2:9: +2:10 + let _4: &mut u8; // in scope 2 at $DIR/reborrow.rs:+3:9: +3:10 + scope 3 { +- debug c => _4; // in scope 3 at $DIR/reborrow.rs:+3:9: +3:10 ++ debug c => _2; // in scope 3 at $DIR/reborrow.rs:+3:9: +3:10 + } + } + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/reborrow.rs:+1:9: +1:10 + _2 = &mut _1; // scope 0 at $DIR/reborrow.rs:+1:13: +1:19 + StorageLive(_3); // scope 1 at $DIR/reborrow.rs:+2:9: +2:10 + _3 = &raw mut (*_2); // scope 1 at $DIR/reborrow.rs:+2:13: +2:24 +- StorageLive(_4); // scope 2 at $DIR/reborrow.rs:+3:9: +3:10 +- _4 = move _2; // scope 2 at $DIR/reborrow.rs:+3:13: +3:14 + StorageLive(_5); // scope 3 at $DIR/reborrow.rs:+4:5: +4:14 +- StorageLive(_6); // scope 3 at $DIR/reborrow.rs:+4:12: +4:13 +- _6 = move _4; // scope 3 at $DIR/reborrow.rs:+4:12: +4:13 +- _5 = opaque::<&mut u8>(move _6) -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/reborrow.rs:+4:5: +4:14 ++ _5 = opaque::<&mut u8>(move _2) -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/reborrow.rs:+4:5: +4:14 + // mir::Constant + // + span: $DIR/reborrow.rs:23:5: 23:11 + // + literal: Const { ty: fn(&mut u8) {opaque::<&mut u8>}, val: Value() } + } + + bb1: { +- StorageDead(_6); // scope 3 at $DIR/reborrow.rs:+4:13: +4:14 + StorageDead(_5); // scope 3 at $DIR/reborrow.rs:+4:14: +4:15 + _0 = const (); // scope 0 at $DIR/reborrow.rs:+0:21: +5:2 +- StorageDead(_4); // scope 2 at $DIR/reborrow.rs:+5:1: +5:2 + StorageDead(_3); // scope 1 at $DIR/reborrow.rs:+5:1: +5:2 +- StorageDead(_2); // scope 0 at $DIR/reborrow.rs:+5:1: +5:2 + return; // scope 0 at $DIR/reborrow.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.diff b/tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.diff rename to tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.panic-unwind.diff diff --git a/tests/mir-opt/copy-prop/reborrow.rs b/tests/mir-opt/copy-prop/reborrow.rs index 91b77966ba845..c37ba5e5c4ca2 100644 --- a/tests/mir-opt/copy-prop/reborrow.rs +++ b/tests/mir-opt/copy-prop/reborrow.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Check that CopyProp considers reborrows as not mutating the pointer. // unit-test: CopyProp diff --git a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-abort.diff new file mode 100644 index 0000000000000..be96743c36279 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-abort.diff @@ -0,0 +1,80 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/checked.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/checked.rs:+1:9: +1:10 + let mut _4: i32; // in scope 0 at $DIR/checked.rs:+3:13: +3:14 + let mut _5: i32; // in scope 0 at $DIR/checked.rs:+3:17: +3:18 + let mut _6: (i32, bool); // in scope 0 at $DIR/checked.rs:+3:13: +3:18 + let mut _9: i32; // in scope 0 at $DIR/checked.rs:+6:13: +6:14 + let mut _10: (i32, bool); // in scope 0 at $DIR/checked.rs:+6:13: +6:18 + scope 1 { + debug a => _1; // in scope 1 at $DIR/checked.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/checked.rs:+2:9: +2:10 + scope 2 { + debug b => _2; // in scope 2 at $DIR/checked.rs:+2:9: +2:10 + let _3: i32; // in scope 2 at $DIR/checked.rs:+3:9: +3:10 + scope 3 { + debug c => _3; // in scope 3 at $DIR/checked.rs:+3:9: +3:10 + let _7: i32; // in scope 3 at $DIR/checked.rs:+5:9: +5:10 + scope 4 { + debug d => _7; // in scope 4 at $DIR/checked.rs:+5:9: +5:10 + let _8: i32; // in scope 4 at $DIR/checked.rs:+6:9: +6:10 + scope 5 { + debug e => _8; // in scope 5 at $DIR/checked.rs:+6:9: +6:10 + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/checked.rs:+1:9: +1:10 + _1 = const 1_i32; // scope 0 at $DIR/checked.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/checked.rs:+2:9: +2:10 + _2 = const 2_i32; // scope 1 at $DIR/checked.rs:+2:13: +2:14 + StorageLive(_3); // scope 2 at $DIR/checked.rs:+3:9: +3:10 + StorageLive(_4); // scope 2 at $DIR/checked.rs:+3:13: +3:14 +- _4 = _1; // scope 2 at $DIR/checked.rs:+3:13: +3:14 ++ _4 = const 1_i32; // scope 2 at $DIR/checked.rs:+3:13: +3:14 + StorageLive(_5); // scope 2 at $DIR/checked.rs:+3:17: +3:18 +- _5 = _2; // scope 2 at $DIR/checked.rs:+3:17: +3:18 +- _6 = CheckedAdd(_4, _5); // scope 2 at $DIR/checked.rs:+3:13: +3:18 +- assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> [success: bb1, unwind unreachable]; // scope 2 at $DIR/checked.rs:+3:13: +3:18 ++ _5 = const 2_i32; // scope 2 at $DIR/checked.rs:+3:17: +3:18 ++ _6 = CheckedAdd(const 1_i32, const 2_i32); // scope 2 at $DIR/checked.rs:+3:13: +3:18 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> [success: bb1, unwind unreachable]; // scope 2 at $DIR/checked.rs:+3:13: +3:18 + } + + bb1: { +- _3 = move (_6.0: i32); // scope 2 at $DIR/checked.rs:+3:13: +3:18 ++ _3 = const 3_i32; // scope 2 at $DIR/checked.rs:+3:13: +3:18 + StorageDead(_5); // scope 2 at $DIR/checked.rs:+3:17: +3:18 + StorageDead(_4); // scope 2 at $DIR/checked.rs:+3:17: +3:18 + StorageLive(_7); // scope 3 at $DIR/checked.rs:+5:9: +5:10 + _7 = const _; // scope 3 at $DIR/checked.rs:+5:13: +5:21 + StorageLive(_8); // scope 4 at $DIR/checked.rs:+6:9: +6:10 + StorageLive(_9); // scope 4 at $DIR/checked.rs:+6:13: +6:14 +- _9 = _7; // scope 4 at $DIR/checked.rs:+6:13: +6:14 +- _10 = CheckedAdd(_9, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18 +- assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> [success: bb2, unwind unreachable]; // scope 4 at $DIR/checked.rs:+6:13: +6:18 ++ _9 = const i32::MAX; // scope 4 at $DIR/checked.rs:+6:13: +6:14 ++ _10 = CheckedAdd(const i32::MAX, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18 ++ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> [success: bb2, unwind unreachable]; // scope 4 at $DIR/checked.rs:+6:13: +6:18 + } + + bb2: { +- _8 = move (_10.0: i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18 ++ _8 = const i32::MIN; // scope 4 at $DIR/checked.rs:+6:13: +6:18 + StorageDead(_9); // scope 4 at $DIR/checked.rs:+6:17: +6:18 + _0 = const (); // scope 0 at $DIR/checked.rs:+0:11: +7:2 + StorageDead(_8); // scope 4 at $DIR/checked.rs:+7:1: +7:2 + StorageDead(_7); // scope 3 at $DIR/checked.rs:+7:1: +7:2 + StorageDead(_3); // scope 2 at $DIR/checked.rs:+7:1: +7:2 + StorageDead(_2); // scope 1 at $DIR/checked.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/checked.rs:+7:1: +7:2 + return; // scope 0 at $DIR/checked.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff rename to tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff diff --git a/tests/mir-opt/dataflow-const-prop/checked.rs b/tests/mir-opt/dataflow-const-prop/checked.rs index 0f9f5a97faca2..1c301460f5d6a 100644 --- a/tests/mir-opt/dataflow-const-prop/checked.rs +++ b/tests/mir-opt/dataflow-const-prop/checked.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp // compile-flags: -Coverflow-checks=on diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff new file mode 100644 index 0000000000000..ff95cba98ad6b --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff @@ -0,0 +1,39 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inherit_overflow.rs:+0:11: +0:11 + let mut _1: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + let mut _2: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + let mut _3: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + scope 1 { + } + scope 2 (inlined ::add) { // at $DIR/inherit_overflow.rs:9:13: 9:47 + debug self => _2; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + debug other => _3; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + let mut _4: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageLive(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + _2 = const u8::MAX; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageLive(_3); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + _3 = const 1_u8; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 +- _4 = CheckedAdd(_2, _3); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL +- assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL ++ _4 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL ++ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + } + + bb1: { +- _1 = move (_4.0: u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL ++ _1 = const 0_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + StorageDead(_3); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageDead(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:47: +3:48 + _0 = const (); // scope 0 at $DIR/inherit_overflow.rs:+0:11: +4:2 + return; // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff rename to tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs index 90349d5270cc8..964c58966f009 100644 --- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs +++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp // compile-flags: -Zmir-enable-passes=+Inline diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-abort.diff new file mode 100644 index 0000000000000..7a9ab39e0e59c --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-abort.diff @@ -0,0 +1,55 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/ref_without_sb.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/ref_without_sb.rs:+1:9: +1:14 + let _2: (); // in scope 0 at $DIR/ref_without_sb.rs:+2:5: +2:15 + let mut _3: &i32; // in scope 0 at $DIR/ref_without_sb.rs:+2:12: +2:14 + let _4: &i32; // in scope 0 at $DIR/ref_without_sb.rs:+2:12: +2:14 + let _5: (); // in scope 0 at $DIR/ref_without_sb.rs:+4:5: +4:20 + scope 1 { + debug a => _1; // in scope 1 at $DIR/ref_without_sb.rs:+1:9: +1:14 + let _6: i32; // in scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10 + scope 2 { + debug b => _6; // in scope 2 at $DIR/ref_without_sb.rs:+6:9: +6:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/ref_without_sb.rs:+1:9: +1:14 + _1 = const 0_i32; // scope 0 at $DIR/ref_without_sb.rs:+1:17: +1:18 + StorageLive(_2); // scope 1 at $DIR/ref_without_sb.rs:+2:5: +2:15 + StorageLive(_3); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14 + StorageLive(_4); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14 + _4 = &_1; // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14 + _3 = &(*_4); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14 + _2 = escape::(move _3) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/ref_without_sb.rs:+2:5: +2:15 + // mir::Constant + // + span: $DIR/ref_without_sb.rs:13:5: 13:11 + // + literal: Const { ty: for<'a> fn(&'a i32) {escape::}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 1 at $DIR/ref_without_sb.rs:+2:14: +2:15 + StorageDead(_4); // scope 1 at $DIR/ref_without_sb.rs:+2:15: +2:16 + StorageDead(_2); // scope 1 at $DIR/ref_without_sb.rs:+2:15: +2:16 + _1 = const 1_i32; // scope 1 at $DIR/ref_without_sb.rs:+3:5: +3:10 + StorageLive(_5); // scope 1 at $DIR/ref_without_sb.rs:+4:5: +4:20 + _5 = some_function() -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/ref_without_sb.rs:+4:5: +4:20 + // mir::Constant + // + span: $DIR/ref_without_sb.rs:15:5: 15:18 + // + literal: Const { ty: fn() {some_function}, val: Value() } + } + + bb2: { + StorageDead(_5); // scope 1 at $DIR/ref_without_sb.rs:+4:20: +4:21 + StorageLive(_6); // scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10 + _6 = _1; // scope 1 at $DIR/ref_without_sb.rs:+6:13: +6:14 + _0 = const (); // scope 0 at $DIR/ref_without_sb.rs:+0:11: +7:2 + StorageDead(_6); // scope 1 at $DIR/ref_without_sb.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/ref_without_sb.rs:+7:1: +7:2 + return; // scope 0 at $DIR/ref_without_sb.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff rename to tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-unwind.diff diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs index f53de3cf2d4cf..4ac0a5b3298ac 100644 --- a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs +++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp #[inline(never)] diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff new file mode 100644 index 0000000000000..ee857e716e2c0 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff @@ -0,0 +1,54 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/sibling_ptr.rs:+0:11: +0:11 + let mut _1: (u8, u8); // in scope 0 at $DIR/sibling_ptr.rs:+1:9: +1:14 + let _2: (); // in scope 0 at $DIR/sibling_ptr.rs:+2:5: +5:6 + let mut _4: *mut u8; // in scope 0 at $DIR/sibling_ptr.rs:+4:10: +4:18 + let mut _5: *mut u8; // in scope 0 at $DIR/sibling_ptr.rs:+4:10: +4:11 + scope 1 { + debug x => _1; // in scope 1 at $DIR/sibling_ptr.rs:+1:9: +1:14 + let _6: u8; // in scope 1 at $DIR/sibling_ptr.rs:+6:9: +6:11 + scope 2 { + let _3: *mut u8; // in scope 2 at $DIR/sibling_ptr.rs:+3:13: +3:14 + scope 3 { + debug p => _3; // in scope 3 at $DIR/sibling_ptr.rs:+3:13: +3:14 + } + } + scope 4 { + debug x1 => _6; // in scope 4 at $DIR/sibling_ptr.rs:+6:9: +6:11 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/sibling_ptr.rs:+1:9: +1:14 + _1 = (const 0_u8, const 0_u8); // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33 + StorageLive(_2); // scope 1 at $DIR/sibling_ptr.rs:+2:5: +5:6 + StorageLive(_3); // scope 2 at $DIR/sibling_ptr.rs:+3:13: +3:14 + _3 = &raw mut (_1.0: u8); // scope 2 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageLive(_4); // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18 + StorageLive(_5); // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11 + _5 = _3; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11 + _4 = ptr::mut_ptr::::add(move _5, const 1_usize) -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18 + // mir::Constant + // + span: $DIR/sibling_ptr.rs:16:12: 16:15 + // + literal: Const { ty: unsafe fn(*mut u8, usize) -> *mut u8 {ptr::mut_ptr::::add}, val: Value() } + } + + bb1: { + StorageDead(_5); // scope 3 at $DIR/sibling_ptr.rs:+4:17: +4:18 + (*_4) = const 1_u8; // scope 3 at $DIR/sibling_ptr.rs:+4:9: +4:22 + StorageDead(_4); // scope 3 at $DIR/sibling_ptr.rs:+4:22: +4:23 + _2 = const (); // scope 2 at $DIR/sibling_ptr.rs:+2:5: +5:6 + StorageDead(_3); // scope 2 at $DIR/sibling_ptr.rs:+5:5: +5:6 + StorageDead(_2); // scope 1 at $DIR/sibling_ptr.rs:+5:5: +5:6 + StorageLive(_6); // scope 1 at $DIR/sibling_ptr.rs:+6:9: +6:11 + _6 = (_1.1: u8); // scope 1 at $DIR/sibling_ptr.rs:+6:14: +6:17 + _0 = const (); // scope 0 at $DIR/sibling_ptr.rs:+0:11: +7:2 + StorageDead(_6); // scope 1 at $DIR/sibling_ptr.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/sibling_ptr.rs:+7:1: +7:2 + return; // scope 0 at $DIR/sibling_ptr.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff rename to tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs index 81fc3c2f49c7c..87842f347e48c 100644 --- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // This attempts to modify `x.1` via a pointer derived from `addr_of_mut!(x.0)`. // According to Miri, that is UB. However, T-opsem has not finalized that // decision and as such we cannot rely on it in optimizations. Consequently, diff --git a/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.panic-abort.diff new file mode 100644 index 0000000000000..94e9595a0e332 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.panic-abort.diff @@ -0,0 +1,40 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/terminator.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/terminator.rs:+1:9: +1:10 + let _2: (); // in scope 0 at $DIR/terminator.rs:+3:5: +3:15 + let mut _3: i32; // in scope 0 at $DIR/terminator.rs:+3:9: +3:14 + let mut _4: i32; // in scope 0 at $DIR/terminator.rs:+3:9: +3:10 + scope 1 { + debug a => _1; // in scope 1 at $DIR/terminator.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/terminator.rs:+1:9: +1:10 + _1 = const 1_i32; // scope 0 at $DIR/terminator.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/terminator.rs:+3:5: +3:15 + StorageLive(_3); // scope 1 at $DIR/terminator.rs:+3:9: +3:14 + StorageLive(_4); // scope 1 at $DIR/terminator.rs:+3:9: +3:10 +- _4 = _1; // scope 1 at $DIR/terminator.rs:+3:9: +3:10 +- _3 = Add(move _4, const 1_i32); // scope 1 at $DIR/terminator.rs:+3:9: +3:14 ++ _4 = const 1_i32; // scope 1 at $DIR/terminator.rs:+3:9: +3:10 ++ _3 = const 2_i32; // scope 1 at $DIR/terminator.rs:+3:9: +3:14 + StorageDead(_4); // scope 1 at $DIR/terminator.rs:+3:13: +3:14 +- _2 = foo(move _3) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/terminator.rs:+3:5: +3:15 ++ _2 = foo(const 2_i32) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/terminator.rs:+3:5: +3:15 + // mir::Constant + // + span: $DIR/terminator.rs:10:5: 10:8 + // + literal: Const { ty: fn(i32) {foo}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 1 at $DIR/terminator.rs:+3:14: +3:15 + StorageDead(_2); // scope 1 at $DIR/terminator.rs:+3:15: +3:16 + _0 = const (); // scope 0 at $DIR/terminator.rs:+0:11: +4:2 + StorageDead(_1); // scope 0 at $DIR/terminator.rs:+4:1: +4:2 + return; // scope 0 at $DIR/terminator.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff rename to tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.panic-unwind.diff diff --git a/tests/mir-opt/dataflow-const-prop/terminator.rs b/tests/mir-opt/dataflow-const-prop/terminator.rs index 4f001df35f14d..114dbeca5acf1 100644 --- a/tests/mir-opt/dataflow-const-prop/terminator.rs +++ b/tests/mir-opt/dataflow-const-prop/terminator.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp fn foo(n: i32) {} diff --git a/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-abort.diff b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-abort.diff new file mode 100644 index 0000000000000..23cd812cabe54 --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-abort.diff @@ -0,0 +1,76 @@ +- // MIR for `cycle` before DeadStoreElimination ++ // MIR for `cycle` after DeadStoreElimination + + fn cycle(_1: i32, _2: i32, _3: i32) -> () { + debug x => _1; // in scope 0 at $DIR/cycle.rs:+0:10: +0:15 + debug y => _2; // in scope 0 at $DIR/cycle.rs:+0:22: +0:27 + debug z => _3; // in scope 0 at $DIR/cycle.rs:+0:34: +0:39 + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:46: +0:46 +- let mut _4: (); // in scope 0 at $DIR/cycle.rs:+0:1: +9:2 +- let mut _5: bool; // in scope 0 at $DIR/cycle.rs:+3:11: +3:17 +- let _6: i32; // in scope 0 at $DIR/cycle.rs:+4:13: +4:17 +- let mut _7: i32; // in scope 0 at $DIR/cycle.rs:+5:13: +5:14 +- let mut _8: i32; // in scope 0 at $DIR/cycle.rs:+6:13: +6:14 +- let mut _9: i32; // in scope 0 at $DIR/cycle.rs:+7:13: +7:17 +- let mut _10: !; // in scope 0 at $DIR/cycle.rs:+3:5: +8:6 +- let _11: (); // in scope 0 at $DIR/cycle.rs:+3:5: +8:6 +- let mut _12: !; // in scope 0 at $DIR/cycle.rs:+3:5: +8:6 ++ let mut _4: bool; // in scope 0 at $DIR/cycle.rs:+3:11: +3:17 ++ let _5: i32; // in scope 0 at $DIR/cycle.rs:+4:13: +4:17 + scope 1 { +- debug temp => _6; // in scope 1 at $DIR/cycle.rs:+4:13: +4:17 ++ debug temp => _5; // in scope 1 at $DIR/cycle.rs:+4:13: +4:17 + } + + bb0: { + goto -> bb1; // scope 0 at $DIR/cycle.rs:+3:5: +8:6 + } + + bb1: { +- StorageLive(_5); // scope 0 at $DIR/cycle.rs:+3:11: +3:17 +- _5 = cond() -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 ++ StorageLive(_4); // scope 0 at $DIR/cycle.rs:+3:11: +3:17 ++ _4 = cond() -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 + // mir::Constant + // + span: $DIR/cycle.rs:13:11: 13:15 + // + literal: Const { ty: fn() -> bool {cond}, val: Value() } + } + + bb2: { +- switchInt(move _5) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 ++ switchInt(move _4) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 + } + + bb3: { +- StorageLive(_6); // scope 0 at $DIR/cycle.rs:+4:13: +4:17 +- _6 = _3; // scope 0 at $DIR/cycle.rs:+4:20: +4:21 +- StorageLive(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14 +- _7 = _2; // scope 1 at $DIR/cycle.rs:+5:13: +5:14 +- _3 = move _7; // scope 1 at $DIR/cycle.rs:+5:9: +5:14 +- StorageDead(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14 +- StorageLive(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14 +- _8 = _1; // scope 1 at $DIR/cycle.rs:+6:13: +6:14 +- _2 = move _8; // scope 1 at $DIR/cycle.rs:+6:9: +6:14 +- StorageDead(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14 +- StorageLive(_9); // scope 1 at $DIR/cycle.rs:+7:13: +7:17 +- _9 = _6; // scope 1 at $DIR/cycle.rs:+7:13: +7:17 +- _1 = move _9; // scope 1 at $DIR/cycle.rs:+7:9: +7:17 +- StorageDead(_9); // scope 1 at $DIR/cycle.rs:+7:16: +7:17 +- _4 = const (); // scope 0 at $DIR/cycle.rs:+3:18: +8:6 +- StorageDead(_6); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 ++ StorageLive(_5); // scope 0 at $DIR/cycle.rs:+4:13: +4:17 + StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 ++ StorageDead(_4); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 + goto -> bb1; // scope 0 at $DIR/cycle.rs:+3:5: +8:6 + } + + bb4: { +- StorageLive(_11); // scope 0 at $DIR/cycle.rs:+3:5: +8:6 + _0 = const (); // scope 0 at $DIR/cycle.rs:+3:5: +8:6 +- StorageDead(_11); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 +- StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 ++ StorageDead(_4); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 + return; // scope 0 at $DIR/cycle.rs:+9:2: +9:2 + } + } + diff --git a/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff rename to tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-unwind.diff diff --git a/tests/mir-opt/dead-store-elimination/cycle.rs b/tests/mir-opt/dead-store-elimination/cycle.rs index 570bfe84d1064..cd34fe96e8c64 100644 --- a/tests/mir-opt/dead-store-elimination/cycle.rs +++ b/tests/mir-opt/dead-store-elimination/cycle.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DeadStoreElimination #[inline(never)] diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff new file mode 100644 index 0000000000000..89de03000ae70 --- /dev/null +++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff @@ -0,0 +1,100 @@ +- // MIR for `is_line_doc_comment_2` before DeduplicateBlocks ++ // MIR for `is_line_doc_comment_2` after DeduplicateBlocks + + fn is_line_doc_comment_2(_1: &str) -> bool { + debug s => _1; // in scope 0 at $DIR/deduplicate_blocks.rs:+0:36: +0:37 + let mut _0: bool; // return place in scope 0 at $DIR/deduplicate_blocks.rs:+0:48: +0:52 + let mut _2: &[u8]; // in scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + let mut _3: &str; // in scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + let mut _4: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + let mut _5: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + let mut _6: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + let mut _7: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + let mut _8: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + let mut _9: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + StorageLive(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + _3 = &(*_1); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + _2 = core::str::::as_bytes(move _3) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + // mir::Constant + // + span: $DIR/deduplicate_blocks.rs:6:13: 6:21 + // + literal: Const { ty: for<'a> fn(&'a str) -> &'a [u8] {core::str::::as_bytes}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:22: +1:23 + _7 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + _8 = const 4_usize; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + _9 = Ge(move _7, move _8); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + switchInt(move _9) -> [0: bb6, otherwise: bb2]; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + } + + bb2: { + switchInt((*_2)[0 of 4]) -> [47: bb3, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb3: { + switchInt((*_2)[1 of 4]) -> [47: bb4, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb4: { + switchInt((*_2)[2 of 4]) -> [47: bb5, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb5: { +- switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 ++ switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb6: { + _4 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + _5 = const 3_usize; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + _6 = Ge(move _4, move _5); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + switchInt(move _6) -> [0: bb10, otherwise: bb7]; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + } + + bb7: { + switchInt((*_2)[0 of 3]) -> [47: bb8, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb8: { + switchInt((*_2)[1 of 3]) -> [47: bb9, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb9: { +- switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 ++ switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb10: { +- _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19 +- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19 +- } +- +- bb11: { + _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46 +- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46 ++ goto -> bb12; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46 + } + +- bb12: { +- _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39 +- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39 +- } +- +- bb13: { ++ bb11: { + _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39 +- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39 ++ goto -> bb12; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39 + } + +- bb14: { ++ bb12: { + StorageDead(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+7:1: +7:2 + return; // scope 0 at $DIR/deduplicate_blocks.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff similarity index 100% rename from tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff rename to tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff diff --git a/tests/mir-opt/deduplicate_blocks.rs b/tests/mir-opt/deduplicate_blocks.rs index 46012e19aa4bf..0c38c7f215e0a 100644 --- a/tests/mir-opt/deduplicate_blocks.rs +++ b/tests/mir-opt/deduplicate_blocks.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DeduplicateBlocks // EMIT_MIR deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff diff --git a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff new file mode 100644 index 0000000000000..6458b06f0e08e --- /dev/null +++ b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff @@ -0,0 +1,109 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_complex_case.rs:+0:11: +0:11 + let mut _1: std::slice::Iter<'_, i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _2: &[i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let _3: [i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:+1:18: +1:26 + let mut _4: std::slice::Iter<'_, i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _5: (); // in scope 0 at $DIR/derefer_complex_case.rs:+0:1: +2:2 + let _6: (); // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _7: std::option::Option<&i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _8: &mut std::slice::Iter<'_, i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _9: &mut std::slice::Iter<'_, i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _10: isize; // in scope 0 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + let mut _11: !; // in scope 0 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + let mut _13: i32; // in scope 0 at $DIR/derefer_complex_case.rs:+1:34: +1:37 + let mut _14: &[i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 ++ let mut _15: &i32; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + scope 1 { + debug iter => _4; // in scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let _12: i32; // in scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 + scope 2 { + debug foo => _12; // in scope 2 at $DIR/derefer_complex_case.rs:+1:10: +1:13 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + StorageLive(_2); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _14 = const _; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:6:17: 6:26 + // + literal: Const { ty: &[i32; 2], val: Unevaluated(main, [], Some(promoted[0])) } + _2 = &(*_14); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _1 = <&[i32; 2] as IntoIterator>::into_iter(move _2) -> [return: bb1, unwind: bb8]; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:6:17: 6:26 + // + literal: Const { ty: fn(&[i32; 2]) -> <&[i32; 2] as IntoIterator>::IntoIter {<&[i32; 2] as IntoIterator>::into_iter}, val: Value() } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/derefer_complex_case.rs:+1:25: +1:26 + StorageLive(_4); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _4 = move _1; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + goto -> bb2; // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + } + + bb2: { + StorageLive(_6); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + StorageLive(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + StorageLive(_8); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + StorageLive(_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _9 = &mut _4; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _8 = &mut (*_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _7 = as Iterator>::next(move _8) -> [return: bb3, unwind: bb8]; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:6:17: 6:26 + // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, i32>) -> Option< as Iterator>::Item> { as Iterator>::next}, val: Value() } + } + + bb3: { + StorageDead(_8); // scope 1 at $DIR/derefer_complex_case.rs:+1:25: +1:26 + _10 = discriminant(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + } + + bb4: { + StorageLive(_12); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 +- _12 = (*((_7 as Some).0: &i32)); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 ++ _15 = deref_copy ((_7 as Some).0: &i32); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 ++ _12 = (*_15); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 + StorageLive(_13); // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37 + _13 = _12; // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37 + _6 = std::mem::drop::(move _13) -> [return: bb7, unwind: bb8]; // scope 2 at $DIR/derefer_complex_case.rs:+1:29: +1:38 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:6:29: 6:33 + // + literal: Const { ty: fn(i32) {std::mem::drop::}, val: Value() } + } + + bb5: { + unreachable; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + } + + bb6: { + _0 = const (); // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + StorageDead(_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_6); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_4); // scope 0 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_1); // scope 0 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + return; // scope 0 at $DIR/derefer_complex_case.rs:+2:2: +2:2 + } + + bb7: { + StorageDead(_13); // scope 2 at $DIR/derefer_complex_case.rs:+1:37: +1:38 + StorageDead(_12); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_6); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + _5 = const (); // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + goto -> bb2; // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + } + + bb8 (cleanup): { + resume; // scope 0 at $DIR/derefer_complex_case.rs:+0:1: +2:2 + } + } + diff --git a/tests/mir-opt/derefer_complex_case.main.Derefer.diff b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff similarity index 100% rename from tests/mir-opt/derefer_complex_case.main.Derefer.diff rename to tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff diff --git a/tests/mir-opt/derefer_complex_case.rs b/tests/mir-opt/derefer_complex_case.rs index dc48cee950bc9..cc619879ef3a7 100644 --- a/tests/mir-opt/derefer_complex_case.rs +++ b/tests/mir-opt/derefer_complex_case.rs @@ -1,6 +1,6 @@ // unit-test: Derefer // EMIT_MIR derefer_complex_case.main.Derefer.diff -// ignore-wasm32 +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY fn main() { for &foo in &[42, 43] { drop(foo) } diff --git a/tests/mir-opt/derefer_inline_test.main.Derefer.panic-abort.diff b/tests/mir-opt/derefer_inline_test.main.Derefer.panic-abort.diff new file mode 100644 index 0000000000000..92c8f2059e86d --- /dev/null +++ b/tests/mir-opt/derefer_inline_test.main.Derefer.panic-abort.diff @@ -0,0 +1,45 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_inline_test.rs:+0:11: +0:11 + let _1: std::boxed::Box>; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:18 + let mut _2: std::boxed::Box; // in scope 0 at $DIR/derefer_inline_test.rs:+1:14: +1:17 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:18 + StorageLive(_2); // scope 0 at $DIR/derefer_inline_test.rs:+1:14: +1:17 + _2 = f() -> [return: bb1, unwind: bb5]; // scope 0 at $DIR/derefer_inline_test.rs:+1:14: +1:17 + // mir::Constant + // + span: $DIR/derefer_inline_test.rs:10:14: 10:15 + // + literal: Const { ty: fn() -> Box {f}, val: Value() } + } + + bb1: { + _1 = Box::>::new(move _2) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:18 + // mir::Constant + // + span: $DIR/derefer_inline_test.rs:10:5: 10:13 + // + user_ty: UserType(0) + // + literal: Const { ty: fn(Box) -> Box> {Box::>::new}, val: Value() } + } + + bb2: { + StorageDead(_2); // scope 0 at $DIR/derefer_inline_test.rs:+1:17: +1:18 + drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/derefer_inline_test.rs:+1:18: +1:19 + } + + bb3: { + StorageDead(_1); // scope 0 at $DIR/derefer_inline_test.rs:+1:18: +1:19 + _0 = const (); // scope 0 at $DIR/derefer_inline_test.rs:+0:11: +2:2 + return; // scope 0 at $DIR/derefer_inline_test.rs:+2:2: +2:2 + } + + bb4 (cleanup): { + drop(_2) -> [return: bb5, unwind terminate]; // scope 0 at $DIR/derefer_inline_test.rs:+1:17: +1:18 + } + + bb5 (cleanup): { + resume; // scope 0 at $DIR/derefer_inline_test.rs:+0:1: +2:2 + } + } + diff --git a/tests/mir-opt/derefer_inline_test.main.Derefer.diff b/tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff similarity index 100% rename from tests/mir-opt/derefer_inline_test.main.Derefer.diff rename to tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff diff --git a/tests/mir-opt/derefer_inline_test.rs b/tests/mir-opt/derefer_inline_test.rs index 38311d4d01fb2..7ac330e51025e 100644 --- a/tests/mir-opt/derefer_inline_test.rs +++ b/tests/mir-opt/derefer_inline_test.rs @@ -1,6 +1,6 @@ // unit-test: Derefer // EMIT_MIR derefer_inline_test.main.Derefer.diff -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #[inline] fn f() -> Box { diff --git a/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-abort.diff b/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-abort.diff new file mode 100644 index 0000000000000..5a218df95b724 --- /dev/null +++ b/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-abort.diff @@ -0,0 +1,96 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_terminator_test.rs:+0:11: +0:11 + let _1: bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+1:9: +1:10 + let _3: (); // in scope 0 at $DIR/derefer_terminator_test.rs:+3:5: +6:6 + let mut _4: &&&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 + let _5: &&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:17: +3:21 + let _6: &&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:18: +3:21 + let _7: &bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:19: +3:21 ++ let mut _10: &&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 ++ let mut _11: &&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 ++ let mut _12: &bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 + scope 1 { + debug b => _1; // in scope 1 at $DIR/derefer_terminator_test.rs:+1:9: +1:10 + let _2: bool; // in scope 1 at $DIR/derefer_terminator_test.rs:+2:9: +2:10 + scope 2 { + debug d => _2; // in scope 2 at $DIR/derefer_terminator_test.rs:+2:9: +2:10 + let _8: i32; // in scope 2 at $DIR/derefer_terminator_test.rs:+4:22: +4:23 + let _9: i32; // in scope 2 at $DIR/derefer_terminator_test.rs:+7:9: +7:10 + scope 3 { + debug x => _8; // in scope 3 at $DIR/derefer_terminator_test.rs:+4:22: +4:23 + } + scope 4 { + debug y => _9; // in scope 4 at $DIR/derefer_terminator_test.rs:+7:9: +7:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_terminator_test.rs:+1:9: +1:10 + _1 = foo() -> [return: bb1, unwind: bb6]; // scope 0 at $DIR/derefer_terminator_test.rs:+1:13: +1:18 + // mir::Constant + // + span: $DIR/derefer_terminator_test.rs:6:13: 6:16 + // + literal: Const { ty: fn() -> bool {foo}, val: Value() } + } + + bb1: { + StorageLive(_2); // scope 1 at $DIR/derefer_terminator_test.rs:+2:9: +2:10 + _2 = foo() -> [return: bb2, unwind: bb6]; // scope 1 at $DIR/derefer_terminator_test.rs:+2:13: +2:18 + // mir::Constant + // + span: $DIR/derefer_terminator_test.rs:7:13: 7:16 + // + literal: Const { ty: fn() -> bool {foo}, val: Value() } + } + + bb2: { + StorageLive(_3); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +6:6 + StorageLive(_4); // scope 2 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 + StorageLive(_5); // scope 2 at $DIR/derefer_terminator_test.rs:+3:17: +3:21 + StorageLive(_6); // scope 2 at $DIR/derefer_terminator_test.rs:+3:18: +3:21 + StorageLive(_7); // scope 2 at $DIR/derefer_terminator_test.rs:+3:19: +3:21 + _7 = &_1; // scope 2 at $DIR/derefer_terminator_test.rs:+3:19: +3:21 + _6 = &_7; // scope 2 at $DIR/derefer_terminator_test.rs:+3:18: +3:21 + _5 = &_6; // scope 2 at $DIR/derefer_terminator_test.rs:+3:17: +3:21 + _4 = &_5; // scope 2 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 +- switchInt((*(*(*(*_4))))) -> [0: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ _10 = deref_copy (*_4); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ _11 = deref_copy (*_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ _12 = deref_copy (*_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ switchInt((*_12)) -> [0: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 + } + + bb3: { + _3 = const (); // scope 2 at $DIR/derefer_terminator_test.rs:+5:18: +5:20 + goto -> bb5; // scope 2 at $DIR/derefer_terminator_test.rs:+5:18: +5:20 + } + + bb4: { + StorageLive(_8); // scope 2 at $DIR/derefer_terminator_test.rs:+4:22: +4:23 + _8 = const 5_i32; // scope 2 at $DIR/derefer_terminator_test.rs:+4:26: +4:27 + _3 = const (); // scope 2 at $DIR/derefer_terminator_test.rs:+4:17: +4:29 + StorageDead(_8); // scope 2 at $DIR/derefer_terminator_test.rs:+4:28: +4:29 + goto -> bb5; // scope 2 at $DIR/derefer_terminator_test.rs:+4:28: +4:29 + } + + bb5: { + StorageDead(_7); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6 + StorageDead(_6); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6 + StorageDead(_5); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6 + StorageDead(_4); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6 + StorageDead(_3); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6 + StorageLive(_9); // scope 2 at $DIR/derefer_terminator_test.rs:+7:9: +7:10 + _9 = const 42_i32; // scope 2 at $DIR/derefer_terminator_test.rs:+7:13: +7:15 + _0 = const (); // scope 0 at $DIR/derefer_terminator_test.rs:+0:11: +8:2 + StorageDead(_9); // scope 2 at $DIR/derefer_terminator_test.rs:+8:1: +8:2 + StorageDead(_2); // scope 1 at $DIR/derefer_terminator_test.rs:+8:1: +8:2 + StorageDead(_1); // scope 0 at $DIR/derefer_terminator_test.rs:+8:1: +8:2 + return; // scope 0 at $DIR/derefer_terminator_test.rs:+8:2: +8:2 + } + + bb6 (cleanup): { + resume; // scope 0 at $DIR/derefer_terminator_test.rs:+0:1: +8:2 + } + } + diff --git a/tests/mir-opt/derefer_terminator_test.main.Derefer.diff b/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-unwind.diff similarity index 100% rename from tests/mir-opt/derefer_terminator_test.main.Derefer.diff rename to tests/mir-opt/derefer_terminator_test.main.Derefer.panic-unwind.diff diff --git a/tests/mir-opt/derefer_terminator_test.rs b/tests/mir-opt/derefer_terminator_test.rs index d6750c29dd98c..164aa733a246c 100644 --- a/tests/mir-opt/derefer_terminator_test.rs +++ b/tests/mir-opt/derefer_terminator_test.rs @@ -1,6 +1,6 @@ // unit-test: Derefer // EMIT_MIR derefer_terminator_test.main.Derefer.diff -// ignore-wasm32 +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY fn main() { let b = foo(); diff --git a/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.panic-abort.diff new file mode 100644 index 0000000000000..c039fc76b7694 --- /dev/null +++ b/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.panic-abort.diff @@ -0,0 +1,75 @@ +- // MIR for `foo` before DestinationPropagation ++ // MIR for `foo` after DestinationPropagation + + fn foo() -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/branch.rs:+0:13: +0:16 + let _1: i32; // in scope 0 at $DIR/branch.rs:+1:9: +1:10 + let mut _3: bool; // in scope 0 at $DIR/branch.rs:+3:16: +3:22 + let _4: i32; // in scope 0 at $DIR/branch.rs:+6:9: +6:14 + scope 1 { +- debug x => _1; // in scope 1 at $DIR/branch.rs:+1:9: +1:10 ++ debug x => _0; // in scope 1 at $DIR/branch.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/branch.rs:+3:9: +3:10 + scope 2 { +- debug y => _2; // in scope 2 at $DIR/branch.rs:+3:9: +3:10 ++ debug y => _0; // in scope 2 at $DIR/branch.rs:+3:9: +3:10 + } + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/branch.rs:+1:9: +1:10 +- _1 = val() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/branch.rs:+1:13: +1:18 ++ nop; // scope 0 at $DIR/branch.rs:+1:9: +1:10 ++ _0 = val() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/branch.rs:+1:13: +1:18 + // mir::Constant + // + span: $DIR/branch.rs:14:13: 14:16 + // + literal: Const { ty: fn() -> i32 {val}, val: Value() } + } + + bb1: { +- StorageLive(_2); // scope 1 at $DIR/branch.rs:+3:9: +3:10 ++ nop; // scope 1 at $DIR/branch.rs:+3:9: +3:10 + StorageLive(_3); // scope 1 at $DIR/branch.rs:+3:16: +3:22 + _3 = cond() -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/branch.rs:+3:16: +3:22 + // mir::Constant + // + span: $DIR/branch.rs:16:16: 16:20 + // + literal: Const { ty: fn() -> bool {cond}, val: Value() } + } + + bb2: { + switchInt(move _3) -> [0: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22 + } + + bb3: { +- _2 = _1; // scope 1 at $DIR/branch.rs:+4:9: +4:10 ++ nop; // scope 1 at $DIR/branch.rs:+4:9: +4:10 + goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6 + } + + bb4: { + StorageLive(_4); // scope 1 at $DIR/branch.rs:+6:9: +6:14 + _4 = val() -> [return: bb5, unwind unreachable]; // scope 1 at $DIR/branch.rs:+6:9: +6:14 + // mir::Constant + // + span: $DIR/branch.rs:19:9: 19:12 + // + literal: Const { ty: fn() -> i32 {val}, val: Value() } + } + + bb5: { + StorageDead(_4); // scope 1 at $DIR/branch.rs:+6:14: +6:15 +- _2 = _1; // scope 1 at $DIR/branch.rs:+7:9: +7:10 ++ nop; // scope 1 at $DIR/branch.rs:+7:9: +7:10 + goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6 + } + + bb6: { + StorageDead(_3); // scope 1 at $DIR/branch.rs:+8:5: +8:6 +- _0 = _2; // scope 2 at $DIR/branch.rs:+10:5: +10:6 +- StorageDead(_2); // scope 1 at $DIR/branch.rs:+11:1: +11:2 +- StorageDead(_1); // scope 0 at $DIR/branch.rs:+11:1: +11:2 ++ nop; // scope 2 at $DIR/branch.rs:+10:5: +10:6 ++ nop; // scope 1 at $DIR/branch.rs:+11:1: +11:2 ++ nop; // scope 0 at $DIR/branch.rs:+11:1: +11:2 + return; // scope 0 at $DIR/branch.rs:+11:2: +11:2 + } + } + diff --git a/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff b/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff rename to tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.panic-unwind.diff diff --git a/tests/mir-opt/dest-prop/branch.rs b/tests/mir-opt/dest-prop/branch.rs index 7e4276e66922f..5007aafb62f8c 100644 --- a/tests/mir-opt/dest-prop/branch.rs +++ b/tests/mir-opt/dest-prop/branch.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY //! Tests that assignment in both branches of an `if` are eliminated. // unit-test: DestinationPropagation fn val() -> i32 { diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.panic-abort.diff similarity index 100% rename from tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff rename to tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.panic-abort.diff diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.panic-unwind.diff new file mode 100644 index 0000000000000..4343a593542ba --- /dev/null +++ b/tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.panic-unwind.diff @@ -0,0 +1,26 @@ +- // MIR for `arg_src` before DestinationPropagation ++ // MIR for `arg_src` after DestinationPropagation + + fn arg_src(_1: i32) -> i32 { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:12: +0:17 + let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30 + let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 + scope 1 { +- debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 ++ debug y => _0; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 +- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 ++ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 + _1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12 +- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 +- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2 ++ nop; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.panic-abort.diff new file mode 100644 index 0000000000000..2e1bb2a79ecac --- /dev/null +++ b/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.panic-abort.diff @@ -0,0 +1,32 @@ +- // MIR for `bar` before DestinationPropagation ++ // MIR for `bar` after DestinationPropagation + + fn bar(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13 + let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19 + let _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13 + let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13 +- StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 +- _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 +- _2 = dummy(move _3) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 ++ _2 = dummy(move _1) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13 + // mir::Constant + // + span: $DIR/copy_propagation_arg.rs:17:5: 17:10 + // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value() } + } + + bb1: { +- StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13 + StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 + _1 = const 5_u8; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10 + _0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff rename to tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.panic-unwind.diff diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.panic-abort.diff similarity index 100% rename from tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff rename to tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.panic-abort.diff diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.panic-unwind.diff new file mode 100644 index 0000000000000..bc88787e64b2d --- /dev/null +++ b/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.panic-unwind.diff @@ -0,0 +1,22 @@ +- // MIR for `baz` before DestinationPropagation ++ // MIR for `baz` after DestinationPropagation + + fn baz(_1: i32) -> i32 { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13 + let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:23: +0:26 + let mut _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 +- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 +- _1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10 +- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-abort.diff new file mode 100644 index 0000000000000..fce57a0359220 --- /dev/null +++ b/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-abort.diff @@ -0,0 +1,32 @@ +- // MIR for `foo` before DestinationPropagation ++ // MIR for `foo` after DestinationPropagation + + fn foo(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13 + let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19 + let mut _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 + let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16 + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 + StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16 + _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16 +- _2 = dummy(move _3) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 ++ _1 = dummy(move _3) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 + // mir::Constant + // + span: $DIR/copy_propagation_arg.rs:12:9: 12:14 + // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17 +- _1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17 +- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17 + _0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff rename to tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-unwind.diff diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.rs b/tests/mir-opt/dest-prop/copy_propagation_arg.rs index 57cb328c231b3..1f8d588925c4e 100644 --- a/tests/mir-opt/dest-prop/copy_propagation_arg.rs +++ b/tests/mir-opt/dest-prop/copy_propagation_arg.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Check that DestinationPropagation does not propagate an assignment to a function argument // (doing so can break usages of the original argument value) // unit-test: DestinationPropagation diff --git a/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.panic-abort.diff new file mode 100644 index 0000000000000..35947cace2968 --- /dev/null +++ b/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.panic-abort.diff @@ -0,0 +1,77 @@ +- // MIR for `main` before DestinationPropagation ++ // MIR for `main` after DestinationPropagation + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/cycle.rs:+1:9: +1:14 + let mut _4: i32; // in scope 0 at $DIR/cycle.rs:+4:9: +4:10 + let _5: (); // in scope 0 at $DIR/cycle.rs:+6:5: +6:12 + let mut _6: i32; // in scope 0 at $DIR/cycle.rs:+6:10: +6:11 + scope 1 { +- debug x => _1; // in scope 1 at $DIR/cycle.rs:+1:9: +1:14 ++ debug x => _6; // in scope 1 at $DIR/cycle.rs:+1:9: +1:14 + let _2: i32; // in scope 1 at $DIR/cycle.rs:+2:9: +2:10 + scope 2 { +- debug y => _2; // in scope 2 at $DIR/cycle.rs:+2:9: +2:10 ++ debug y => _6; // in scope 2 at $DIR/cycle.rs:+2:9: +2:10 + let _3: i32; // in scope 2 at $DIR/cycle.rs:+3:9: +3:10 + scope 3 { +- debug z => _3; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10 ++ debug z => _6; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10 + } + } + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:14 +- _1 = val() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/cycle.rs:+1:17: +1:22 ++ nop; // scope 0 at $DIR/cycle.rs:+1:9: +1:14 ++ _6 = val() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/cycle.rs:+1:17: +1:22 + // mir::Constant + // + span: $DIR/cycle.rs:10:17: 10:20 + // + literal: Const { ty: fn() -> i32 {val}, val: Value() } + } + + bb1: { +- StorageLive(_2); // scope 1 at $DIR/cycle.rs:+2:9: +2:10 +- _2 = _1; // scope 1 at $DIR/cycle.rs:+2:13: +2:14 +- StorageLive(_3); // scope 2 at $DIR/cycle.rs:+3:9: +3:10 +- _3 = _2; // scope 2 at $DIR/cycle.rs:+3:13: +3:14 +- StorageLive(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10 +- _4 = _3; // scope 3 at $DIR/cycle.rs:+4:9: +4:10 +- _1 = move _4; // scope 3 at $DIR/cycle.rs:+4:5: +4:10 +- StorageDead(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10 ++ nop; // scope 1 at $DIR/cycle.rs:+2:9: +2:10 ++ nop; // scope 1 at $DIR/cycle.rs:+2:13: +2:14 ++ nop; // scope 2 at $DIR/cycle.rs:+3:9: +3:10 ++ nop; // scope 2 at $DIR/cycle.rs:+3:13: +3:14 ++ nop; // scope 3 at $DIR/cycle.rs:+4:9: +4:10 ++ nop; // scope 3 at $DIR/cycle.rs:+4:9: +4:10 ++ nop; // scope 3 at $DIR/cycle.rs:+4:5: +4:10 ++ nop; // scope 3 at $DIR/cycle.rs:+4:9: +4:10 + StorageLive(_5); // scope 3 at $DIR/cycle.rs:+6:5: +6:12 +- StorageLive(_6); // scope 3 at $DIR/cycle.rs:+6:10: +6:11 +- _6 = _1; // scope 3 at $DIR/cycle.rs:+6:10: +6:11 ++ nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11 ++ nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11 + _5 = std::mem::drop::(move _6) -> [return: bb2, unwind unreachable]; // scope 3 at $DIR/cycle.rs:+6:5: +6:12 + // mir::Constant + // + span: $DIR/cycle.rs:15:5: 15:9 + // + literal: Const { ty: fn(i32) {std::mem::drop::}, val: Value() } + } + + bb2: { +- StorageDead(_6); // scope 3 at $DIR/cycle.rs:+6:11: +6:12 ++ nop; // scope 3 at $DIR/cycle.rs:+6:11: +6:12 + StorageDead(_5); // scope 3 at $DIR/cycle.rs:+6:12: +6:13 + _0 = const (); // scope 0 at $DIR/cycle.rs:+0:11: +7:2 +- StorageDead(_3); // scope 2 at $DIR/cycle.rs:+7:1: +7:2 +- StorageDead(_2); // scope 1 at $DIR/cycle.rs:+7:1: +7:2 +- StorageDead(_1); // scope 0 at $DIR/cycle.rs:+7:1: +7:2 ++ nop; // scope 2 at $DIR/cycle.rs:+7:1: +7:2 ++ nop; // scope 1 at $DIR/cycle.rs:+7:1: +7:2 ++ nop; // scope 0 at $DIR/cycle.rs:+7:1: +7:2 + return; // scope 0 at $DIR/cycle.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff b/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff rename to tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.panic-unwind.diff diff --git a/tests/mir-opt/dest-prop/cycle.rs b/tests/mir-opt/dest-prop/cycle.rs index 3aea19d80dc7a..9bc0cb05a3514 100644 --- a/tests/mir-opt/dest-prop/cycle.rs +++ b/tests/mir-opt/dest-prop/cycle.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY //! Tests that cyclic assignments don't hang DestinationPropagation, and result in reasonable code. // unit-test: DestinationPropagation fn val() -> i32 { diff --git a/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.panic-abort.mir b/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.panic-abort.mir new file mode 100644 index 0000000000000..5882e0aee109a --- /dev/null +++ b/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.panic-abort.mir @@ -0,0 +1,34 @@ +// MIR for `f` after DestinationPropagation + +fn f(_1: usize) -> usize { + debug a => _1; // in scope 0 at $DIR/dead_stores_79191.rs:+0:6: +0:11 + let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_79191.rs:+0:23: +0:28 + let _2: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10 + let mut _3: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+3:9: +3:10 + let mut _4: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+4:8: +4:9 + scope 1 { + debug b => _3; // in scope 1 at $DIR/dead_stores_79191.rs:+1:9: +1:10 + } + + bb0: { + nop; // scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10 + _3 = _1; // scope 0 at $DIR/dead_stores_79191.rs:+1:13: +1:14 + _1 = const 5_usize; // scope 1 at $DIR/dead_stores_79191.rs:+2:5: +2:10 + nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10 + nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10 + _1 = move _3; // scope 1 at $DIR/dead_stores_79191.rs:+3:5: +3:10 + nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10 + nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9 + nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9 + _0 = id::(move _1) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/dead_stores_79191.rs:+4:5: +4:10 + // mir::Constant + // + span: $DIR/dead_stores_79191.rs:13:5: 13:7 + // + literal: Const { ty: fn(usize) -> usize {id::}, val: Value() } + } + + bb1: { + nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:9: +4:10 + nop; // scope 0 at $DIR/dead_stores_79191.rs:+5:1: +5:2 + return; // scope 0 at $DIR/dead_stores_79191.rs:+5:2: +5:2 + } +} diff --git a/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir b/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir rename to tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.panic-unwind.mir diff --git a/tests/mir-opt/dest-prop/dead_stores_79191.rs b/tests/mir-opt/dest-prop/dead_stores_79191.rs index 9d4814838d4ea..2f95ba0e326a4 100644 --- a/tests/mir-opt/dest-prop/dead_stores_79191.rs +++ b/tests/mir-opt/dest-prop/dead_stores_79191.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DestinationPropagation fn id(x: T) -> T { diff --git a/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-abort.mir b/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-abort.mir new file mode 100644 index 0000000000000..f4568111d2e15 --- /dev/null +++ b/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-abort.mir @@ -0,0 +1,33 @@ +// MIR for `f` after DestinationPropagation + +fn f(_1: usize) -> usize { + debug a => _1; // in scope 0 at $DIR/dead_stores_better.rs:+0:10: +0:15 + let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_better.rs:+0:27: +0:32 + let _2: usize; // in scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10 + let mut _3: usize; // in scope 0 at $DIR/dead_stores_better.rs:+3:9: +3:10 + let mut _4: usize; // in scope 0 at $DIR/dead_stores_better.rs:+4:8: +4:9 + scope 1 { + debug b => _1; // in scope 1 at $DIR/dead_stores_better.rs:+1:9: +1:10 + } + + bb0: { + nop; // scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10 + nop; // scope 0 at $DIR/dead_stores_better.rs:+1:13: +1:14 + nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10 + nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10 + nop; // scope 1 at $DIR/dead_stores_better.rs:+3:5: +3:10 + nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10 + nop; // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9 + nop; // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9 + _0 = id::(move _1) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/dead_stores_better.rs:+4:5: +4:10 + // mir::Constant + // + span: $DIR/dead_stores_better.rs:17:5: 17:7 + // + literal: Const { ty: fn(usize) -> usize {id::}, val: Value() } + } + + bb1: { + nop; // scope 1 at $DIR/dead_stores_better.rs:+4:9: +4:10 + nop; // scope 0 at $DIR/dead_stores_better.rs:+5:1: +5:2 + return; // scope 0 at $DIR/dead_stores_better.rs:+5:2: +5:2 + } +} diff --git a/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir b/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir rename to tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-unwind.mir diff --git a/tests/mir-opt/dest-prop/dead_stores_better.rs b/tests/mir-opt/dest-prop/dead_stores_better.rs index 72d406bfd40ad..e67653c57e4d2 100644 --- a/tests/mir-opt/dest-prop/dead_stores_better.rs +++ b/tests/mir-opt/dest-prop/dead_stores_better.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // This is a copy of the `dead_stores_79191` test, except that we turn on DSE. This demonstrates // that that pass enables this one to do more optimizations. diff --git a/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-abort.diff new file mode 100644 index 0000000000000..0b0eb03b652f9 --- /dev/null +++ b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-abort.diff @@ -0,0 +1,43 @@ +- // MIR for `nrvo` before DestinationPropagation ++ // MIR for `nrvo` after DestinationPropagation + + fn nrvo(_1: for<'a> fn(&'a mut [u8; 1024])) -> [u8; 1024] { + debug init => _1; // in scope 0 at $DIR/simple.rs:+0:9: +0:13 + let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/simple.rs:+0:39: +0:49 + let mut _2: [u8; 1024]; // in scope 0 at $DIR/simple.rs:+1:9: +1:16 + let _3: (); // in scope 0 at $DIR/simple.rs:+2:5: +2:19 + let mut _4: for<'a> fn(&'a mut [u8; 1024]); // in scope 0 at $DIR/simple.rs:+2:5: +2:9 + let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/simple.rs:+2:10: +2:18 + let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/simple.rs:+2:10: +2:18 + scope 1 { + debug buf => _2; // in scope 1 at $DIR/simple.rs:+1:9: +1:16 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simple.rs:+1:9: +1:16 + _2 = [const 0_u8; 1024]; // scope 0 at $DIR/simple.rs:+1:19: +1:28 + StorageLive(_3); // scope 1 at $DIR/simple.rs:+2:5: +2:19 +- StorageLive(_4); // scope 1 at $DIR/simple.rs:+2:5: +2:9 +- _4 = _1; // scope 1 at $DIR/simple.rs:+2:5: +2:9 ++ nop; // scope 1 at $DIR/simple.rs:+2:5: +2:9 ++ nop; // scope 1 at $DIR/simple.rs:+2:5: +2:9 + StorageLive(_5); // scope 1 at $DIR/simple.rs:+2:10: +2:18 + StorageLive(_6); // scope 1 at $DIR/simple.rs:+2:10: +2:18 + _6 = &mut _2; // scope 1 at $DIR/simple.rs:+2:10: +2:18 + _5 = &mut (*_6); // scope 1 at $DIR/simple.rs:+2:10: +2:18 +- _3 = move _4(move _5) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/simple.rs:+2:5: +2:19 ++ _3 = move _1(move _5) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/simple.rs:+2:5: +2:19 + } + + bb1: { + StorageDead(_5); // scope 1 at $DIR/simple.rs:+2:18: +2:19 +- StorageDead(_4); // scope 1 at $DIR/simple.rs:+2:18: +2:19 ++ nop; // scope 1 at $DIR/simple.rs:+2:18: +2:19 + StorageDead(_6); // scope 1 at $DIR/simple.rs:+2:19: +2:20 + StorageDead(_3); // scope 1 at $DIR/simple.rs:+2:19: +2:20 + _0 = _2; // scope 1 at $DIR/simple.rs:+3:5: +3:8 + StorageDead(_2); // scope 0 at $DIR/simple.rs:+4:1: +4:2 + return; // scope 0 at $DIR/simple.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff rename to tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-unwind.diff diff --git a/tests/mir-opt/dest-prop/simple.rs b/tests/mir-opt/dest-prop/simple.rs index 3a4aec34e8cc4..0bcb2924f1dd9 100644 --- a/tests/mir-opt/dest-prop/simple.rs +++ b/tests/mir-opt/dest-prop/simple.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY //! Copy of `nrvo-simple.rs`, to ensure that full dest-prop handles it too. // unit-test: DestinationPropagation // EMIT_MIR simple.nrvo.DestinationPropagation.diff diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff new file mode 100644 index 0000000000000..61cdc26dcdc80 --- /dev/null +++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff @@ -0,0 +1,35 @@ +- // MIR for `main` before DestinationPropagation ++ // MIR for `main` after DestinationPropagation + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/union.rs:+0:11: +0:11 + let _1: main::Un; // in scope 0 at $DIR/union.rs:+5:9: +5:11 + let mut _2: u32; // in scope 0 at $DIR/union.rs:+5:23: +5:28 + let mut _3: u32; // in scope 0 at $DIR/union.rs:+7:10: +7:26 + scope 1 { + debug un => _1; // in scope 1 at $DIR/union.rs:+5:9: +5:11 + scope 2 { + } + scope 3 (inlined std::mem::drop::) { // at $DIR/union.rs:16:5: 16:27 + debug _x => _3; // in scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/union.rs:+5:9: +5:11 + StorageLive(_2); // scope 0 at $DIR/union.rs:+5:23: +5:28 + _2 = val() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/union.rs:+5:23: +5:28 + // mir::Constant + // + span: $DIR/union.rs:14:23: 14:26 + // + literal: Const { ty: fn() -> u32 {val}, val: Value() } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/union.rs:+5:29: +5:30 + StorageLive(_3); // scope 1 at $DIR/union.rs:+7:10: +7:26 + StorageDead(_3); // scope 1 at $DIR/union.rs:+7:26: +7:27 + StorageDead(_1); // scope 0 at $DIR/union.rs:+8:1: +8:2 + return; // scope 0 at $DIR/union.rs:+8:2: +8:2 + } + } + diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dest-prop/union.main.DestinationPropagation.diff rename to tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff diff --git a/tests/mir-opt/dest-prop/union.rs b/tests/mir-opt/dest-prop/union.rs index 062d02d067311..4bc6f28c6c297 100644 --- a/tests/mir-opt/dest-prop/union.rs +++ b/tests/mir-opt/dest-prop/union.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY //! Tests that we can propagate into places that are projections into unions // compile-flags: -Zunsound-mir-opts fn val() -> u32 { diff --git a/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.panic-abort.diff new file mode 100644 index 0000000000000..e8f0b25c59b35 --- /dev/null +++ b/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.panic-abort.diff @@ -0,0 +1,86 @@ +- // MIR for `f` before DestinationPropagation ++ // MIR for `f` after DestinationPropagation + + fn f(_1: T) -> () { + debug a => _1; // in scope 0 at $DIR/unreachable.rs:+0:19: +0:20 + let mut _0: (); // return place in scope 0 at $DIR/unreachable.rs:+0:25: +0:25 + let _2: T; // in scope 0 at $DIR/unreachable.rs:+1:9: +1:10 + let mut _3: bool; // in scope 0 at $DIR/unreachable.rs:+2:8: +2:13 + let _4: (); // in scope 0 at $DIR/unreachable.rs:+3:9: +3:16 + let mut _5: T; // in scope 0 at $DIR/unreachable.rs:+3:11: +3:12 + let mut _6: T; // in scope 0 at $DIR/unreachable.rs:+3:14: +3:15 + let _7: (); // in scope 0 at $DIR/unreachable.rs:+5:9: +5:16 + let mut _8: T; // in scope 0 at $DIR/unreachable.rs:+5:11: +5:12 + let mut _9: T; // in scope 0 at $DIR/unreachable.rs:+5:14: +5:15 + scope 1 { +- debug b => _2; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10 ++ debug b => _1; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/unreachable.rs:+1:9: +1:10 +- _2 = _1; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14 ++ nop; // scope 0 at $DIR/unreachable.rs:+1:9: +1:10 ++ nop; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14 + StorageLive(_3); // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 + _3 = const false; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 +- goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 ++ goto -> bb1; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 + } + + bb1: { +- StorageLive(_4); // scope 1 at $DIR/unreachable.rs:+3:9: +3:16 +- StorageLive(_5); // scope 1 at $DIR/unreachable.rs:+3:11: +3:12 +- _5 = _1; // scope 1 at $DIR/unreachable.rs:+3:11: +3:12 +- StorageLive(_6); // scope 1 at $DIR/unreachable.rs:+3:14: +3:15 +- _6 = _2; // scope 1 at $DIR/unreachable.rs:+3:14: +3:15 +- _4 = g::(move _5, move _6) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/unreachable.rs:+3:9: +3:16 +- // mir::Constant +- // + span: $DIR/unreachable.rs:12:9: 12:10 +- // + literal: Const { ty: fn(T, T) {g::}, val: Value() } +- } +- +- bb2: { +- StorageDead(_6); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16 +- StorageDead(_5); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16 +- StorageDead(_4); // scope 1 at $DIR/unreachable.rs:+3:16: +3:17 +- _0 = const (); // scope 1 at $DIR/unreachable.rs:+2:14: +4:6 +- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6 +- } +- +- bb3: { + StorageLive(_7); // scope 1 at $DIR/unreachable.rs:+5:9: +5:16 +- StorageLive(_8); // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 +- _8 = _2; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 ++ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 ++ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 + StorageLive(_9); // scope 1 at $DIR/unreachable.rs:+5:14: +5:15 +- _9 = _2; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15 +- _7 = g::(move _8, move _9) -> [return: bb4, unwind unreachable]; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16 ++ _9 = _1; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15 ++ _7 = g::(move _1, move _9) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16 + // mir::Constant + // + span: $DIR/unreachable.rs:14:9: 14:10 + // + literal: Const { ty: fn(T, T) {g::}, val: Value() } + } + +- bb4: { ++ bb2: { + StorageDead(_9); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16 +- StorageDead(_8); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16 ++ nop; // scope 1 at $DIR/unreachable.rs:+5:15: +5:16 + StorageDead(_7); // scope 1 at $DIR/unreachable.rs:+5:16: +5:17 + _0 = const (); // scope 1 at $DIR/unreachable.rs:+4:12: +6:6 +- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6 ++ goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6 + } + +- bb5: { ++ bb3: { + StorageDead(_3); // scope 1 at $DIR/unreachable.rs:+6:5: +6:6 +- StorageDead(_2); // scope 0 at $DIR/unreachable.rs:+7:1: +7:2 ++ nop; // scope 0 at $DIR/unreachable.rs:+7:1: +7:2 + return; // scope 0 at $DIR/unreachable.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff b/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.panic-unwind.diff similarity index 100% rename from tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff rename to tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.panic-unwind.diff diff --git a/tests/mir-opt/dest-prop/unreachable.rs b/tests/mir-opt/dest-prop/unreachable.rs index c73d11ae3bafc..e950dbbf5c917 100644 --- a/tests/mir-opt/dest-prop/unreachable.rs +++ b/tests/mir-opt/dest-prop/unreachable.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Check that unreachable code is removed after the destination propagation. // Regression test for issue #105428. // 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 new file mode 100644 index 0000000000000..a10c5a7901968 --- /dev/null +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-abort.diff @@ -0,0 +1,129 @@ +- // MIR for `float_to_exponential_common` before ConstProp ++ // MIR for `float_to_exponential_common` after ConstProp + + fn float_to_exponential_common(_1: &mut Formatter<'_>, _2: &T, _3: bool) -> Result<(), std::fmt::Error> { + debug fmt => _1; // in scope 0 at $DIR/funky_arms.rs:+0:35: +0:38 + debug num => _2; // in scope 0 at $DIR/funky_arms.rs:+0:60: +0:63 + debug upper => _3; // in scope 0 at $DIR/funky_arms.rs:+0:69: +0:74 + let mut _0: std::result::Result<(), std::fmt::Error>; // return place in scope 0 at $DIR/funky_arms.rs:+0:85: +0:91 + let _4: bool; // in scope 0 at $DIR/funky_arms.rs:+4:9: +4:19 + let mut _5: &std::fmt::Formatter<'_>; // in scope 0 at $DIR/funky_arms.rs:+4:22: +4:37 + let mut _7: std::option::Option; // in scope 0 at $DIR/funky_arms.rs:+13:30: +13:45 + let mut _8: &std::fmt::Formatter<'_>; // in scope 0 at $DIR/funky_arms.rs:+13:30: +13:45 + let mut _9: isize; // in scope 0 at $DIR/funky_arms.rs:+13:12: +13:27 + let mut _11: &mut std::fmt::Formatter<'_>; // in scope 0 at $DIR/funky_arms.rs:+15:43: +15:46 + let mut _12: &T; // in scope 0 at $DIR/funky_arms.rs:+15:48: +15:51 + let mut _13: core::num::flt2dec::Sign; // in scope 0 at $DIR/funky_arms.rs:+15:53: +15:57 + let mut _14: u32; // in scope 0 at $DIR/funky_arms.rs:+15:59: +15:79 + let mut _15: u32; // in scope 0 at $DIR/funky_arms.rs:+15:59: +15:75 + let mut _16: usize; // in scope 0 at $DIR/funky_arms.rs:+15:59: +15:68 + let mut _17: bool; // in scope 0 at $DIR/funky_arms.rs:+15:81: +15:86 + let mut _18: &mut std::fmt::Formatter<'_>; // in scope 0 at $DIR/funky_arms.rs:+17:46: +17:49 + let mut _19: &T; // in scope 0 at $DIR/funky_arms.rs:+17:51: +17:54 + let mut _20: core::num::flt2dec::Sign; // in scope 0 at $DIR/funky_arms.rs:+17:56: +17:60 + let mut _21: bool; // in scope 0 at $DIR/funky_arms.rs:+17:62: +17:67 + scope 1 { + debug force_sign => _4; // in scope 1 at $DIR/funky_arms.rs:+4:9: +4:19 + let _6: core::num::flt2dec::Sign; // in scope 1 at $DIR/funky_arms.rs:+8:9: +8:13 + scope 2 { + debug sign => _6; // in scope 2 at $DIR/funky_arms.rs:+8:9: +8:13 + scope 3 { + debug precision => _10; // in scope 3 at $DIR/funky_arms.rs:+13:17: +13:26 + let _10: usize; // in scope 3 at $DIR/funky_arms.rs:+13:17: +13:26 + } + } + } + + bb0: { + StorageLive(_4); // scope 0 at $DIR/funky_arms.rs:+4:9: +4:19 + StorageLive(_5); // scope 0 at $DIR/funky_arms.rs:+4:22: +4:37 + _5 = &(*_1); // scope 0 at $DIR/funky_arms.rs:+4:22: +4:37 + _4 = Formatter::<'_>::sign_plus(move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/funky_arms.rs:+4:22: +4:37 + // mir::Constant + // + span: $DIR/funky_arms.rs:16:26: 16:35 + // + literal: Const { ty: for<'a> fn(&'a Formatter<'_>) -> bool {Formatter::<'_>::sign_plus}, val: Value() } + } + + bb1: { + StorageDead(_5); // scope 0 at $DIR/funky_arms.rs:+4:36: +4:37 + StorageLive(_6); // scope 1 at $DIR/funky_arms.rs:+8:9: +8:13 + switchInt(_4) -> [0: bb3, otherwise: bb2]; // scope 1 at $DIR/funky_arms.rs:+8:16: +8:32 + } + + bb2: { +- _6 = MinusPlus; // scope 1 at $DIR/funky_arms.rs:+10:17: +10:41 ++ _6 = const MinusPlus; // scope 1 at $DIR/funky_arms.rs:+10:17: +10:41 ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: Sign, val: Value(Scalar(0x01)) } + goto -> bb4; // scope 1 at $DIR/funky_arms.rs:+10:17: +10:41 + } + + bb3: { +- _6 = Minus; // scope 1 at $DIR/funky_arms.rs:+9:18: +9:38 ++ _6 = const Minus; // scope 1 at $DIR/funky_arms.rs:+9:18: +9:38 ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: Sign, val: Value(Scalar(0x00)) } + goto -> bb4; // scope 1 at $DIR/funky_arms.rs:+9:18: +9:38 + } + + bb4: { + StorageLive(_7); // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45 + StorageLive(_8); // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45 + _8 = &(*_1); // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45 + _7 = Formatter::<'_>::precision(move _8) -> [return: bb5, unwind unreachable]; // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45 + // mir::Constant + // + span: $DIR/funky_arms.rs:25:34: 25:43 + // + literal: Const { ty: for<'a> fn(&'a Formatter<'_>) -> Option {Formatter::<'_>::precision}, val: Value() } + } + + bb5: { + StorageDead(_8); // scope 3 at $DIR/funky_arms.rs:+13:44: +13:45 + _9 = discriminant(_7); // scope 3 at $DIR/funky_arms.rs:+13:12: +13:27 + switchInt(move _9) -> [1: bb6, otherwise: bb8]; // scope 3 at $DIR/funky_arms.rs:+13:12: +13:27 + } + + bb6: { + _10 = ((_7 as Some).0: usize); // scope 3 at $DIR/funky_arms.rs:+13:17: +13:26 + StorageLive(_13); // scope 3 at $DIR/funky_arms.rs:+15:53: +15:57 + _13 = _6; // scope 3 at $DIR/funky_arms.rs:+15:53: +15:57 + StorageLive(_14); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79 + StorageLive(_15); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75 + _15 = _10 as u32 (IntToInt); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75 + _14 = Add(move _15, const 1_u32); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79 + StorageDead(_15); // scope 3 at $DIR/funky_arms.rs:+15:78: +15:79 + _0 = float_to_exponential_common_exact::(_1, _2, move _13, move _14, _3) -> [return: bb7, unwind unreachable]; // scope 3 at $DIR/funky_arms.rs:+15:9: +15:87 + // mir::Constant + // + span: $DIR/funky_arms.rs:27:9: 27:42 + // + literal: Const { ty: for<'a, 'b, 'c> fn(&'a mut Formatter<'b>, &'c T, Sign, u32, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_exact::}, val: Value() } + } + + bb7: { + StorageDead(_14); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87 + StorageDead(_13); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87 + goto -> bb10; // scope 2 at $DIR/funky_arms.rs:+13:5: +18:6 + } + + bb8: { + StorageLive(_20); // scope 2 at $DIR/funky_arms.rs:+17:56: +17:60 + _20 = _6; // scope 2 at $DIR/funky_arms.rs:+17:56: +17:60 + _0 = float_to_exponential_common_shortest::(_1, _2, move _20, _3) -> [return: bb9, unwind unreachable]; // scope 2 at $DIR/funky_arms.rs:+17:9: +17:68 + // mir::Constant + // + span: $DIR/funky_arms.rs:29:9: 29:45 + // + literal: Const { ty: for<'a, 'b, 'c> fn(&'a mut Formatter<'b>, &'c T, Sign, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_shortest::}, val: Value() } + } + + bb9: { + StorageDead(_20); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68 + goto -> bb10; // scope 2 at $DIR/funky_arms.rs:+13:5: +18:6 + } + + bb10: { + StorageDead(_6); // scope 1 at $DIR/funky_arms.rs:+19:1: +19:2 + StorageDead(_4); // scope 0 at $DIR/funky_arms.rs:+19:1: +19:2 + StorageDead(_7); // scope 0 at $DIR/funky_arms.rs:+19:1: +19:2 + return; // scope 0 at $DIR/funky_arms.rs:+19:2: +19:2 + } + } + diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff rename to tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/funky_arms.rs b/tests/mir-opt/funky_arms.rs index c4f75b5df6d8a..6b4f4c80560b7 100644 --- a/tests/mir-opt/funky_arms.rs +++ b/tests/mir-opt/funky_arms.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: --crate-type lib -Cdebug-assertions=no #![feature(flt2dec)] diff --git a/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-abort.mir b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-abort.mir new file mode 100644 index 0000000000000..16e8c2a8e5813 --- /dev/null +++ b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-abort.mir @@ -0,0 +1,82 @@ +// MIR for `main::{closure#0}` 0 generator_drop +/* generator_layout = GeneratorLayout { + field_tys: { + _0: GeneratorSavedTy { + ty: std::string::String, + source_info: SourceInfo { + span: $DIR/generator_drop_cleanup.rs:11:13: 11:15 (#0), + scope: scope[0], + }, + ignore_for_traits: false, + }, + }, + variant_fields: { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + Suspend0 (3): [_0], + }, + storage_conflicts: BitMatrix(1x1) { + (_0, _0), + }, +} */ + +fn main::{closure#0}(_1: *mut [generator@$DIR/generator_drop_cleanup.rs:10:15: 10:17]) -> () { + let mut _0: (); // return place in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + let mut _2: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + let _3: std::string::String; // in scope 0 at $DIR/generator_drop_cleanup.rs:+1:13: +1:15 + let _4: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+2:9: +2:14 + let mut _5: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+2:9: +2:14 + let mut _6: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:18: +0:18 + let mut _7: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + let mut _8: u32; // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + scope 1 { + debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator_drop_cleanup.rs:+1:13: +1:15 + } + + bb0: { + _8 = discriminant((*_1)); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + switchInt(move _8) -> [0: bb5, 3: bb8, otherwise: bb9]; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } + + bb1: { + StorageDead(_5); // scope 1 at $DIR/generator_drop_cleanup.rs:+2:13: +2:14 + StorageDead(_4); // scope 1 at $DIR/generator_drop_cleanup.rs:+2:14: +2:15 + drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6 + } + + bb2: { + nop; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6 + goto -> bb6; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6 + } + + bb3: { + return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } + + bb4: { + return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } + + bb5: { + goto -> bb7; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } + + bb6: { + goto -> bb3; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6 + } + + bb7: { + goto -> bb4; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } + + bb8: { + StorageLive(_4); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + StorageLive(_5); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + goto -> bb1; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } + + bb9: { + return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } +} diff --git a/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-unwind.mir similarity index 100% rename from tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir rename to tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-unwind.mir diff --git a/tests/mir-opt/generator_drop_cleanup.rs b/tests/mir-opt/generator_drop_cleanup.rs index 82c1292cbd05c..7e0d7bb59a5ad 100644 --- a/tests/mir-opt/generator_drop_cleanup.rs +++ b/tests/mir-opt/generator_drop_cleanup.rs @@ -1,6 +1,6 @@ #![feature(generators, generator_trait)] -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Regression test for #58892, generator drop shims should not have blocks // spuriously marked as cleanup diff --git a/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir b/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir new file mode 100644 index 0000000000000..5b24dd4602f4f --- /dev/null +++ b/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir @@ -0,0 +1,89 @@ +// MIR for `main::{closure#0}` before StateTransform + +fn main::{closure#0}(_1: [generator@$DIR/generator_storage_dead_unwind.rs:22:16: 22:18], _2: ()) -> () +yields () + { + let mut _0: (); // return place in scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:19: +0:19 + let _3: Foo; // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+1:13: +1:14 + let _5: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + let mut _6: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + let _7: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+4:9: +4:16 + let mut _8: Foo; // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+4:14: +4:15 + let _9: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+5:9: +5:16 + let mut _10: Bar; // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+5:14: +5:15 + scope 1 { + debug a => _3; // in scope 1 at $DIR/generator_storage_dead_unwind.rs:+1:13: +1:14 + let _4: Bar; // in scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:13: +2:14 + scope 2 { + debug b => _4; // in scope 2 at $DIR/generator_storage_dead_unwind.rs:+2:13: +2:14 + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+1:13: +1:14 + _3 = Foo(const 5_i32); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+1:17: +1:23 + StorageLive(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:13: +2:14 + _4 = Bar(const 6_i32); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:17: +2:23 + StorageLive(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + StorageLive(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + _6 = (); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + _5 = yield(move _6) -> [resume: bb1, drop: bb6]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + } + + bb1: { + StorageDead(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:13: +3:14 + StorageDead(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:14: +3:15 + StorageLive(_7); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:9: +4:16 + StorageLive(_8); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:14: +4:15 + _8 = move _3; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:14: +4:15 + _7 = take::(move _8) -> [return: bb2, unwind unreachable]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:9: +4:16 + // mir::Constant + // + span: $DIR/generator_storage_dead_unwind.rs:26:9: 26:13 + // + literal: Const { ty: fn(Foo) {take::}, val: Value() } + } + + bb2: { + StorageDead(_8); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:15: +4:16 + StorageDead(_7); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:16: +4:17 + StorageLive(_9); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:9: +5:16 + StorageLive(_10); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:14: +5:15 + _10 = move _4; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:14: +5:15 + _9 = take::(move _10) -> [return: bb3, unwind unreachable]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:9: +5:16 + // mir::Constant + // + span: $DIR/generator_storage_dead_unwind.rs:27:9: 27:13 + // + literal: Const { ty: fn(Bar) {take::}, val: Value() } + } + + bb3: { + StorageDead(_10); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:15: +5:16 + StorageDead(_9); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:16: +5:17 + _0 = const (); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:19: +6:6 + StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + goto -> bb4; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } + + bb4: { + StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_1) -> [return: bb5, unwind unreachable]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } + + bb5: { + return; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:6: +6:6 + } + + bb6: { + StorageDead(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:13: +3:14 + StorageDead(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:14: +3:15 + StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_3) -> [return: bb7, unwind unreachable]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } + + bb7: { + StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_1) -> [return: bb8, unwind unreachable]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } + + bb8: { + generator_drop; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:16: +6:6 + } +} diff --git a/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir b/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir similarity index 100% rename from tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir rename to tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir diff --git a/tests/mir-opt/generator_storage_dead_unwind.rs b/tests/mir-opt/generator_storage_dead_unwind.rs index b72170adec37a..664f7ef67e323 100644 --- a/tests/mir-opt/generator_storage_dead_unwind.rs +++ b/tests/mir-opt/generator_storage_dead_unwind.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Test that we generate StorageDead on unwind paths for generators. // diff --git a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-abort.diff b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-abort.diff new file mode 100644 index 0000000000000..8c68e215e4af7 --- /dev/null +++ b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-abort.diff @@ -0,0 +1,37 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/asm_unwind.rs:+0:15: +0:15 + let _1: (); // in scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 ++ scope 1 (inlined foo) { // at $DIR/asm_unwind.rs:21:5: 21:10 ++ let _2: D; // in scope 1 at $DIR/asm_unwind.rs:15:9: 15:11 ++ scope 2 { ++ debug _d => const D; // in scope 2 at $DIR/asm_unwind.rs:15:9: 15:11 ++ scope 3 { ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 +- _1 = foo() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 +- // mir::Constant +- // + span: $DIR/asm_unwind.rs:21:5: 21:8 +- // + literal: Const { ty: fn() {foo}, val: Value() } ++ StorageLive(_2); // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 ++ asm!("", options(MAY_UNWIND)) -> [return: bb2, unwind terminate]; // scope 3 at $DIR/asm_unwind.rs:16:14: 16:54 + } + + bb1: { ++ StorageDead(_2); // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 + StorageDead(_1); // scope 0 at $DIR/asm_unwind.rs:+1:10: +1:11 + _0 = const (); // scope 0 at $DIR/asm_unwind.rs:+0:15: +2:2 + return; // scope 0 at $DIR/asm_unwind.rs:+2:2: +2:2 ++ } ++ ++ bb2: { ++ drop(_2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2 + } + } + diff --git a/tests/mir-opt/inline/asm_unwind.main.Inline.diff b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/asm_unwind.main.Inline.diff rename to tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/asm_unwind.rs b/tests/mir-opt/inline/asm_unwind.rs index c03feb433128c..a977ebf1bb7b3 100644 --- a/tests/mir-opt/inline/asm_unwind.rs +++ b/tests/mir-opt/inline/asm_unwind.rs @@ -1,6 +1,6 @@ // Tests inlining of `may_unwind` inline assembly. // -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // needs-asm-support #![feature(asm_unwind)] diff --git a/tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff b/tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff rename to tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/caller_with_trivial_bound.rs b/tests/mir-opt/inline/caller_with_trivial_bound.rs index 8545db89414a7..a8f101d488cae 100644 --- a/tests/mir-opt/inline/caller_with_trivial_bound.rs +++ b/tests/mir-opt/inline/caller_with_trivial_bound.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // needs-unwind #![crate_type = "lib"] diff --git a/tests/mir-opt/inline/cycle.f.Inline.panic-abort.diff b/tests/mir-opt/inline/cycle.f.Inline.panic-abort.diff new file mode 100644 index 0000000000000..a4cb48e66c101 --- /dev/null +++ b/tests/mir-opt/inline/cycle.f.Inline.panic-abort.diff @@ -0,0 +1,35 @@ +- // MIR for `f` before Inline ++ // MIR for `f` after Inline + + fn f(_1: impl Fn()) -> () { + debug g => _1; // in scope 0 at $DIR/cycle.rs:+0:6: +0:7 + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:20: +0:20 + let _2: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:8 + let mut _3: &impl Fn(); // in scope 0 at $DIR/cycle.rs:+1:5: +1:6 + let mut _4: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:8 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:8 + StorageLive(_3); // scope 0 at $DIR/cycle.rs:+1:5: +1:6 + _3 = &_1; // scope 0 at $DIR/cycle.rs:+1:5: +1:6 + StorageLive(_4); // scope 0 at $DIR/cycle.rs:+1:5: +1:8 + _4 = (); // scope 0 at $DIR/cycle.rs:+1:5: +1:8 + _2 = >::call(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/cycle.rs:+1:5: +1:8 + // mir::Constant + // + span: $DIR/cycle.rs:6:5: 6:6 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(), ()) -> >::Output {>::call}, val: Value() } + } + + bb1: { + StorageDead(_4); // scope 0 at $DIR/cycle.rs:+1:7: +1:8 + StorageDead(_3); // scope 0 at $DIR/cycle.rs:+1:7: +1:8 + StorageDead(_2); // scope 0 at $DIR/cycle.rs:+1:8: +1:9 + _0 = const (); // scope 0 at $DIR/cycle.rs:+0:20: +2:2 + drop(_1) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/cycle.rs:+2:1: +2:2 + } + + bb2: { + return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/cycle.f.Inline.diff b/tests/mir-opt/inline/cycle.f.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/cycle.f.Inline.diff rename to tests/mir-opt/inline/cycle.f.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/cycle.g.Inline.panic-abort.diff b/tests/mir-opt/inline/cycle.g.Inline.panic-abort.diff new file mode 100644 index 0000000000000..faa0b120ed543 --- /dev/null +++ b/tests/mir-opt/inline/cycle.g.Inline.panic-abort.diff @@ -0,0 +1,50 @@ +- // MIR for `g` before Inline ++ // MIR for `g` after Inline + + fn g() -> () { + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:8: +0:8 + let _1: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:12 ++ let mut _2: fn() {main}; // in scope 0 at $DIR/cycle.rs:+1:5: +1:12 ++ let mut _5: (); // in scope 0 at $DIR/cycle.rs:6:5: 6:8 ++ scope 1 (inlined f::) { // at $DIR/cycle.rs:12:5: 12:12 ++ debug g => _2; // in scope 1 at $DIR/cycle.rs:5:6: 5:7 ++ let mut _3: &fn() {main}; // in scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ let _4: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ scope 2 (inlined >::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8 ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:5: +1:12 +- _1 = f::(main) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/cycle.rs:+1:5: +1:12 ++ StorageLive(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:12 ++ _2 = main; // scope 0 at $DIR/cycle.rs:+1:5: +1:12 + // mir::Constant +- // + span: $DIR/cycle.rs:12:5: 12:6 +- // + literal: Const { ty: fn(fn() {main}) {f::}, val: Value() } +- // mir::Constant + // + span: $DIR/cycle.rs:12:7: 12:11 + // + literal: Const { ty: fn() {main}, val: Value() } ++ StorageLive(_4); // scope 0 at $DIR/cycle.rs:+1:5: +1:12 ++ StorageLive(_3); // scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ _3 = &_2; // scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ _5 = const (); // scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ _4 = move (*_3)() -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL + } + + bb1: { ++ StorageDead(_4); // scope 0 at $DIR/cycle.rs:+1:5: +1:12 ++ StorageDead(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:12 + StorageDead(_1); // scope 0 at $DIR/cycle.rs:+1:12: +1:13 + _0 = const (); // scope 0 at $DIR/cycle.rs:+0:8: +2:2 + return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2 ++ } ++ ++ bb2: { ++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:7: 6:8 ++ drop(_2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/cycle.rs:7:1: 7:2 + } + } + diff --git a/tests/mir-opt/inline/cycle.g.Inline.diff b/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/cycle.g.Inline.diff rename to tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/cycle.main.Inline.panic-abort.diff b/tests/mir-opt/inline/cycle.main.Inline.panic-abort.diff new file mode 100644 index 0000000000000..55a0f92197bcc --- /dev/null +++ b/tests/mir-opt/inline/cycle.main.Inline.panic-abort.diff @@ -0,0 +1,63 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:9 ++ let mut _2: fn() {g}; // in scope 0 at $DIR/cycle.rs:+1:5: +1:9 ++ let mut _5: (); // in scope 0 at $DIR/cycle.rs:6:5: 6:8 ++ scope 1 (inlined f::) { // at $DIR/cycle.rs:17:5: 17:9 ++ debug g => _2; // in scope 1 at $DIR/cycle.rs:5:6: 5:7 ++ let mut _3: &fn() {g}; // in scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ let _4: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ scope 2 (inlined >::call - shim(fn() {g})) { // at $DIR/cycle.rs:6:5: 6:8 ++ scope 3 (inlined g) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ scope 4 (inlined f::) { // at $DIR/cycle.rs:12:5: 12:12 ++ debug g => main; // in scope 4 at $DIR/cycle.rs:5:6: 5:7 ++ let _6: (); // in scope 4 at $DIR/cycle.rs:6:5: 6:8 ++ scope 5 (inlined >::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8 ++ } ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:5: +1:9 +- _1 = f::(g) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/cycle.rs:+1:5: +1:9 ++ StorageLive(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:9 ++ _2 = g; // scope 0 at $DIR/cycle.rs:+1:5: +1:9 + // mir::Constant +- // + span: $DIR/cycle.rs:17:5: 17:6 +- // + literal: Const { ty: fn(fn() {g}) {f::}, val: Value() } +- // mir::Constant + // + span: $DIR/cycle.rs:17:7: 17:8 + // + literal: Const { ty: fn() {g}, val: Value() } ++ StorageLive(_4); // scope 0 at $DIR/cycle.rs:+1:5: +1:9 ++ StorageLive(_3); // scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ _3 = &_2; // scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ _5 = const (); // scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ _6 = main() -> [return: bb2, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: fn() {main}, val: Value() } + } + + bb1: { ++ StorageDead(_4); // scope 0 at $DIR/cycle.rs:+1:5: +1:9 ++ StorageDead(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:9 + StorageDead(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:10 + _0 = const (); // scope 0 at $DIR/cycle.rs:+0:11: +2:2 + return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2 ++ } ++ ++ bb2: { ++ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:7: 6:8 ++ drop(_2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/cycle.rs:7:1: 7:2 + } + } + diff --git a/tests/mir-opt/inline/cycle.main.Inline.diff b/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/cycle.main.Inline.diff rename to tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/cycle.rs b/tests/mir-opt/inline/cycle.rs index 9e8950d8a3d61..af2ca895cc637 100644 --- a/tests/mir-opt/inline/cycle.rs +++ b/tests/mir-opt/inline/cycle.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR cycle.f.Inline.diff #[inline(always)] diff --git a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff new file mode 100644 index 0000000000000..2e5afd6cece6a --- /dev/null +++ b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff @@ -0,0 +1,54 @@ +- // MIR for `get_query` before Inline ++ // MIR for `get_query` after Inline + + fn get_query(_1: &T) -> () { + debug t => _1; // in scope 0 at $DIR/dyn_trait.rs:+0:31: +0:32 + let mut _0: (); // return place in scope 0 at $DIR/dyn_trait.rs:+0:38: +0:38 + let _2: &::C; // in scope 0 at $DIR/dyn_trait.rs:+1:9: +1:10 + let mut _3: &T; // in scope 0 at $DIR/dyn_trait.rs:+1:22: +1:23 + let mut _4: &::C; // in scope 0 at $DIR/dyn_trait.rs:+2:23: +2:24 + scope 1 { + debug c => _2; // in scope 1 at $DIR/dyn_trait.rs:+1:9: +1:10 ++ scope 2 (inlined try_execute_query::<::C>) { // at $DIR/dyn_trait.rs:35:5: 35:25 ++ debug c => _4; // in scope 2 at $DIR/dyn_trait.rs:27:36: 27:37 ++ let mut _5: &dyn Cache::V>; // in scope 2 at $DIR/dyn_trait.rs:28:14: 28:15 ++ scope 3 (inlined mk_cycle::<::V>) { // at $DIR/dyn_trait.rs:28:5: 28:16 ++ debug c => _5; // in scope 3 at $DIR/dyn_trait.rs:21:27: 21:28 ++ } ++ } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/dyn_trait.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/dyn_trait.rs:+1:22: +1:23 + _3 = &(*_1); // scope 0 at $DIR/dyn_trait.rs:+1:22: +1:23 + _2 = ::cache::(move _3) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/dyn_trait.rs:+1:13: +1:24 + // mir::Constant + // + span: $DIR/dyn_trait.rs:34:13: 34:21 + // + user_ty: UserType(0) + // + literal: Const { ty: for<'a> fn(&'a T) -> &'a ::C {::cache::}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/dyn_trait.rs:+1:23: +1:24 + StorageLive(_4); // scope 1 at $DIR/dyn_trait.rs:+2:23: +2:24 + _4 = &(*_2); // scope 1 at $DIR/dyn_trait.rs:+2:23: +2:24 +- _0 = try_execute_query::<::C>(move _4) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/dyn_trait.rs:+2:5: +2:25 ++ StorageLive(_5); // scope 2 at $DIR/dyn_trait.rs:28:14: 28:15 ++ _5 = _4 as &dyn Cache::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn_trait.rs:28:14: 28:15 ++ _0 = ::V> as Cache>::store_nocache(_5) -> [return: bb2, unwind unreachable]; // scope 3 at $DIR/dyn_trait.rs:22:5: 22:22 + // mir::Constant +- // + span: $DIR/dyn_trait.rs:35:5: 35:22 +- // + literal: Const { ty: for<'a> fn(&'a ::C) {try_execute_query::<::C>}, val: Value() } ++ // + span: $DIR/dyn_trait.rs:22:7: 22:20 ++ // + literal: Const { ty: for<'a> fn(&'a dyn Cache::V>) {::V> as Cache>::store_nocache}, val: Value() } + } + + bb2: { ++ StorageDead(_5); // scope 2 at $DIR/dyn_trait.rs:28:15: 28:16 + StorageDead(_4); // scope 1 at $DIR/dyn_trait.rs:+2:24: +2:25 + StorageDead(_2); // scope 0 at $DIR/dyn_trait.rs:+3:1: +3:2 + return; // scope 0 at $DIR/dyn_trait.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/dyn_trait.get_query.Inline.diff rename to tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.panic-abort.diff b/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.panic-abort.diff new file mode 100644 index 0000000000000..46a1ea59bc27a --- /dev/null +++ b/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.panic-abort.diff @@ -0,0 +1,23 @@ +- // MIR for `mk_cycle` before Inline ++ // MIR for `mk_cycle` after Inline + + fn mk_cycle(_1: &dyn Cache) -> () { + debug c => _1; // in scope 0 at $DIR/dyn_trait.rs:+0:27: +0:28 + let mut _0: (); // return place in scope 0 at $DIR/dyn_trait.rs:+0:49: +0:49 + let mut _2: &dyn Cache; // in scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22 + _2 = &(*_1); // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22 + _0 = as Cache>::store_nocache(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22 + // mir::Constant + // + span: $DIR/dyn_trait.rs:22:7: 22:20 + // + literal: Const { ty: for<'a> fn(&'a dyn Cache) { as Cache>::store_nocache}, val: Value() } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/dyn_trait.rs:+1:21: +1:22 + return; // scope 0 at $DIR/dyn_trait.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff b/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff rename to tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/dyn_trait.rs b/tests/mir-opt/inline/dyn_trait.rs index 2af81f8257053..0faeec0bbab27 100644 --- a/tests/mir-opt/inline/dyn_trait.rs +++ b/tests/mir-opt/inline/dyn_trait.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] use std::fmt::Debug; diff --git a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff new file mode 100644 index 0000000000000..5d84f0f508a1c --- /dev/null +++ b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff @@ -0,0 +1,33 @@ +- // MIR for `try_execute_query` before Inline ++ // MIR for `try_execute_query` after Inline + + fn try_execute_query(_1: &C) -> () { + debug c => _1; // in scope 0 at $DIR/dyn_trait.rs:+0:36: +0:37 + let mut _0: (); // return place in scope 0 at $DIR/dyn_trait.rs:+0:43: +0:43 + let mut _2: &dyn Cache::V>; // in scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 + let mut _3: &C; // in scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 ++ scope 1 (inlined mk_cycle::<::V>) { // at $DIR/dyn_trait.rs:28:5: 28:16 ++ debug c => _2; // in scope 1 at $DIR/dyn_trait.rs:21:27: 21:28 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 + StorageLive(_3); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 + _3 = &(*_1); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 + _2 = move _3 as &dyn Cache::V> (Pointer(Unsize)); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 + StorageDead(_3); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 +- _0 = mk_cycle::<::V>(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:16 ++ _0 = ::V> as Cache>::store_nocache(_2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/dyn_trait.rs:22:5: 22:22 + // mir::Constant +- // + span: $DIR/dyn_trait.rs:28:5: 28:13 +- // + literal: Const { ty: for<'a> fn(&'a (dyn Cache::V> + 'a)) {mk_cycle::<::V>}, val: Value() } ++ // + span: $DIR/dyn_trait.rs:22:7: 22:20 ++ // + literal: Const { ty: for<'a> fn(&'a dyn Cache::V>) {::V> as Cache>::store_nocache}, val: Value() } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/dyn_trait.rs:+1:15: +1:16 + return; // scope 0 at $DIR/dyn_trait.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff rename to tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-abort.diff b/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-abort.diff new file mode 100644 index 0000000000000..967186b1989a6 --- /dev/null +++ b/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-abort.diff @@ -0,0 +1,175 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/exponential_runtime.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 ++ scope 1 (inlined <() as G>::call) { // at $DIR/exponential_runtime.rs:87:5: 87:22 ++ let _2: (); // in scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25 ++ let _3: (); // in scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25 ++ let _4: (); // in scope 1 at $DIR/exponential_runtime.rs:76:9: 76:25 ++ scope 2 (inlined <() as F>::call) { // at $DIR/exponential_runtime.rs:74:9: 74:25 ++ let _5: (); // in scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25 ++ let _6: (); // in scope 2 at $DIR/exponential_runtime.rs:63:9: 63:25 ++ let _7: (); // in scope 2 at $DIR/exponential_runtime.rs:64:9: 64:25 ++ scope 3 (inlined <() as E>::call) { // at $DIR/exponential_runtime.rs:62:9: 62:25 ++ let _8: (); // in scope 3 at $DIR/exponential_runtime.rs:50:9: 50:25 ++ let _9: (); // in scope 3 at $DIR/exponential_runtime.rs:51:9: 51:25 ++ let _10: (); // in scope 3 at $DIR/exponential_runtime.rs:52:9: 52:25 ++ scope 4 (inlined <() as D>::call) { // at $DIR/exponential_runtime.rs:50:9: 50:25 ++ let _11: (); // in scope 4 at $DIR/exponential_runtime.rs:38:9: 38:25 ++ let _12: (); // in scope 4 at $DIR/exponential_runtime.rs:39:9: 39:25 ++ let _13: (); // in scope 4 at $DIR/exponential_runtime.rs:40:9: 40:25 ++ scope 5 (inlined <() as C>::call) { // at $DIR/exponential_runtime.rs:38:9: 38:25 ++ let _14: (); // in scope 5 at $DIR/exponential_runtime.rs:26:9: 26:25 ++ let _15: (); // in scope 5 at $DIR/exponential_runtime.rs:27:9: 27:25 ++ let _16: (); // in scope 5 at $DIR/exponential_runtime.rs:28:9: 28:25 ++ scope 6 (inlined <() as B>::call) { // at $DIR/exponential_runtime.rs:26:9: 26:25 ++ let _17: (); // in scope 6 at $DIR/exponential_runtime.rs:14:9: 14:25 ++ let _18: (); // in scope 6 at $DIR/exponential_runtime.rs:15:9: 15:25 ++ let _19: (); // in scope 6 at $DIR/exponential_runtime.rs:16:9: 16:25 ++ } ++ } ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 +- _1 = <() as G>::call() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 ++ StorageLive(_2); // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 ++ StorageLive(_3); // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 ++ StorageLive(_4); // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 ++ StorageLive(_5); // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25 ++ StorageLive(_6); // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25 ++ StorageLive(_7); // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25 ++ StorageLive(_8); // scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25 ++ StorageLive(_9); // scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25 ++ StorageLive(_10); // scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25 ++ StorageLive(_11); // scope 3 at $DIR/exponential_runtime.rs:50:9: 50:25 ++ StorageLive(_12); // scope 3 at $DIR/exponential_runtime.rs:50:9: 50:25 ++ StorageLive(_13); // scope 3 at $DIR/exponential_runtime.rs:50:9: 50:25 ++ StorageLive(_14); // scope 4 at $DIR/exponential_runtime.rs:38:9: 38:25 ++ StorageLive(_15); // scope 4 at $DIR/exponential_runtime.rs:38:9: 38:25 ++ StorageLive(_16); // scope 4 at $DIR/exponential_runtime.rs:38:9: 38:25 ++ StorageLive(_17); // scope 5 at $DIR/exponential_runtime.rs:26:9: 26:25 ++ StorageLive(_18); // scope 5 at $DIR/exponential_runtime.rs:26:9: 26:25 ++ StorageLive(_19); // scope 5 at $DIR/exponential_runtime.rs:26:9: 26:25 ++ _17 = <() as A>::call() -> [return: bb12, unwind unreachable]; // scope 6 at $DIR/exponential_runtime.rs:14:9: 14:25 + // mir::Constant +- // + span: $DIR/exponential_runtime.rs:87:5: 87:20 +- // + literal: Const { ty: fn() {<() as G>::call}, val: Value() } ++ // + span: $DIR/exponential_runtime.rs:14:9: 14:23 ++ // + literal: Const { ty: fn() {<() as A>::call}, val: Value() } + } + + bb1: { ++ StorageDead(_4); // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 ++ StorageDead(_3); // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 ++ StorageDead(_2); // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 + StorageDead(_1); // scope 0 at $DIR/exponential_runtime.rs:+1:22: +1:23 + _0 = const (); // scope 0 at $DIR/exponential_runtime.rs:+0:11: +2:2 + return; // scope 0 at $DIR/exponential_runtime.rs:+2:2: +2:2 ++ } ++ ++ bb2: { ++ StorageDead(_7); // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25 ++ StorageDead(_6); // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25 ++ StorageDead(_5); // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25 ++ _3 = <() as F>::call() -> [return: bb3, unwind unreachable]; // scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:75:9: 75:23 ++ // + literal: Const { ty: fn() {<() as F>::call}, val: Value() } ++ } ++ ++ bb3: { ++ _4 = <() as F>::call() -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/exponential_runtime.rs:76:9: 76:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:76:9: 76:23 ++ // + literal: Const { ty: fn() {<() as F>::call}, val: Value() } ++ } ++ ++ bb4: { ++ StorageDead(_10); // scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25 ++ StorageDead(_9); // scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25 ++ StorageDead(_8); // scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25 ++ _6 = <() as E>::call() -> [return: bb5, unwind unreachable]; // scope 2 at $DIR/exponential_runtime.rs:63:9: 63:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:63:9: 63:23 ++ // + literal: Const { ty: fn() {<() as E>::call}, val: Value() } ++ } ++ ++ bb5: { ++ _7 = <() as E>::call() -> [return: bb2, unwind unreachable]; // scope 2 at $DIR/exponential_runtime.rs:64:9: 64:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:64:9: 64:23 ++ // + literal: Const { ty: fn() {<() as E>::call}, val: Value() } ++ } ++ ++ bb6: { ++ StorageDead(_13); // scope 3 at $DIR/exponential_runtime.rs:50:9: 50:25 ++ StorageDead(_12); // scope 3 at $DIR/exponential_runtime.rs:50:9: 50:25 ++ StorageDead(_11); // scope 3 at $DIR/exponential_runtime.rs:50:9: 50:25 ++ _9 = <() as D>::call() -> [return: bb7, unwind unreachable]; // scope 3 at $DIR/exponential_runtime.rs:51:9: 51:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:51:9: 51:23 ++ // + literal: Const { ty: fn() {<() as D>::call}, val: Value() } ++ } ++ ++ bb7: { ++ _10 = <() as D>::call() -> [return: bb4, unwind unreachable]; // scope 3 at $DIR/exponential_runtime.rs:52:9: 52:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:52:9: 52:23 ++ // + literal: Const { ty: fn() {<() as D>::call}, val: Value() } ++ } ++ ++ bb8: { ++ StorageDead(_16); // scope 4 at $DIR/exponential_runtime.rs:38:9: 38:25 ++ StorageDead(_15); // scope 4 at $DIR/exponential_runtime.rs:38:9: 38:25 ++ StorageDead(_14); // scope 4 at $DIR/exponential_runtime.rs:38:9: 38:25 ++ _12 = <() as C>::call() -> [return: bb9, unwind unreachable]; // scope 4 at $DIR/exponential_runtime.rs:39:9: 39:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:39:9: 39:23 ++ // + literal: Const { ty: fn() {<() as C>::call}, val: Value() } ++ } ++ ++ bb9: { ++ _13 = <() as C>::call() -> [return: bb6, unwind unreachable]; // scope 4 at $DIR/exponential_runtime.rs:40:9: 40:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:40:9: 40:23 ++ // + literal: Const { ty: fn() {<() as C>::call}, val: Value() } ++ } ++ ++ bb10: { ++ StorageDead(_19); // scope 5 at $DIR/exponential_runtime.rs:26:9: 26:25 ++ StorageDead(_18); // scope 5 at $DIR/exponential_runtime.rs:26:9: 26:25 ++ StorageDead(_17); // scope 5 at $DIR/exponential_runtime.rs:26:9: 26:25 ++ _15 = <() as B>::call() -> [return: bb11, unwind unreachable]; // scope 5 at $DIR/exponential_runtime.rs:27:9: 27:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:27:9: 27:23 ++ // + literal: Const { ty: fn() {<() as B>::call}, val: Value() } ++ } ++ ++ bb11: { ++ _16 = <() as B>::call() -> [return: bb8, unwind unreachable]; // scope 5 at $DIR/exponential_runtime.rs:28:9: 28:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:28:9: 28:23 ++ // + literal: Const { ty: fn() {<() as B>::call}, val: Value() } ++ } ++ ++ bb12: { ++ _18 = <() as A>::call() -> [return: bb13, unwind unreachable]; // scope 6 at $DIR/exponential_runtime.rs:15:9: 15:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:15:9: 15:23 ++ // + literal: Const { ty: fn() {<() as A>::call}, val: Value() } ++ } ++ ++ bb13: { ++ _19 = <() as A>::call() -> [return: bb10, unwind unreachable]; // scope 6 at $DIR/exponential_runtime.rs:16:9: 16:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:16:9: 16:23 ++ // + literal: Const { ty: fn() {<() as A>::call}, val: Value() } + } + } + diff --git a/tests/mir-opt/inline/exponential_runtime.main.Inline.diff b/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/exponential_runtime.main.Inline.diff rename to tests/mir-opt/inline/exponential_runtime.main.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/exponential_runtime.rs b/tests/mir-opt/inline/exponential_runtime.rs index 39985528f462a..cfa9ff210f846 100644 --- a/tests/mir-opt/inline/exponential_runtime.rs +++ b/tests/mir-opt/inline/exponential_runtime.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Checks that code with exponential runtime does not have exponential behavior in inlining. trait A { diff --git a/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.panic-abort.diff new file mode 100644 index 0000000000000..abb0263d7e48d --- /dev/null +++ b/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.panic-abort.diff @@ -0,0 +1,24 @@ +- // MIR for `inlined_no_sanitize` before Inline ++ // MIR for `inlined_no_sanitize` after Inline + + fn inlined_no_sanitize() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:37: +0:37 + let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 ++ scope 1 (inlined no_sanitize) { // at $DIR/inline_compatibility.rs:25:5: 25:18 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 +- _1 = no_sanitize() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 +- // mir::Constant +- // + span: $DIR/inline_compatibility.rs:25:5: 25:16 +- // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value() } +- } +- +- bb1: { + StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:18: +1:19 + _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:37: +2:2 + return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff b/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.panic-unwind.diff similarity index 95% rename from tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff rename to tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.panic-unwind.diff index e30a5e116ea4b..de4462227fd8d 100644 --- a/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff +++ b/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.panic-unwind.diff @@ -4,14 +4,14 @@ fn inlined_no_sanitize() -> () { let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:37: +0:37 let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 -+ scope 1 (inlined no_sanitize) { // at $DIR/inline_compatibility.rs:24:5: 24:18 ++ scope 1 (inlined no_sanitize) { // at $DIR/inline_compatibility.rs:25:5: 25:18 + } bb0: { StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 - _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 - // mir::Constant -- // + span: $DIR/inline_compatibility.rs:24:5: 24:16 +- // + span: $DIR/inline_compatibility.rs:25:5: 25:16 - // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value() } - } - diff --git a/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.panic-abort.diff new file mode 100644 index 0000000000000..e758127265ebd --- /dev/null +++ b/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.panic-abort.diff @@ -0,0 +1,24 @@ +- // MIR for `inlined_target_feature` before Inline ++ // MIR for `inlined_target_feature` after Inline + + fn inlined_target_feature() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:40: +0:40 + let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 ++ scope 1 (inlined target_feature) { // at $DIR/inline_compatibility.rs:14:5: 14:21 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 +- _1 = target_feature() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 +- // mir::Constant +- // + span: $DIR/inline_compatibility.rs:14:5: 14:19 +- // + literal: Const { ty: unsafe fn() {target_feature}, val: Value() } +- } +- +- bb1: { + StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:21: +1:22 + _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:40: +2:2 + return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff b/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.panic-unwind.diff similarity index 95% rename from tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff rename to tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.panic-unwind.diff index c2b3c46a30c69..9eb565bd0e71e 100644 --- a/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff +++ b/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.panic-unwind.diff @@ -4,14 +4,14 @@ fn inlined_target_feature() -> () { let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:40: +0:40 let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 -+ scope 1 (inlined target_feature) { // at $DIR/inline_compatibility.rs:13:5: 13:21 ++ scope 1 (inlined target_feature) { // at $DIR/inline_compatibility.rs:14:5: 14:21 + } bb0: { StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 - _1 = target_feature() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 - // mir::Constant -- // + span: $DIR/inline_compatibility.rs:13:5: 13:19 +- // + span: $DIR/inline_compatibility.rs:14:5: 14:19 - // + literal: Const { ty: unsafe fn() {target_feature}, val: Value() } - } - diff --git a/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.panic-abort.diff new file mode 100644 index 0000000000000..124435cd258ef --- /dev/null +++ b/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.panic-abort.diff @@ -0,0 +1,25 @@ +- // MIR for `not_inlined_c_variadic` before Inline ++ // MIR for `not_inlined_c_variadic` after Inline + + fn not_inlined_c_variadic() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:40: +0:40 + let _1: u32; // in scope 0 at $DIR/inline_compatibility.rs:+1:9: +1:10 + scope 1 { + debug s => _1; // in scope 1 at $DIR/inline_compatibility.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:9: +1:10 + _1 = sum(const 4_u32, const 4_u32, const 30_u32, const 200_u32, const 1000_u32) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_compatibility.rs:+1:13: +1:52 + // mir::Constant + // + span: $DIR/inline_compatibility.rs:43:13: 43:16 + // + literal: Const { ty: unsafe extern "C" fn(u32, ...) -> u32 {sum}, val: Value() } + } + + bb1: { + _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:40: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.panic-unwind.diff similarity index 97% rename from tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff rename to tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.panic-unwind.diff index 0ca5a5f70b7fd..775f3af76b6cf 100644 --- a/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff +++ b/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.panic-unwind.diff @@ -12,7 +12,7 @@ StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:9: +1:10 _1 = sum(const 4_u32, const 4_u32, const 30_u32, const 200_u32, const 1000_u32) -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:13: +1:52 // mir::Constant - // + span: $DIR/inline_compatibility.rs:42:13: 42:16 + // + span: $DIR/inline_compatibility.rs:43:13: 43:16 // + literal: Const { ty: unsafe extern "C" fn(u32, ...) -> u32 {sum}, val: Value() } } diff --git a/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.panic-abort.diff new file mode 100644 index 0000000000000..21dc2ee8da1f8 --- /dev/null +++ b/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.panic-abort.diff @@ -0,0 +1,22 @@ +- // MIR for `not_inlined_no_sanitize` before Inline ++ // MIR for `not_inlined_no_sanitize` after Inline + + fn not_inlined_no_sanitize() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:41: +0:41 + let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 + _1 = no_sanitize() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 + // mir::Constant + // + span: $DIR/inline_compatibility.rs:30:5: 30:16 + // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value() } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:18: +1:19 + _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:41: +2:2 + return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.panic-unwind.diff similarity index 97% rename from tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff rename to tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.panic-unwind.diff index 00d405c77f91d..8ef5b8ba98e5e 100644 --- a/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff +++ b/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.panic-unwind.diff @@ -9,7 +9,7 @@ StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 // mir::Constant - // + span: $DIR/inline_compatibility.rs:29:5: 29:16 + // + span: $DIR/inline_compatibility.rs:30:5: 30:16 // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value() } } diff --git a/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.panic-abort.diff new file mode 100644 index 0000000000000..02feec05befde --- /dev/null +++ b/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.panic-abort.diff @@ -0,0 +1,22 @@ +- // MIR for `not_inlined_target_feature` before Inline ++ // MIR for `not_inlined_target_feature` after Inline + + fn not_inlined_target_feature() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:44: +0:44 + let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 + _1 = target_feature() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 + // mir::Constant + // + span: $DIR/inline_compatibility.rs:19:5: 19:19 + // + literal: Const { ty: unsafe fn() {target_feature}, val: Value() } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:21: +1:22 + _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:44: +2:2 + return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.panic-unwind.diff similarity index 97% rename from tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff rename to tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.panic-unwind.diff index 8b9c86f5515a3..2523162dfff92 100644 --- a/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff +++ b/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.panic-unwind.diff @@ -9,7 +9,7 @@ StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 _1 = target_feature() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 // mir::Constant - // + span: $DIR/inline_compatibility.rs:18:5: 18:19 + // + span: $DIR/inline_compatibility.rs:19:5: 19:19 // + literal: Const { ty: unsafe fn() {target_feature}, val: Value() } } diff --git a/tests/mir-opt/inline/inline_compatibility.rs b/tests/mir-opt/inline/inline_compatibility.rs index 30aff0a64efb9..1527fea1c93c1 100644 --- a/tests/mir-opt/inline/inline_compatibility.rs +++ b/tests/mir-opt/inline/inline_compatibility.rs @@ -1,6 +1,7 @@ // Checks that only functions with compatible attributes are inlined. // // only-x86_64 +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] #![feature(no_sanitize)] diff --git a/tests/mir-opt/inline/inline_cycle.one.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_cycle.one.Inline.panic-abort.diff new file mode 100644 index 0000000000000..228a34a492ebd --- /dev/null +++ b/tests/mir-opt/inline/inline_cycle.one.Inline.panic-abort.diff @@ -0,0 +1,30 @@ +- // MIR for `one` before Inline ++ // MIR for `one` after Inline + + fn one() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_cycle.rs:+0:10: +0:10 + let _1: (); // in scope 0 at $DIR/inline_cycle.rs:+1:5: +1:24 ++ scope 1 (inlined ::call) { // at $DIR/inline_cycle.rs:15:5: 15:24 ++ scope 2 (inlined as Call>::call) { // at $DIR/inline_cycle.rs:44:9: 44:23 ++ scope 3 (inlined as Call>::call) { // at $DIR/inline_cycle.rs:29:9: 29:31 ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:24 +- _1 = ::call() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:24 ++ _1 = ::call() -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/inline_cycle.rs:37:9: 37:28 + // mir::Constant +- // + span: $DIR/inline_cycle.rs:15:5: 15:22 ++ // + span: $DIR/inline_cycle.rs:37:9: 37:26 + // + literal: Const { ty: fn() {::call}, val: Value() } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline_cycle.rs:+1:24: +1:25 + _0 = const (); // scope 0 at $DIR/inline_cycle.rs:+0:10: +2:2 + return; // scope 0 at $DIR/inline_cycle.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_cycle.one.Inline.diff b/tests/mir-opt/inline/inline_cycle.one.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_cycle.one.Inline.diff rename to tests/mir-opt/inline/inline_cycle.one.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_cycle.rs b/tests/mir-opt/inline/inline_cycle.rs index 2f81696cf03e9..42a6914c96516 100644 --- a/tests/mir-opt/inline/inline_cycle.rs +++ b/tests/mir-opt/inline/inline_cycle.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Check that inliner handles various forms of recursion and doesn't fall into // an infinite inlining cycle. The particular outcome of inlining is not // crucial otherwise. diff --git a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff new file mode 100644 index 0000000000000..123fa5cb9132f --- /dev/null +++ b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff @@ -0,0 +1,55 @@ +- // MIR for `two` before Inline ++ // MIR for `two` after Inline + + fn two() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_cycle.rs:+0:10: +0:10 + let _1: (); // in scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 ++ let mut _2: fn() {f}; // in scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 ++ let mut _4: (); // in scope 0 at $DIR/inline_cycle.rs:55:5: 55:8 ++ scope 1 (inlined call::) { // at $DIR/inline_cycle.rs:50:5: 50:12 ++ debug f => _2; // in scope 1 at $DIR/inline_cycle.rs:54:22: 54:23 ++ let _3: (); // in scope 1 at $DIR/inline_cycle.rs:55:5: 55:8 ++ scope 2 (inlined >::call_once - shim(fn() {f})) { // at $DIR/inline_cycle.rs:55:5: 55:8 ++ scope 3 (inlined f) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ scope 4 (inlined call::) { // at $DIR/inline_cycle.rs:60:5: 60:12 ++ debug f => f; // in scope 4 at $DIR/inline_cycle.rs:54:22: 54:23 ++ let _5: (); // in scope 4 at $DIR/inline_cycle.rs:55:5: 55:8 ++ scope 5 (inlined >::call_once - shim(fn() {f})) { // at $DIR/inline_cycle.rs:55:5: 55:8 ++ } ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 +- _1 = call::(f) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 ++ StorageLive(_2); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 ++ _2 = f; // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 + // mir::Constant +- // + span: $DIR/inline_cycle.rs:50:5: 50:9 +- // + literal: Const { ty: fn(fn() {f}) {call::}, val: Value() } +- // mir::Constant + // + span: $DIR/inline_cycle.rs:50:10: 50:11 + // + literal: Const { ty: fn() {f}, val: Value() } ++ StorageLive(_3); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 ++ StorageLive(_4); // scope 1 at $DIR/inline_cycle.rs:55:5: 55:8 ++ _4 = const (); // scope 1 at $DIR/inline_cycle.rs:55:5: 55:8 ++ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ _5 = f() -> [return: bb1, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: fn() {f}, val: Value() } + } + + bb1: { ++ StorageDead(_5); // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ StorageDead(_4); // scope 1 at $DIR/inline_cycle.rs:55:5: 55:8 ++ StorageDead(_3); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 ++ StorageDead(_2); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 + StorageDead(_1); // scope 0 at $DIR/inline_cycle.rs:+1:12: +1:13 + _0 = const (); // scope 0 at $DIR/inline_cycle.rs:+0:10: +2:2 + return; // scope 0 at $DIR/inline_cycle.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_cycle.two.Inline.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_cycle.two.Inline.diff rename to tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff new file mode 100644 index 0000000000000..25a97cf021018 --- /dev/null +++ b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff @@ -0,0 +1,31 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_cycle_generic.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/inline_cycle_generic.rs:+1:5: +1:24 ++ scope 1 (inlined ::call) { // at $DIR/inline_cycle_generic.rs:10:5: 10:24 ++ scope 2 (inlined as Call>::call) { // at $DIR/inline_cycle_generic.rs:39:9: 39:31 ++ scope 3 (inlined ::call) { // at $DIR/inline_cycle_generic.rs:32:9: 32:28 ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_cycle_generic.rs:+1:5: +1:24 +- _1 = ::call() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_cycle_generic.rs:+1:5: +1:24 ++ _1 = as Call>::call() -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/inline_cycle_generic.rs:24:9: 24:31 + // mir::Constant +- // + span: $DIR/inline_cycle_generic.rs:10:5: 10:22 +- // + literal: Const { ty: fn() {::call}, val: Value() } ++ // + span: $DIR/inline_cycle_generic.rs:24:9: 24:29 ++ // + literal: Const { ty: fn() { as Call>::call}, val: Value() } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline_cycle_generic.rs:+1:24: +1:25 + _0 = const (); // scope 0 at $DIR/inline_cycle_generic.rs:+0:11: +2:2 + return; // scope 0 at $DIR/inline_cycle_generic.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.diff b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_cycle_generic.main.Inline.diff rename to tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_cycle_generic.rs b/tests/mir-opt/inline/inline_cycle_generic.rs index 84e6e4005a6e7..ef261b04c8085 100644 --- a/tests/mir-opt/inline/inline_cycle_generic.rs +++ b/tests/mir-opt/inline/inline_cycle_generic.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Check that inliner handles various forms of recursion and doesn't fall into // an infinite inlining cycle. The particular outcome of inlining is not // crucial otherwise. diff --git a/tests/mir-opt/inline/inline_diverging.f.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.f.Inline.panic-abort.diff new file mode 100644 index 0000000000000..a818e7355baa7 --- /dev/null +++ b/tests/mir-opt/inline/inline_diverging.f.Inline.panic-abort.diff @@ -0,0 +1,24 @@ +- // MIR for `f` before Inline ++ // MIR for `f` after Inline + + fn f() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_diverging.rs:+0:12: +0:12 + let mut _1: !; // in scope 0 at $DIR/inline_diverging.rs:+0:12: +2:2 + let _2: !; // in scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12 ++ scope 1 (inlined sleep) { // at $DIR/inline_diverging.rs:8:5: 8:12 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12 +- _2 = sleep() -> unwind unreachable; // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12 +- // mir::Constant +- // + span: $DIR/inline_diverging.rs:8:5: 8:10 +- // + literal: Const { ty: fn() -> ! {sleep}, val: Value() } ++ goto -> bb1; // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12 ++ } ++ ++ bb1: { ++ goto -> bb1; // scope 1 at $DIR/inline_diverging.rs:39:5: 39:12 + } + } + diff --git a/tests/mir-opt/inline/inline_diverging.f.Inline.diff b/tests/mir-opt/inline/inline_diverging.f.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_diverging.f.Inline.diff rename to tests/mir-opt/inline/inline_diverging.f.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff new file mode 100644 index 0000000000000..77a156a513e60 --- /dev/null +++ b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff @@ -0,0 +1,49 @@ +- // MIR for `g` before Inline ++ // MIR for `g` after Inline + + fn g(_1: i32) -> u32 { + debug i => _1; // in scope 0 at $DIR/inline_diverging.rs:+0:10: +0:11 + let mut _0: u32; // return place in scope 0 at $DIR/inline_diverging.rs:+0:21: +0:24 + let mut _2: bool; // in scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 + let mut _3: i32; // in scope 0 at $DIR/inline_diverging.rs:+1:8: +1:9 + let mut _4: i32; // in scope 0 at $DIR/inline_diverging.rs:+2:9: +2:10 + let mut _5: !; // in scope 0 at $DIR/inline_diverging.rs:+3:12: +5:6 + let _6: !; // in scope 0 at $DIR/inline_diverging.rs:+4:9: +4:16 ++ scope 1 (inlined panic) { // at $DIR/inline_diverging.rs:16:9: 16:16 ++ let mut _7: !; // in scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 + StorageLive(_3); // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:9 + _2 = Gt(move _3, const 0_i32); // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 + StorageDead(_3); // scope 0 at $DIR/inline_diverging.rs:+1:12: +1:13 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 + } + + bb1: { + StorageLive(_4); // scope 0 at $DIR/inline_diverging.rs:+2:9: +2:10 + _4 = _1; // scope 0 at $DIR/inline_diverging.rs:+2:9: +2:10 + _0 = move _4 as u32 (IntToInt); // scope 0 at $DIR/inline_diverging.rs:+2:9: +2:17 + StorageDead(_4); // scope 0 at $DIR/inline_diverging.rs:+2:16: +2:17 + StorageDead(_2); // scope 0 at $DIR/inline_diverging.rs:+5:5: +5:6 + return; // scope 0 at $DIR/inline_diverging.rs:+6:2: +6:2 + } + + bb2: { + StorageLive(_6); // scope 0 at $DIR/inline_diverging.rs:+4:9: +4:16 +- _6 = panic() -> unwind unreachable; // scope 0 at $DIR/inline_diverging.rs:+4:9: +4:16 ++ StorageLive(_7); // scope 0 at $DIR/inline_diverging.rs:+4:9: +4:16 ++ _7 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL + // mir::Constant +- // + span: $DIR/inline_diverging.rs:16:9: 16:14 +- // + literal: Const { ty: fn() -> ! {panic}, val: Value() } ++ // + span: $SRC_DIR/std/src/panic.rs:LL:COL ++ // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value() } ++ // mir::Constant ++ // + span: $SRC_DIR/std/src/panic.rs:LL:COL ++ // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + } + diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_diverging.g.Inline.diff rename to tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff new file mode 100644 index 0000000000000..b864cbdfad0dc --- /dev/null +++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff @@ -0,0 +1,51 @@ +- // MIR for `h` before Inline ++ // MIR for `h` after Inline + + fn h() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_diverging.rs:+0:12: +0:12 + let _1: (!, !); // in scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ let mut _7: (); // in scope 0 at $DIR/inline_diverging.rs:27:13: 27:16 ++ scope 1 (inlined call_twice:: ! {sleep}>) { // at $DIR/inline_diverging.rs:22:5: 22:22 ++ debug f => _2; // in scope 1 at $DIR/inline_diverging.rs:26:36: 26:37 ++ let mut _3: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline_diverging.rs:27:13: 27:14 ++ let mut _4: !; // in scope 1 at $DIR/inline_diverging.rs:29:6: 29:7 ++ let mut _5: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline_diverging.rs:28:13: 28:14 ++ let mut _6: !; // in scope 1 at $DIR/inline_diverging.rs:29:9: 29:10 ++ scope 2 { ++ debug a => _4; // in scope 2 at $DIR/inline_diverging.rs:27:9: 27:10 ++ scope 3 { ++ debug b => _6; // in scope 3 at $DIR/inline_diverging.rs:28:9: 28:10 ++ } ++ } ++ scope 4 (inlined ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline_diverging.rs:27:13: 27:16 ++ scope 5 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 +- _1 = call_twice:: ! {sleep}>(sleep) -> unwind unreachable; // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ StorageLive(_2); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ _2 = sleep; // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 + // mir::Constant +- // + span: $DIR/inline_diverging.rs:22:5: 22:15 +- // + literal: Const { ty: fn(fn() -> ! {sleep}) -> (!, !) {call_twice:: ! {sleep}>}, val: Value() } +- // mir::Constant + // + span: $DIR/inline_diverging.rs:22:16: 22:21 + // + literal: Const { ty: fn() -> ! {sleep}, val: Value() } ++ StorageLive(_4); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ StorageLive(_6); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ StorageLive(_3); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:14 ++ _3 = &_2; // scope 1 at $DIR/inline_diverging.rs:27:13: 27:14 ++ StorageLive(_7); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:16 ++ _7 = const (); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:16 ++ goto -> bb1; // scope 5 at $DIR/inline_diverging.rs:39:5: 39:12 ++ } ++ ++ bb1: { ++ goto -> bb1; // scope 5 at $DIR/inline_diverging.rs:39:5: 39:12 + } + } + diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_diverging.h.Inline.diff rename to tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_diverging.rs b/tests/mir-opt/inline/inline_diverging.rs index ae6f814c290c8..febf1a8a6bf57 100644 --- a/tests/mir-opt/inline/inline_diverging.rs +++ b/tests/mir-opt/inline/inline_diverging.rs @@ -1,6 +1,6 @@ // Tests inlining of diverging calls. // -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] // EMIT_MIR inline_diverging.f.Inline.diff diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff new file mode 100644 index 0000000000000..21a8bf09254ef --- /dev/null +++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff @@ -0,0 +1,127 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_generator.rs:+0:11: +0:11 + let _1: std::ops::GeneratorState; // in scope 0 at $DIR/inline_generator.rs:+1:9: +1:11 + let mut _2: std::pin::Pin<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>; // in scope 0 at $DIR/inline_generator.rs:+1:14: +1:32 + let mut _3: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline_generator.rs:+1:23: +1:31 + let mut _4: [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline_generator.rs:+1:28: +1:31 ++ let mut _5: bool; // in scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 + scope 1 { + debug _r => _1; // in scope 1 at $DIR/inline_generator.rs:+1:9: +1:11 + } ++ scope 2 (inlined g) { // at $DIR/inline_generator.rs:9:28: 9:31 ++ } ++ scope 3 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new) { // at $DIR/inline_generator.rs:9:14: 9:32 ++ debug pointer => _3; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL ++ scope 4 { ++ scope 5 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new_unchecked) { // at $SRC_DIR/core/src/pin.rs:LL:COL ++ debug pointer => _3; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ } ++ } ++ } ++ scope 6 (inlined g::{closure#0}) { // at $DIR/inline_generator.rs:9:33: 9:46 ++ debug a => _5; // in scope 6 at $DIR/inline_generator.rs:15:6: 15:7 ++ let mut _6: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _7: u32; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _8: i32; // in scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ let mut _9: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _10: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_generator.rs:+1:9: +1:11 + StorageLive(_2); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:32 + StorageLive(_3); // scope 0 at $DIR/inline_generator.rs:+1:23: +1:31 + StorageLive(_4); // scope 0 at $DIR/inline_generator.rs:+1:28: +1:31 +- _4 = g() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_generator.rs:+1:28: +1:31 +- // mir::Constant +- // + span: $DIR/inline_generator.rs:9:28: 9:29 +- // + literal: Const { ty: fn() -> impl Generator {g}, val: Value() } +- } +- +- bb1: { ++ _4 = [generator@$DIR/inline_generator.rs:15:5: 15:8 (#0)]; // scope 2 at $DIR/inline_generator.rs:15:5: 15:41 ++ // generator ++ // + def_id: DefId(0:7 ~ inline_generator[e37e]::g::{closure#0}) ++ // + substs: [ ++ // bool, ++ // i32, ++ // bool, ++ // {bool, i32}, ++ // (), ++ // ] ++ // + movability: Movable + _3 = &mut _4; // scope 0 at $DIR/inline_generator.rs:+1:23: +1:31 +- _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:32 +- // mir::Constant +- // + span: $DIR/inline_generator.rs:9:14: 9:22 +- // + user_ty: UserType(0) +- // + literal: Const { ty: fn(&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]) -> Pin<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]> {Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new}, val: Value() } +- } +- +- bb2: { ++ _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]> { pointer: move _3 }; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL + StorageDead(_3); // scope 0 at $DIR/inline_generator.rs:+1:31: +1:32 +- _1 = <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::resume(move _2, const false) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 +- // mir::Constant +- // + span: $DIR/inline_generator.rs:9:33: 9:39 +- // + literal: Const { ty: for<'a> fn(Pin<&'a mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>, bool) -> GeneratorState<<[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::Yield, <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::Return> {<[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::resume}, val: Value() } ++ StorageLive(_5); // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 ++ _5 = const false; // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 ++ _6 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ _7 = discriminant((*_6)); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ switchInt(move _7) -> [0: bb2, 1: bb6, 3: bb7, otherwise: bb8]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 + } + +- bb3: { ++ bb1: { ++ StorageDead(_5); // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 + StorageDead(_2); // scope 0 at $DIR/inline_generator.rs:+1:45: +1:46 + StorageDead(_4); // scope 0 at $DIR/inline_generator.rs:+1:46: +1:47 + _0 = const (); // scope 0 at $DIR/inline_generator.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_generator.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline_generator.rs:+2:2: +2:2 ++ } ++ ++ bb2: { ++ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ switchInt(_5) -> [0: bb3, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21 ++ } ++ ++ bb3: { ++ _8 = const 13_i32; // scope 6 at $DIR/inline_generator.rs:15:35: 15:37 ++ goto -> bb5; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ } ++ ++ bb4: { ++ _8 = const 7_i32; // scope 6 at $DIR/inline_generator.rs:15:24: 15:25 ++ goto -> bb5; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ } ++ ++ bb5: { ++ _1 = GeneratorState::::Yielded(move _8); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ _9 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ discriminant((*_9)) = 3; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:11: 15:39 ++ } ++ ++ bb6: { ++ assert(const false, "generator resumed after completion") -> [success: bb6, unwind unreachable]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ } ++ ++ bb7: { ++ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ StorageDead(_8); // scope 6 at $DIR/inline_generator.rs:15:38: 15:39 ++ _1 = GeneratorState::::Complete(_5); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ discriminant((*_10)) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:41: 15:41 ++ } ++ ++ bb8: { ++ unreachable; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 + } + } + diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_generator.main.Inline.diff rename to tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_generator.rs b/tests/mir-opt/inline/inline_generator.rs index d11b3e548f721..61f1da897bd10 100644 --- a/tests/mir-opt/inline/inline_generator.rs +++ b/tests/mir-opt/inline/inline_generator.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![feature(generators, generator_trait)] use std::ops::Generator; diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff new file mode 100644 index 0000000000000..3b3b29af3942f --- /dev/null +++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff @@ -0,0 +1,72 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_into_box_place.rs:+0:11: +0:11 + let _1: std::boxed::Box>; // in scope 0 at $DIR/inline_into_box_place.rs:+1:9: +1:11 + let mut _2: std::vec::Vec; // in scope 0 at $DIR/inline_into_box_place.rs:+1:38: +1:48 + scope 1 { + debug _x => _1; // in scope 1 at $DIR/inline_into_box_place.rs:+1:9: +1:11 + } ++ scope 2 (inlined Vec::::new) { // at $DIR/inline_into_box_place.rs:8:38: 8:48 ++ let mut _3: alloc::raw_vec::RawVec; // in scope 2 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ } ++ scope 3 (inlined Box::>::new) { // at $DIR/inline_into_box_place.rs:8:29: 8:49 ++ debug x => _2; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ let mut _4: usize; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ let mut _5: usize; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ let mut _6: *mut u8; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ let mut _7: *const std::vec::Vec; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ scope 4 { ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_into_box_place.rs:+1:9: +1:11 + StorageLive(_2); // scope 0 at $DIR/inline_into_box_place.rs:+1:38: +1:48 +- _2 = Vec::::new() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_into_box_place.rs:+1:38: +1:48 ++ StorageLive(_3); // scope 2 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ _3 = const _; // scope 2 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + // mir::Constant +- // + span: $DIR/inline_into_box_place.rs:8:38: 8:46 +- // + user_ty: UserType(2) +- // + literal: Const { ty: fn() -> Vec {Vec::::new}, val: Value() } ++ // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ // + user_ty: UserType(0) ++ // + literal: Const { ty: alloc::raw_vec::RawVec, val: Unevaluated(alloc::raw_vec::RawVec::::NEW, [u32], None) } ++ _2 = Vec:: { buf: move _3, len: const 0_usize }; // scope 2 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageDead(_3); // scope 2 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ _4 = SizeOf(std::vec::Vec); // scope 4 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ _5 = AlignOf(std::vec::Vec); // scope 4 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb2, unwind unreachable]; // scope 4 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ // mir::Constant ++ // + span: $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value() } + } + + bb1: { +- _1 = Box::>::new(move _2) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:49 +- // mir::Constant +- // + span: $DIR/inline_into_box_place.rs:8:29: 8:37 +- // + user_ty: UserType(1) +- // + literal: Const { ty: fn(Vec) -> Box> {Box::>::new}, val: Value() } ++ StorageDead(_1); // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2 ++ return; // scope 0 at $DIR/inline_into_box_place.rs:+2:2: +2:2 + } + + bb2: { ++ _1 = ShallowInitBox(move _6, std::vec::Vec); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ _7 = (((_1.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ (*_7) = move _2; // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_2); // scope 0 at $DIR/inline_into_box_place.rs:+1:48: +1:49 + _0 = const (); // scope 0 at $DIR/inline_into_box_place.rs:+0:11: +2:2 +- drop(_1) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2 +- } +- +- bb3: { +- StorageDead(_1); // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2 +- return; // scope 0 at $DIR/inline_into_box_place.rs:+2:2: +2:2 ++ drop(_1) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_into_box_place.main.Inline.diff rename to tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_into_box_place.rs b/tests/mir-opt/inline/inline_into_box_place.rs index 02823e4e1b745..bc578ec90e842 100644 --- a/tests/mir-opt/inline/inline_into_box_place.rs +++ b/tests/mir-opt/inline/inline_into_box_place.rs @@ -1,5 +1,5 @@ // ignore-endian-big -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // ignore-debug MIR alignment checks in std alter the diff, breaking the test // compile-flags: -Z mir-opt-level=4 diff --git a/tests/mir-opt/inline/inline_options.main.Inline.after.panic-abort.mir b/tests/mir-opt/inline/inline_options.main.Inline.after.panic-abort.mir new file mode 100644 index 0000000000000..755ef3fa3d8a9 --- /dev/null +++ b/tests/mir-opt/inline/inline_options.main.Inline.after.panic-abort.mir @@ -0,0 +1,55 @@ +// MIR for `main` after Inline + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_options.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/inline_options.rs:+1:5: +1:18 + let _2: (); // in scope 0 at $DIR/inline_options.rs:+2:5: +2:21 + scope 1 (inlined inlined::) { // at $DIR/inline_options.rs:11:5: 11:21 + let _3: (); // in scope 1 at $DIR/inline_options.rs:17:23: 17:26 + let _4: (); // in scope 1 at $DIR/inline_options.rs:17:28: 17:31 + let _5: (); // in scope 1 at $DIR/inline_options.rs:17:33: 17:36 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_options.rs:+1:5: +1:18 + _1 = not_inlined() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_options.rs:+1:5: +1:18 + // mir::Constant + // + span: $DIR/inline_options.rs:10:5: 10:16 + // + literal: Const { ty: fn() {not_inlined}, val: Value() } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline_options.rs:+1:18: +1:19 + StorageLive(_2); // scope 0 at $DIR/inline_options.rs:+2:5: +2:21 + StorageLive(_3); // scope 0 at $DIR/inline_options.rs:+2:5: +2:21 + StorageLive(_4); // scope 0 at $DIR/inline_options.rs:+2:5: +2:21 + StorageLive(_5); // scope 0 at $DIR/inline_options.rs:+2:5: +2:21 + _3 = g() -> [return: bb3, unwind unreachable]; // scope 1 at $DIR/inline_options.rs:17:23: 17:26 + // mir::Constant + // + span: $DIR/inline_options.rs:17:23: 17:24 + // + literal: Const { ty: fn() {g}, val: Value() } + } + + bb2: { + StorageDead(_5); // scope 0 at $DIR/inline_options.rs:+2:5: +2:21 + StorageDead(_4); // scope 0 at $DIR/inline_options.rs:+2:5: +2:21 + StorageDead(_3); // scope 0 at $DIR/inline_options.rs:+2:5: +2:21 + StorageDead(_2); // scope 0 at $DIR/inline_options.rs:+2:21: +2:22 + _0 = const (); // scope 0 at $DIR/inline_options.rs:+0:11: +3:2 + return; // scope 0 at $DIR/inline_options.rs:+3:2: +3:2 + } + + bb3: { + _4 = g() -> [return: bb4, unwind unreachable]; // scope 1 at $DIR/inline_options.rs:17:28: 17:31 + // mir::Constant + // + span: $DIR/inline_options.rs:17:28: 17:29 + // + literal: Const { ty: fn() {g}, val: Value() } + } + + bb4: { + _5 = g() -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/inline_options.rs:17:33: 17:36 + // mir::Constant + // + span: $DIR/inline_options.rs:17:33: 17:34 + // + literal: Const { ty: fn() {g}, val: Value() } + } +} diff --git a/tests/mir-opt/inline/inline_options.main.Inline.after.mir b/tests/mir-opt/inline/inline_options.main.Inline.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/inline/inline_options.main.Inline.after.mir rename to tests/mir-opt/inline/inline_options.main.Inline.after.panic-unwind.mir diff --git a/tests/mir-opt/inline/inline_options.rs b/tests/mir-opt/inline/inline_options.rs index f0a898832392b..b247ecd0bc0a1 100644 --- a/tests/mir-opt/inline/inline_options.rs +++ b/tests/mir-opt/inline/inline_options.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Checks that inlining threshold can be controlled with // inline-mir-threshold and inline-hint-threshold options. // diff --git a/tests/mir-opt/inline/inline_shims.clone.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.clone.Inline.panic-abort.diff new file mode 100644 index 0000000000000..d8521bb1d6280 --- /dev/null +++ b/tests/mir-opt/inline/inline_shims.clone.Inline.panic-abort.diff @@ -0,0 +1,26 @@ +- // MIR for `clone` before Inline ++ // MIR for `clone` after Inline + + fn clone(_1: fn(A, B)) -> fn(A, B) { + debug f => _1; // in scope 0 at $DIR/inline_shims.rs:+0:20: +0:21 + let mut _0: fn(A, B); // return place in scope 0 at $DIR/inline_shims.rs:+0:36: +0:44 + let mut _2: &fn(A, B); // in scope 0 at $DIR/inline_shims.rs:+1:5: +1:14 ++ scope 1 (inlined ::clone - shim(fn(A, B))) { // at $DIR/inline_shims.rs:6:7: 6:14 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline_shims.rs:+1:5: +1:14 + _2 = &_1; // scope 0 at $DIR/inline_shims.rs:+1:5: +1:14 +- _0 = ::clone(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_shims.rs:+1:5: +1:14 +- // mir::Constant +- // + span: $DIR/inline_shims.rs:6:7: 6:12 +- // + literal: Const { ty: for<'a> fn(&'a fn(A, B)) -> fn(A, B) {::clone}, val: Value() } +- } +- +- bb1: { ++ _0 = (*_2); // scope 1 at $SRC_DIR/core/src/clone.rs:LL:COL + StorageDead(_2); // scope 0 at $DIR/inline_shims.rs:+1:13: +1:14 + return; // scope 0 at $DIR/inline_shims.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_shims.clone.Inline.diff b/tests/mir-opt/inline/inline_shims.clone.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_shims.clone.Inline.diff rename to tests/mir-opt/inline/inline_shims.clone.Inline.panic-unwind.diff 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 new file mode 100644 index 0000000000000..49b36f0d91b6e --- /dev/null +++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff @@ -0,0 +1,72 @@ +- // MIR for `drop` before Inline ++ // MIR for `drop` after Inline + + fn drop(_1: *mut Vec, _2: *mut Option) -> () { + debug a => _1; // in scope 0 at $DIR/inline_shims.rs:+0:19: +0:20 + debug b => _2; // in scope 0 at $DIR/inline_shims.rs:+0:35: +0:36 + let mut _0: (); // return place in scope 0 at $DIR/inline_shims.rs:+0:54: +0:54 + let _3: (); // in scope 0 at $DIR/inline_shims.rs:+1:14: +1:40 + let mut _4: *mut std::vec::Vec; // in scope 0 at $DIR/inline_shims.rs:+1:38: +1:39 + let mut _5: *mut std::option::Option; // in scope 0 at $DIR/inline_shims.rs:+2:38: +2:39 + scope 1 { ++ scope 3 (inlined std::ptr::drop_in_place::> - shim(Some(Vec))) { // at $DIR/inline_shims.rs:11:14: 11:40 ++ let mut _6: &mut std::vec::Vec; // in scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ let mut _7: (); // in scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ } + } + scope 2 { ++ scope 4 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { // at $DIR/inline_shims.rs:12:14: 12:40 ++ let mut _8: isize; // in scope 4 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ let mut _9: isize; // in scope 4 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/inline_shims.rs:+1:5: +1:42 + StorageLive(_4); // scope 1 at $DIR/inline_shims.rs:+1:38: +1:39 + _4 = _1; // scope 1 at $DIR/inline_shims.rs:+1:38: +1:39 +- _3 = std::ptr::drop_in_place::>(move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/inline_shims.rs:+1:14: +1:40 ++ StorageLive(_6); // scope 1 at $DIR/inline_shims.rs:+1:14: +1:40 ++ StorageLive(_7); // scope 1 at $DIR/inline_shims.rs:+1:14: +1:40 ++ _6 = &mut (*_4); // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ _7 = as Drop>::drop(move _6) -> [return: bb2, unwind unreachable]; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + // mir::Constant +- // + span: $DIR/inline_shims.rs:11:14: 11:37 +- // + literal: Const { ty: unsafe fn(*mut Vec) {std::ptr::drop_in_place::>}, val: Value() } ++ // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ // + literal: Const { ty: for<'a> fn(&'a mut Vec) { as Drop>::drop}, val: Value() } + } + + bb1: { ++ StorageDead(_7); // scope 1 at $DIR/inline_shims.rs:+1:14: +1:40 ++ StorageDead(_6); // scope 1 at $DIR/inline_shims.rs:+1:14: +1:40 + StorageDead(_4); // scope 1 at $DIR/inline_shims.rs:+1:39: +1:40 + StorageDead(_3); // scope 0 at $DIR/inline_shims.rs:+1:41: +1:42 + StorageLive(_5); // scope 2 at $DIR/inline_shims.rs:+2:38: +2:39 + _5 = _2; // scope 2 at $DIR/inline_shims.rs:+2:38: +2:39 +- _0 = std::ptr::drop_in_place::>(move _5) -> [return: bb2, unwind unreachable]; // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 +- // mir::Constant +- // + span: $DIR/inline_shims.rs:12:14: 12:37 +- // + literal: Const { ty: unsafe fn(*mut Option) {std::ptr::drop_in_place::>}, val: Value() } ++ StorageLive(_8); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 ++ StorageLive(_9); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 ++ _8 = discriminant((*_5)); // scope 4 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ switchInt(move _8) -> [0: bb3, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + } + + bb2: { ++ drop(((*_4).0: alloc::raw_vec::RawVec)) -> [return: bb1, unwind unreachable]; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageDead(_9); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 ++ StorageDead(_8); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 + StorageDead(_5); // scope 2 at $DIR/inline_shims.rs:+2:39: +2:40 + return; // scope 0 at $DIR/inline_shims.rs:+3:2: +3:2 ++ } ++ ++ bb4: { ++ drop((((*_5) as Some).0: B)) -> [return: bb3, unwind unreachable]; // scope 4 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + } + } + diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_shims.drop.Inline.diff rename to tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_shims.rs b/tests/mir-opt/inline/inline_shims.rs index 7c8618f71e5f5..eafbb962efb73 100644 --- a/tests/mir-opt/inline/inline_shims.rs +++ b/tests/mir-opt/inline/inline_shims.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] // EMIT_MIR inline_shims.clone.Inline.diff diff --git a/tests/mir-opt/inline/inline_specialization.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_specialization.main.Inline.panic-abort.diff new file mode 100644 index 0000000000000..451c90b160550 --- /dev/null +++ b/tests/mir-opt/inline/inline_specialization.main.Inline.panic-abort.diff @@ -0,0 +1,28 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline_specialization.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/inline_specialization.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/inline_specialization.rs:+1:9: +1:10 + } ++ scope 2 (inlined as Foo>::bar) { // at $DIR/inline_specialization.rs:6:13: 6:38 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline_specialization.rs:+1:9: +1:10 +- _1 = as Foo>::bar() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_specialization.rs:+1:13: +1:38 +- // mir::Constant +- // + span: $DIR/inline_specialization.rs:6:13: 6:36 +- // + literal: Const { ty: fn() -> u32 { as Foo>::bar}, val: Value() } +- } +- +- bb1: { ++ _1 = const 123_u32; // scope 2 at $DIR/inline_specialization.rs:15:31: 15:34 + _0 = const (); // scope 0 at $DIR/inline_specialization.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_specialization.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline_specialization.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/inline_specialization.main.Inline.diff b/tests/mir-opt/inline/inline_specialization.main.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_specialization.main.Inline.diff rename to tests/mir-opt/inline/inline_specialization.main.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_specialization.rs b/tests/mir-opt/inline/inline_specialization.rs index c24795e05c6dc..0311531dc3fa2 100644 --- a/tests/mir-opt/inline/inline_specialization.rs +++ b/tests/mir-opt/inline/inline_specialization.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![feature(specialization)] // EMIT_MIR inline_specialization.main.Inline.diff diff --git a/tests/mir-opt/inline/inline_trait_method.rs b/tests/mir-opt/inline/inline_trait_method.rs index 6aa957eb5349f..a9d2168c2ec15 100644 --- a/tests/mir-opt/inline/inline_trait_method.rs +++ b/tests/mir-opt/inline/inline_trait_method.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Z span_free_formats fn main() { diff --git a/tests/mir-opt/inline/inline_trait_method.test.Inline.after.panic-abort.mir b/tests/mir-opt/inline/inline_trait_method.test.Inline.after.panic-abort.mir new file mode 100644 index 0000000000000..a6496bf5f0de6 --- /dev/null +++ b/tests/mir-opt/inline/inline_trait_method.test.Inline.after.panic-abort.mir @@ -0,0 +1,21 @@ +// MIR for `test` after Inline + +fn test(_1: &dyn X) -> u32 { + debug x => _1; // in scope 0 at $DIR/inline_trait_method.rs:+0:9: +0:10 + let mut _0: u32; // return place in scope 0 at $DIR/inline_trait_method.rs:+0:23: +0:26 + let mut _2: &dyn X; // in scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10 + _2 = &(*_1); // scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10 + _0 = ::y(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10 + // mir::Constant + // + span: $DIR/inline_trait_method.rs:10:7: 10:8 + // + literal: Const { ty: for<'a> fn(&'a dyn X) -> u32 {::y}, val: Value() } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/inline_trait_method.rs:+1:9: +1:10 + return; // scope 0 at $DIR/inline_trait_method.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/inline/inline_trait_method.test.Inline.after.mir b/tests/mir-opt/inline/inline_trait_method.test.Inline.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/inline/inline_trait_method.test.Inline.after.mir rename to tests/mir-opt/inline/inline_trait_method.test.Inline.after.panic-unwind.mir diff --git a/tests/mir-opt/inline/inline_trait_method_2.rs b/tests/mir-opt/inline/inline_trait_method_2.rs index 07a6019080188..62ec7ebde6a99 100644 --- a/tests/mir-opt/inline/inline_trait_method_2.rs +++ b/tests/mir-opt/inline/inline_trait_method_2.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Z span_free_formats -Z mir-opt-level=4 // EMIT_MIR inline_trait_method_2.test2.Inline.after.mir diff --git a/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-abort.mir b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-abort.mir new file mode 100644 index 0000000000000..8e37c7dca6c01 --- /dev/null +++ b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-abort.mir @@ -0,0 +1,28 @@ +// MIR for `test2` after Inline + +fn test2(_1: &dyn X) -> bool { + debug x => _1; // in scope 0 at $DIR/inline_trait_method_2.rs:+0:10: +0:11 + let mut _0: bool; // return place in scope 0 at $DIR/inline_trait_method_2.rs:+0:24: +0:28 + let mut _2: &dyn X; // in scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + let mut _3: &dyn X; // in scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + scope 1 (inlined test) { // at $DIR/inline_trait_method_2.rs:6:5: 6:12 + debug x => _2; // in scope 1 at $DIR/inline_trait_method_2.rs:10:9: 10:10 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + StorageLive(_3); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + _3 = &(*_1); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + _2 = move _3 as &dyn X (Pointer(Unsize)); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + StorageDead(_3); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + _0 = ::y(_2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/inline_trait_method_2.rs:11:5: 11:10 + // mir::Constant + // + span: $DIR/inline_trait_method_2.rs:11:7: 11:8 + // + literal: Const { ty: for<'a> fn(&'a dyn X) -> bool {::y}, val: Value() } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/inline_trait_method_2.rs:+1:11: +1:12 + return; // scope 0 at $DIR/inline_trait_method_2.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir rename to tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff new file mode 100644 index 0000000000000..4f8c7123aaf82 --- /dev/null +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff @@ -0,0 +1,55 @@ +- // MIR for `outer` before Inline ++ // MIR for `outer` after Inline + + fn outer() -> usize { + let mut _0: usize; // return place in scope 0 at $DIR/issue_106141.rs:+0:19: +0:24 ++ scope 1 (inlined inner) { // at $DIR/issue_106141.rs:3:5: 3:12 ++ let mut _1: &[bool; 1]; // in scope 1 at $DIR/issue_106141.rs:12:18: 12:25 ++ let mut _2: bool; // in scope 1 at $DIR/issue_106141.rs:14:8: 14:21 ++ let mut _3: bool; // in scope 1 at $DIR/issue_106141.rs:14:8: 14:21 ++ scope 2 { ++ debug buffer => const _; // in scope 2 at $DIR/issue_106141.rs:12:9: 12:15 ++ scope 3 { ++ debug index => _0; // in scope 3 at $DIR/issue_106141.rs:13:9: 13:14 ++ } ++ } ++ } + + bb0: { +- _0 = inner() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/issue_106141.rs:+1:5: +1:12 ++ StorageLive(_1); // scope 0 at $DIR/issue_106141.rs:+1:5: +1:12 ++ _1 = const _; // scope 1 at $DIR/issue_106141.rs:12:18: 12:25 + // mir::Constant +- // + span: $DIR/issue_106141.rs:3:5: 3:10 +- // + literal: Const { ty: fn() -> usize {inner}, val: Value() } ++ // + span: $DIR/issue_106141.rs:12:18: 12:25 ++ // + literal: Const { ty: &[bool; 1], val: Unevaluated(inner, [], Some(promoted[0])) } ++ _0 = index() -> [return: bb1, unwind unreachable]; // scope 2 at $DIR/issue_106141.rs:13:17: 13:24 ++ // mir::Constant ++ // + span: $DIR/issue_106141.rs:13:17: 13:22 ++ // + literal: Const { ty: fn() -> usize {index}, val: Value() } + } + + bb1: { ++ StorageLive(_3); // scope 3 at $DIR/issue_106141.rs:14:8: 14:21 ++ _2 = Lt(_0, const 1_usize); // scope 3 at $DIR/issue_106141.rs:14:8: 14:21 ++ assert(move _2, "index out of bounds: the length is {} but the index is {}", const 1_usize, _0) -> [success: bb2, unwind unreachable]; // scope 3 at $DIR/issue_106141.rs:14:8: 14:21 ++ } ++ ++ bb2: { ++ _3 = (*_1)[_0]; // scope 3 at $DIR/issue_106141.rs:14:8: 14:21 ++ switchInt(move _3) -> [0: bb3, otherwise: bb4]; // scope 3 at $DIR/issue_106141.rs:14:8: 14:21 ++ } ++ ++ bb3: { ++ _0 = const 0_usize; // scope 3 at $DIR/issue_106141.rs:17:9: 17:10 ++ goto -> bb4; // scope 3 at $DIR/issue_106141.rs:14:5: 18:6 ++ } ++ ++ bb4: { ++ StorageDead(_3); // scope 3 at $DIR/issue_106141.rs:18:5: 18:6 ++ StorageDead(_1); // scope 0 at $DIR/issue_106141.rs:+1:5: +1:12 + return; // scope 0 at $DIR/issue_106141.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/issue_106141.outer.Inline.diff rename to tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/issue_106141.rs b/tests/mir-opt/inline/issue_106141.rs index b6bd806e6fce5..eed1d89172ce0 100644 --- a/tests/mir-opt/inline/issue_106141.rs +++ b/tests/mir-opt/inline/issue_106141.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY pub fn outer() -> usize { inner() } diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff new file mode 100644 index 0000000000000..4d9215ee7e4a3 --- /dev/null +++ b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff @@ -0,0 +1,53 @@ +- // MIR for `bar` before Inline ++ // MIR for `bar` after Inline + + fn bar(_1: P) -> () { + debug _baz => _1; // in scope 0 at $DIR/issue_78442.rs:+2:5: +2:9 + let mut _0: (); // return place in scope 0 at $DIR/issue_78442.rs:+3:3: +3:3 + let _2: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + let _4: fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + let mut _5: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 ++ scope 1 (inlined >::call - shim(fn() {foo})) { // at $DIR/issue_78442.rs:11:5: 11:17 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + StorageLive(_3); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + StorageLive(_4); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + _4 = hide_foo() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + // mir::Constant + // + span: $DIR/issue_78442.rs:11:5: 11:13 + // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value() } + } + + bb1: { + _3 = &_4; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + StorageLive(_5); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + _5 = (); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 +- // mir::Constant +- // + span: $DIR/issue_78442.rs:11:5: 11:15 +- // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() {foo}, ()) -> >::Output {>::call}, val: Value() } ++ _2 = move (*_3)() -> [return: bb3, unwind unreachable]; // scope 1 at $SRC_DIR/core/src/ops/function.rs:LL:COL + } + + bb2: { ++ return; // scope 0 at $DIR/issue_78442.rs:+5:2: +5:2 ++ } ++ ++ bb3: { + StorageDead(_5); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17 + StorageDead(_3); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17 + StorageDead(_4); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18 + StorageDead(_2); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18 + _0 = const (); // scope 0 at $DIR/issue_78442.rs:+3:3: +5:2 +- drop(_1) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2 +- } +- +- bb3: { +- return; // scope 0 at $DIR/issue_78442.rs:+5:2: +5:2 ++ drop(_1) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2 + } + } + diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/issue_78442.bar.Inline.diff rename to tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff new file mode 100644 index 0000000000000..dcdb1069605d8 --- /dev/null +++ b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff @@ -0,0 +1,49 @@ +- // MIR for `bar` before RevealAll ++ // MIR for `bar` after RevealAll + + fn bar(_1: P) -> () { + debug _baz => _1; // in scope 0 at $DIR/issue_78442.rs:+2:5: +2:9 + let mut _0: (); // return place in scope 0 at $DIR/issue_78442.rs:+3:3: +3:3 + let _2: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 +- let mut _3: &impl Fn(); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 +- let _4: impl Fn(); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 ++ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 ++ let _4: fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + let mut _5: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + StorageLive(_3); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + StorageLive(_4); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + _4 = hide_foo() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + // mir::Constant + // + span: $DIR/issue_78442.rs:11:5: 11:13 + // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value() } + } + + bb1: { + _3 = &_4; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + StorageLive(_5); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + _5 = (); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 ++ _2 = >::call(move _3, move _5) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + // mir::Constant + // + span: $DIR/issue_78442.rs:11:5: 11:15 +- // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(), ()) -> >::Output {>::call}, val: Value() } ++ // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() {foo}, ()) -> >::Output {>::call}, val: Value() } + } + + bb2: { + StorageDead(_5); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17 + StorageDead(_3); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17 + StorageDead(_4); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18 + StorageDead(_2); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18 + _0 = const (); // scope 0 at $DIR/issue_78442.rs:+3:3: +5:2 + drop(_1) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2 + } + + bb3: { + return; // scope 0 at $DIR/issue_78442.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/issue_78442.bar.RevealAll.diff rename to tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff diff --git a/tests/mir-opt/inline/issue_78442.rs b/tests/mir-opt/inline/issue_78442.rs index aa8ede2df9e9c..d956e62414ccf 100644 --- a/tests/mir-opt/inline/issue_78442.rs +++ b/tests/mir-opt/inline/issue_78442.rs @@ -1,5 +1,5 @@ // compile-flags: -Z mir-opt-level=3 -Z inline-mir -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] // EMIT_MIR issue_78442.bar.RevealAll.diff diff --git a/tests/mir-opt/inline/unchecked_shifts.rs b/tests/mir-opt/inline/unchecked_shifts.rs index 17724530d6575..64ec26b587d28 100644 --- a/tests/mir-opt/inline/unchecked_shifts.rs +++ b/tests/mir-opt/inline/unchecked_shifts.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] #![feature(unchecked_math)] diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff new file mode 100644 index 0000000000000..fa82ff4b122cc --- /dev/null +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff @@ -0,0 +1,144 @@ +- // MIR for `unchecked_shl_unsigned_smaller` before Inline ++ // MIR for `unchecked_shl_unsigned_smaller` after Inline + + fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { + debug a => _1; // in scope 0 at $DIR/unchecked_shifts.rs:+0:46: +0:47 + debug b => _2; // in scope 0 at $DIR/unchecked_shifts.rs:+0:54: +0:55 + let mut _0: u16; // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:65: +0:68 + let mut _3: u16; // in scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + let mut _4: u32; // in scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 ++ scope 1 (inlined core::num::::unchecked_shl) { // at $DIR/unchecked_shifts.rs:11:7: 11:23 ++ debug self => _3; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ let mut _5: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ scope 2 { ++ scope 3 (inlined core::num::::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug x => _4; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _6: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _7: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ scope 4 { ++ scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _4; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ scope 6 (inlined convert::num:: for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug u => _4; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _10: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ } ++ scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _12: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 8 { ++ debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ } ++ scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _13: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 10 { ++ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 11 { ++ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 14 { ++ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } ++ } ++ } ++ scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ } ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + _3 = _1; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + StorageLive(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 + _4 = _2; // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 +- _0 = core::num::::unchecked_shl(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:23 +- // mir::Constant +- // + span: $DIR/unchecked_shifts.rs:11:7: 11:20 +- // + literal: Const { ty: unsafe fn(u16, u32) -> u16 {core::num::::unchecked_shl}, val: Value() } ++ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _9 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _8 = Gt(_4, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb1: { ++ StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 ++ } ++ ++ bb2: { ++ _7 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: TryFromIntError, val: Value() } ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _10 = _4 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _7 = Result::::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb4: { ++ StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb5: { ++ _6 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb6: { ++ unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb7: { ++ _12 = move ((_7 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _6 = Option::::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb8: { ++ StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ ++ bb9: { ++ _5 = move ((_6 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _0 = unchecked_shl::(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ // mir::Constant ++ // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::}, val: Value() } + } + } + diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff rename to tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir similarity index 100% rename from tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir rename to tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir new file mode 100644 index 0000000000000..8fa4fdaa49aed --- /dev/null +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,130 @@ +// MIR for `unchecked_shl_unsigned_smaller` after PreCodegen + +fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { + debug a => _1; // in scope 0 at $DIR/unchecked_shifts.rs:+0:46: +0:47 + debug b => _2; // in scope 0 at $DIR/unchecked_shifts.rs:+0:54: +0:55 + let mut _0: u16; // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:65: +0:68 + scope 1 (inlined core::num::::unchecked_shl) { // at $DIR/unchecked_shifts.rs:11:7: 11:23 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + let mut _11: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 2 { + scope 3 (inlined core::num::::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug x => _2; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _9: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 4 { + scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _2; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + scope 6 (inlined convert::num:: for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug u => _2; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _3: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _4: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _5: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + } + scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _6; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _7: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let _8: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + scope 8 { + debug x => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _9; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _10: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _12: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + scope 10 { + debug val => _11; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 11 { + scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 14 { + scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + } + scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _12; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + } + } + } + } + + bb0: { + StorageLive(_11); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_4); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _3 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _4 = Gt(_2, move _3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + switchInt(move _4) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb1: { + StorageLive(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _5 = _2 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _6 = Result::::Ok(move _5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb3; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb2: { + _6 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value() } + goto -> bb3; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb3: { + StorageDead(_4); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _7 = discriminant(_6); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb4: { + _8 = move ((_6 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _9 = Option::::Some(move _8); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb6; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { + _9 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb6; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb6: { + StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _10 = discriminant(_9); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _10) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb7: { + _11 = move ((_9 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _0 = unchecked_shl::(_1, move _11) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::}, val: Value() } + } + + bb8: { + StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 + } + + bb9: { + unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } +} diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-abort.diff new file mode 100644 index 0000000000000..0e37e40fbb6a4 --- /dev/null +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-abort.diff @@ -0,0 +1,144 @@ +- // MIR for `unchecked_shr_signed_smaller` before Inline ++ // MIR for `unchecked_shr_signed_smaller` after Inline + + fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { + debug a => _1; // in scope 0 at $DIR/unchecked_shifts.rs:+0:44: +0:45 + debug b => _2; // in scope 0 at $DIR/unchecked_shifts.rs:+0:52: +0:53 + let mut _0: i16; // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:63: +0:66 + let mut _3: i16; // in scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + let mut _4: u32; // in scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 ++ scope 1 (inlined core::num::::unchecked_shr) { // at $DIR/unchecked_shifts.rs:17:7: 17:23 ++ debug self => _3; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ let mut _5: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ scope 2 { ++ scope 3 (inlined core::num::::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug x => _4; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _6: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _7: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ scope 4 { ++ scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _4; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ scope 6 (inlined convert::num:: for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug u => _4; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _10: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ } ++ scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _12: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 8 { ++ debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ } ++ scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _13: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 10 { ++ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 11 { ++ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 14 { ++ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } ++ } ++ } ++ scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ } ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + _3 = _1; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + StorageLive(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 + _4 = _2; // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 +- _0 = core::num::::unchecked_shr(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:23 +- // mir::Constant +- // + span: $DIR/unchecked_shifts.rs:17:7: 17:20 +- // + literal: Const { ty: unsafe fn(i16, u32) -> i16 {core::num::::unchecked_shr}, val: Value() } ++ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _9 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _8 = Gt(_4, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb1: { ++ StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 ++ } ++ ++ bb2: { ++ _7 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: TryFromIntError, val: Value() } ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _10 = _4 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _7 = Result::::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb4: { ++ StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb5: { ++ _6 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb6: { ++ unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb7: { ++ _12 = move ((_7 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _6 = Option::::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb8: { ++ StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ ++ bb9: { ++ _5 = move ((_6 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _0 = unchecked_shr::(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ // mir::Constant ++ // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::}, val: Value() } + } + } + diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff rename to tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-abort.mir similarity index 100% rename from tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir rename to tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-abort.mir diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-unwind.mir new file mode 100644 index 0000000000000..7f737abb9360d --- /dev/null +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,130 @@ +// MIR for `unchecked_shr_signed_smaller` after PreCodegen + +fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { + debug a => _1; // in scope 0 at $DIR/unchecked_shifts.rs:+0:44: +0:45 + debug b => _2; // in scope 0 at $DIR/unchecked_shifts.rs:+0:52: +0:53 + let mut _0: i16; // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:63: +0:66 + scope 1 (inlined core::num::::unchecked_shr) { // at $DIR/unchecked_shifts.rs:17:7: 17:23 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + let mut _11: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 2 { + scope 3 (inlined core::num::::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug x => _2; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _9: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 4 { + scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _2; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + scope 6 (inlined convert::num:: for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug u => _2; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _3: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _4: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _5: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + } + scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _6; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _7: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let _8: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + scope 8 { + debug x => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _9; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _10: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _12: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + scope 10 { + debug val => _11; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 11 { + scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 14 { + scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + } + scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _12; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + } + } + } + } + + bb0: { + StorageLive(_11); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_4); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _3 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _4 = Gt(_2, move _3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + switchInt(move _4) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb1: { + StorageLive(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _5 = _2 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _6 = Result::::Ok(move _5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb3; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb2: { + _6 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value() } + goto -> bb3; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb3: { + StorageDead(_4); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _7 = discriminant(_6); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb4: { + _8 = move ((_6 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _9 = Option::::Some(move _8); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb6; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { + _9 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb6; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb6: { + StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _10 = discriminant(_9); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _10) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb7: { + _11 = move ((_9 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _0 = unchecked_shr::(_1, move _11) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::}, val: Value() } + } + + bb8: { + StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 + } + + bb9: { + unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } +} diff --git a/tests/mir-opt/inline/unwrap_unchecked.rs b/tests/mir-opt/inline/unwrap_unchecked.rs index 5856f1479414c..f28aef7a808a8 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.rs +++ b/tests/mir-opt/inline/unwrap_unchecked.rs @@ -1,6 +1,6 @@ #![crate_type = "lib"] -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // ignore-debug: the debug assertions prevent the inlining we are testing for // compile-flags: -Zmir-opt-level=2 -Zinline-mir diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff new file mode 100644 index 0000000000000..4f2a32fa6416e --- /dev/null +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff @@ -0,0 +1,51 @@ +- // MIR for `unwrap_unchecked` before Inline ++ // MIR for `unwrap_unchecked` after Inline + + fn unwrap_unchecked(_1: Option) -> T { + debug slf => _1; // in scope 0 at $DIR/unwrap_unchecked.rs:+0:35: +0:38 + let mut _0: T; // return place in scope 0 at $DIR/unwrap_unchecked.rs:+0:54: +0:55 + let mut _2: std::option::Option; // in scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8 ++ scope 1 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $DIR/unwrap_unchecked.rs:10:9: 10:27 ++ debug self => _2; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _3: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _4: isize; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 2 { ++ debug val => _0; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 3 { ++ scope 5 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 6 { ++ scope 7 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } ++ } ++ } ++ scope 4 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _3; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8 +- _0 = Option::::unwrap_unchecked(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:27 +- // mir::Constant +- // + span: $DIR/unwrap_unchecked.rs:10:9: 10:25 +- // + literal: Const { ty: unsafe fn(Option) -> T {Option::::unwrap_unchecked}, val: Value() } ++ StorageLive(_3); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 ++ _4 = discriminant(_2); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _4) -> [1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb1: { ++ unreachable; // scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ ++ bb2: { ++ _0 = move ((_2 as Some).0: T); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_3); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 + StorageDead(_2); // scope 0 at $DIR/unwrap_unchecked.rs:+1:26: +1:27 + return; // scope 0 at $DIR/unwrap_unchecked.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff rename to tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir similarity index 100% rename from tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir rename to tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir new file mode 100644 index 0000000000000..601d83702f435 --- /dev/null +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,41 @@ +// MIR for `unwrap_unchecked` after PreCodegen + +fn unwrap_unchecked(_1: Option) -> T { + debug slf => _1; // in scope 0 at $DIR/unwrap_unchecked.rs:+0:35: +0:38 + let mut _0: T; // return place in scope 0 at $DIR/unwrap_unchecked.rs:+0:54: +0:55 + scope 1 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $DIR/unwrap_unchecked.rs:10:9: 10:27 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _2: isize; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _3: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + scope 2 { + debug val => _0; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 3 { + scope 5 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 6 { + scope 7 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + } + scope 4 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _3; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 + _2 = discriminant(_1); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _2) -> [1: bb1, otherwise: bb2]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb1: { + _0 = move ((_1 as Some).0: T); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_3); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 + return; // scope 0 at $DIR/unwrap_unchecked.rs:+2:2: +2:2 + } + + bb2: { + unreachable; // scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } +} diff --git a/tests/mir-opt/issue_101973.inner.ConstProp.panic-abort.diff b/tests/mir-opt/issue_101973.inner.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..eb47f0d31833b --- /dev/null +++ b/tests/mir-opt/issue_101973.inner.ConstProp.panic-abort.diff @@ -0,0 +1,85 @@ +- // MIR for `inner` before ConstProp ++ // MIR for `inner` after ConstProp + + fn inner(_1: u32) -> i64 { + debug fields => _1; // in scope 0 at $DIR/issue_101973.rs:+0:14: +0:20 + let mut _0: i64; // return place in scope 0 at $DIR/issue_101973.rs:+0:30: +0:33 + let mut _2: i32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 + let mut _3: u32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:58 + let mut _4: u32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:17 + let mut _5: u32; // in scope 0 at $DIR/issue_101973.rs:+1:10: +1:16 + let mut _6: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + let mut _7: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 + let mut _8: u32; // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + let mut _9: u32; // in scope 0 at $DIR/issue_101973.rs:+1:33: +1:39 + let mut _10: u32; // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + let mut _11: bool; // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + let mut _12: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + let mut _13: bool; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + scope 1 (inlined imm8) { // at $DIR/issue_101973.rs:15:5: 15:17 + debug x => _1; // in scope 1 at $DIR/issue_101973.rs:6:13: 6:14 + let mut _14: u32; // in scope 1 at $DIR/issue_101973.rs:8:12: 8:20 + let mut _15: u32; // in scope 1 at $DIR/issue_101973.rs:8:12: 8:27 + scope 2 { + debug out => _4; // in scope 2 at $DIR/issue_101973.rs:7:9: 7:16 + } + } + scope 3 (inlined core::num::::rotate_right) { // at $DIR/issue_101973.rs:15:18: 15:58 + debug self => _4; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + debug n => _6; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 + StorageLive(_3); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:58 + StorageLive(_4); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:17 + StorageLive(_15); // scope 2 at $DIR/issue_101973.rs:8:12: 8:27 + StorageLive(_14); // scope 2 at $DIR/issue_101973.rs:8:12: 8:20 + _14 = Shr(_1, const 0_i32); // scope 2 at $DIR/issue_101973.rs:8:12: 8:20 + _15 = BitAnd(move _14, const 255_u32); // scope 2 at $DIR/issue_101973.rs:8:12: 8:27 + StorageDead(_14); // scope 2 at $DIR/issue_101973.rs:8:26: 8:27 + _4 = BitOr(const 0_u32, move _15); // scope 2 at $DIR/issue_101973.rs:8:5: 8:27 + StorageDead(_15); // scope 2 at $DIR/issue_101973.rs:8:26: 8:27 + StorageLive(_6); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + StorageLive(_7); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 + StorageLive(_8); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 +- _10 = const 8_i32 as u32 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 +- _11 = Lt(move _10, const 32_u32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 +- assert(move _11, "attempt to shift right by `{}`, which would overflow", const 8_i32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 ++ _10 = const 8_u32; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 ++ _11 = const true; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 ++ assert(const true, "attempt to shift right by `{}`, which would overflow", const 8_i32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + } + + bb1: { + _8 = Shr(_1, const 8_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 + StorageDead(_8); // scope 0 at $DIR/issue_101973.rs:+1:51: +1:52 +- _12 = const 1_i32 as u32 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 +- _13 = Lt(move _12, const 32_u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 +- assert(move _13, "attempt to shift left by `{}`, which would overflow", const 1_i32) -> [success: bb2, unwind unreachable]; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 ++ _12 = const 1_u32; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 ++ _13 = const true; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 ++ assert(const true, "attempt to shift left by `{}`, which would overflow", const 1_i32) -> [success: bb2, unwind unreachable]; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + } + + bb2: { + _6 = Shl(move _7, const 1_i32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + StorageDead(_7); // scope 0 at $DIR/issue_101973.rs:+1:56: +1:57 + _3 = rotate_right::(_4, _6) -> [return: bb3, unwind unreachable]; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // + literal: Const { ty: extern "rust-intrinsic" fn(u32, u32) -> u32 {rotate_right::}, val: Value() } + } + + bb3: { + StorageDead(_6); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58 + StorageDead(_4); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58 + _2 = move _3 as i32 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 + StorageDead(_3); // scope 0 at $DIR/issue_101973.rs:+1:64: +1:65 + _0 = move _2 as i64 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:72 + StorageDead(_2); // scope 0 at $DIR/issue_101973.rs:+1:71: +1:72 + return; // scope 0 at $DIR/issue_101973.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/issue_101973.inner.ConstProp.diff b/tests/mir-opt/issue_101973.inner.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/issue_101973.inner.ConstProp.diff rename to tests/mir-opt/issue_101973.inner.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/issue_101973.rs b/tests/mir-opt/issue_101973.rs index da388f14918f7..01b342f4dc3a5 100644 --- a/tests/mir-opt/issue_101973.rs +++ b/tests/mir-opt/issue_101973.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -O -C debug-assertions=on // This needs inlining followed by ConstProp to reproduce, so we cannot use "unit-test". diff --git a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir new file mode 100644 index 0000000000000..a8e2bc7186d28 --- /dev/null +++ b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir @@ -0,0 +1,25 @@ +// MIR for `main` after AbortUnwindingCalls + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_104451_unwindable_intrinsics.rs:+0:11: +0:11 + let mut _1: !; // in scope 0 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:9: +2:62 + let mut _2: (); // in scope 0 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:45: +2:47 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:9: +2:62 + StorageLive(_2); // scope 1 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:45: +2:47 + _2 = (); // scope 1 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:45: +2:47 + _1 = const_eval_select::<(), fn() -> ! {ow_ct}, fn() -> ! {ow_ct}, !>(move _2, ow_ct, ow_ct) -> unwind unreachable; // scope 1 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:9: +2:62 + // mir::Constant + // + span: $DIR/issue_104451_unwindable_intrinsics.rs:8:9: 8:44 + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn((), fn() -> ! {ow_ct}, fn() -> ! {ow_ct}) -> ! {const_eval_select::<(), fn() -> ! {ow_ct}, fn() -> ! {ow_ct}, !>}, val: Value() } + // mir::Constant + // + span: $DIR/issue_104451_unwindable_intrinsics.rs:8:49: 8:54 + // + literal: Const { ty: fn() -> ! {ow_ct}, val: Value() } + // mir::Constant + // + span: $DIR/issue_104451_unwindable_intrinsics.rs:8:56: 8:61 + // + literal: Const { ty: fn() -> ! {ow_ct}, val: Value() } + } +} diff --git a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.mir b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.mir rename to tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir diff --git a/tests/mir-opt/issue_104451_unwindable_intrinsics.rs b/tests/mir-opt/issue_104451_unwindable_intrinsics.rs index 9babd4aaed512..54112627e4ef0 100644 --- a/tests/mir-opt/issue_104451_unwindable_intrinsics.rs +++ b/tests/mir-opt/issue_104451_unwindable_intrinsics.rs @@ -1,5 +1,5 @@ // Check that `UnwindAction::Unreachable` is not generated for unwindable intrinsics. -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![feature(core_intrinsics)] // EMIT_MIR issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.mir diff --git a/tests/mir-opt/issue_41110.main.ElaborateDrops.diff b/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-abort.diff similarity index 100% rename from tests/mir-opt/issue_41110.main.ElaborateDrops.diff rename to tests/mir-opt/issue_41110.main.ElaborateDrops.panic-abort.diff diff --git a/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-unwind.diff new file mode 100644 index 0000000000000..ac2520249285e --- /dev/null +++ b/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-unwind.diff @@ -0,0 +1,75 @@ +- // MIR for `main` before ElaborateDrops ++ // MIR for `main` after ElaborateDrops + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_41110.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + let mut _2: S; // in scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + let mut _3: S; // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 + let mut _4: S; // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 ++ let mut _5: bool; // in scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + scope 1 { + debug x => _1; // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10 + } + + bb0: { ++ _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 ++ _5 = const true; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + _2 = S; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + StorageLive(_3); // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 + StorageLive(_4); // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 + _4 = S; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 + _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 + // mir::Constant + // + span: $DIR/issue_41110.rs:8:23: 8:25 + // + literal: Const { ty: fn(S) -> S {S::id}, val: Value() } + } + + bb1: { + StorageDead(_4); // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27 ++ _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28 + _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28 + // mir::Constant + // + span: $DIR/issue_41110.rs:8:15: 8:20 + // + literal: Const { ty: fn(S, S) {S::other}, val: Value() } + } + + bb2: { + StorageDead(_3); // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 ++ _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + StorageDead(_2); // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue_41110.rs:+2:2: +2:2 + } + + bb3 (cleanup): { +- drop(_3) -> [return: bb5, unwind terminate]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 ++ goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + } + + bb4 (cleanup): { +- drop(_4) -> [return: bb5, unwind terminate]; // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27 ++ goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27 + } + + bb5 (cleanup): { +- drop(_2) -> [return: bb6, unwind terminate]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 ++ goto -> bb8; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + } + + bb6 (cleanup): { + resume; // scope 0 at $DIR/issue_41110.rs:+0:1: +2:2 ++ } ++ ++ bb7 (cleanup): { ++ drop(_2) -> [return: bb6, unwind terminate]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 ++ } ++ ++ bb8 (cleanup): { ++ switchInt(_5) -> [0: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + } + } + diff --git a/tests/mir-opt/issue_41110.rs b/tests/mir-opt/issue_41110.rs index e1067ce53e41d..d8665b23d265c 100644 --- a/tests/mir-opt/issue_41110.rs +++ b/tests/mir-opt/issue_41110.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // check that we don't emit multiple drop flags when they are not needed. diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-abort.diff b/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-abort.diff new file mode 100644 index 0000000000000..84bcab000afe9 --- /dev/null +++ b/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-abort.diff @@ -0,0 +1,105 @@ +- // MIR for `test` before ElaborateDrops ++ // MIR for `test` after ElaborateDrops + + fn test() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_41110.rs:+0:15: +0:15 + let _1: S; // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + let _3: (); // in scope 0 at $DIR/issue_41110.rs:+3:5: +3:12 + let mut _4: S; // in scope 0 at $DIR/issue_41110.rs:+3:10: +3:11 + let mut _5: S; // in scope 0 at $DIR/issue_41110.rs:+4:9: +4:10 ++ let mut _6: bool; // in scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + scope 1 { + debug u => _1; // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10 + let mut _2: S; // in scope 1 at $DIR/issue_41110.rs:+2:9: +2:14 + scope 2 { + debug v => _2; // in scope 2 at $DIR/issue_41110.rs:+2:9: +2:14 + } + } + + bb0: { ++ _6 = const false; // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 ++ _6 = const true; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + _1 = S; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/issue_41110.rs:+2:9: +2:14 + _2 = S; // scope 1 at $DIR/issue_41110.rs:+2:17: +2:18 + StorageLive(_3); // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12 + StorageLive(_4); // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11 + _4 = move _2; // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11 + _3 = std::mem::drop::(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12 + // mir::Constant + // + span: $DIR/issue_41110.rs:17:5: 17:9 + // + literal: Const { ty: fn(S) {std::mem::drop::}, val: Value() } + } + + bb1: { + StorageDead(_4); // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 + StorageDead(_3); // scope 2 at $DIR/issue_41110.rs:+3:12: +3:13 + StorageLive(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 ++ _6 = const false; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + _5 = move _1; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 +- drop(_2) -> [return: bb2, unwind: bb3]; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 ++ goto -> bb2; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 + } + + bb2: { + _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 +- drop(_5) -> [return: bb4, unwind: bb8]; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 ++ goto -> bb4; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + } + + bb3 (cleanup): { + _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 + drop(_5) -> [return: bb8, unwind terminate]; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + } + + bb4: { + StorageDead(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2 + drop(_2) -> [return: bb5, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 + } + + bb5: { + StorageDead(_2); // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 +- drop(_1) -> [return: bb6, unwind: bb10]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 ++ goto -> bb6; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + } + + bb6: { ++ _6 = const false; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + return; // scope 0 at $DIR/issue_41110.rs:+5:2: +5:2 + } + + bb7 (cleanup): { +- drop(_4) -> [return: bb8, unwind terminate]; // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 ++ goto -> bb8; // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 + } + + bb8 (cleanup): { +- drop(_2) -> [return: bb9, unwind terminate]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 ++ goto -> bb9; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 + } + + bb9 (cleanup): { +- drop(_1) -> [return: bb10, unwind terminate]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 ++ goto -> bb13; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + } + + bb10 (cleanup): { + resume; // scope 0 at $DIR/issue_41110.rs:+0:1: +5:2 ++ } ++ ++ bb11 (cleanup): { ++ unreachable; // scope 0 at $DIR/issue_41110.rs:+0:1: +5:2 ++ } ++ ++ bb12 (cleanup): { ++ drop(_1) -> [return: bb10, unwind terminate]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 ++ } ++ ++ bb13 (cleanup): { ++ switchInt(_6) -> [0: bb10, otherwise: bb12]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + } + } + diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.diff b/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff similarity index 100% rename from tests/mir-opt/issue_41110.test.ElaborateDrops.diff rename to tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff new file mode 100644 index 0000000000000..d4d19b97a925d --- /dev/null +++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff @@ -0,0 +1,151 @@ +- // MIR for `main` before ElaborateDrops ++ // MIR for `main` after ElaborateDrops + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_41888.rs:+0:11: +0:11 + let _1: E; // in scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + let mut _2: bool; // in scope 0 at $DIR/issue_41888.rs:+2:8: +2:14 + let mut _3: E; // in scope 0 at $DIR/issue_41888.rs:+3:13: +3:20 + let mut _4: K; // in scope 0 at $DIR/issue_41888.rs:+3:18: +3:19 + let mut _5: isize; // in scope 0 at $DIR/issue_41888.rs:+4:16: +4:24 ++ let mut _7: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ let mut _8: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ let mut _9: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ let mut _10: isize; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ let mut _11: isize; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + scope 1 { + debug e => _1; // in scope 1 at $DIR/issue_41888.rs:+1:9: +1:10 + scope 2 { + debug _k => _6; // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + let _6: K; // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + } + } + + bb0: { ++ _7 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 ++ _8 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 ++ _9 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + StorageLive(_2); // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 + _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 + // mir::Constant + // + span: $DIR/issue_41888.rs:8:8: 8:12 + // + literal: Const { ty: fn() -> bool {cond}, val: Value() } + } + + bb1: { + switchInt(move _2) -> [0: bb8, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 + } + + bb2: { + StorageLive(_3); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20 + StorageLive(_4); // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19 + _4 = K; // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19 + _3 = E::F(move _4); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20 + StorageDead(_4); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 +- drop(_1) -> [return: bb3, unwind: bb4]; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ goto -> bb3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + } + + bb3: { ++ _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 +- drop(_3) -> [return: bb5, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 ++ goto -> bb5; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 + } + + bb4 (cleanup): { + _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + drop(_3) -> [return: bb11, unwind terminate]; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 + } + + bb5: { + StorageDead(_3); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 + _5 = discriminant(_1); // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 + switchInt(move _5) -> [0: bb6, otherwise: bb7]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 + } + + bb6: { + StorageLive(_6); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 ++ _9 = const false; // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + _6 = move ((_1 as F).0: K); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + _0 = const (); // scope 2 at $DIR/issue_41888.rs:+4:29: +7:10 + StorageDead(_6); // scope 1 at $DIR/issue_41888.rs:+7:9: +7:10 + goto -> bb9; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 + } + + bb7: { + _0 = const (); // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10 + goto -> bb9; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 + } + + bb8: { + _0 = const (); // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6 + goto -> bb9; // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6 + } + + bb9: { + StorageDead(_2); // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6 +- drop(_1) -> [return: bb10, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ goto -> bb19; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + + bb10: { ++ _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ _8 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ _9 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + StorageDead(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + return; // scope 0 at $DIR/issue_41888.rs:+9:2: +9:2 + } + + bb11 (cleanup): { +- drop(_1) -> [return: bb12, unwind terminate]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + + bb12 (cleanup): { + resume; // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2 ++ } ++ ++ bb13 (cleanup): { ++ unreachable; // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2 ++ } ++ ++ bb14: { ++ _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ goto -> bb10; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb15 (cleanup): { ++ goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb16: { ++ drop(_1) -> [return: bb14, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb17 (cleanup): { ++ drop(_1) -> [return: bb12, unwind terminate]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb18: { ++ _10 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ switchInt(move _10) -> [0: bb14, otherwise: bb16]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb19: { ++ switchInt(_7) -> [0: bb14, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb20 (cleanup): { ++ _11 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ switchInt(move _11) -> [0: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb21 (cleanup): { ++ switchInt(_7) -> [0: bb12, otherwise: bb20]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + } + diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff similarity index 100% rename from tests/mir-opt/issue_41888.main.ElaborateDrops.diff rename to tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff diff --git a/tests/mir-opt/issue_41888.rs b/tests/mir-opt/issue_41888.rs index 0f10c0a1d09f1..9b16caf92fed4 100644 --- a/tests/mir-opt/issue_41888.rs +++ b/tests/mir-opt/issue_41888.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // check that we clear the "ADT master drop flag" even when there are // no fields to be dropped. diff --git a/tests/mir-opt/issue_62289.rs b/tests/mir-opt/issue_62289.rs index af1bfea3f30b4..fece6bb7cf528 100644 --- a/tests/mir-opt/issue_62289.rs +++ b/tests/mir-opt/issue_62289.rs @@ -1,6 +1,6 @@ // check that we don't forget to drop the Box if we early return before // initializing it -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![feature(rustc_attrs)] diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir new file mode 100644 index 0000000000000..b3566e475b574 --- /dev/null +++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir @@ -0,0 +1,122 @@ +// MIR for `test` before ElaborateDrops + +fn test() -> Option> { + let mut _0: std::option::Option>; // return place in scope 0 at $DIR/issue_62289.rs:+0:14: +0:30 + let mut _1: std::boxed::Box; // in scope 0 at $DIR/issue_62289.rs:+3:9: +3:24 + let mut _2: usize; // in scope 0 at $DIR/issue_62289.rs:+3:9: +3:24 + let mut _3: usize; // in scope 0 at $DIR/issue_62289.rs:+3:9: +3:24 + let mut _4: *mut u8; // in scope 0 at $DIR/issue_62289.rs:+3:9: +3:24 + let mut _5: std::boxed::Box; // in scope 0 at $DIR/issue_62289.rs:+3:9: +3:24 + let mut _6: std::ops::ControlFlow, u32>; // in scope 0 at $DIR/issue_62289.rs:+3:18: +3:23 + let mut _7: std::option::Option; // in scope 0 at $DIR/issue_62289.rs:+3:18: +3:22 + let mut _8: isize; // in scope 0 at $DIR/issue_62289.rs:+3:22: +3:23 + let _9: std::option::Option; // in scope 0 at $DIR/issue_62289.rs:+3:22: +3:23 + let mut _10: !; // in scope 0 at $DIR/issue_62289.rs:+3:22: +3:23 + let mut _11: std::option::Option; // in scope 0 at $DIR/issue_62289.rs:+3:22: +3:23 + let _12: u32; // in scope 0 at $DIR/issue_62289.rs:+3:18: +3:23 + scope 1 { + } + scope 2 { + debug residual => _9; // in scope 2 at $DIR/issue_62289.rs:+3:22: +3:23 + scope 3 { + } + } + scope 4 { + debug val => _12; // in scope 4 at $DIR/issue_62289.rs:+3:18: +3:23 + scope 5 { + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue_62289.rs:+3:9: +3:24 + _2 = SizeOf(u32); // scope 1 at $DIR/issue_62289.rs:+3:9: +3:24 + _3 = AlignOf(u32); // scope 1 at $DIR/issue_62289.rs:+3:9: +3:24 + _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind: bb13]; // scope 1 at $DIR/issue_62289.rs:+3:9: +3:24 + // mir::Constant + // + span: $DIR/issue_62289.rs:11:9: 11:24 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value() } + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/issue_62289.rs:+3:9: +3:24 + _5 = ShallowInitBox(move _4, u32); // scope 0 at $DIR/issue_62289.rs:+3:9: +3:24 + StorageLive(_6); // scope 0 at $DIR/issue_62289.rs:+3:18: +3:23 + StorageLive(_7); // scope 0 at $DIR/issue_62289.rs:+3:18: +3:22 + _7 = Option::::None; // scope 0 at $DIR/issue_62289.rs:+3:18: +3:22 + _6 = as Try>::branch(move _7) -> [return: bb2, unwind: bb12]; // scope 0 at $DIR/issue_62289.rs:+3:18: +3:23 + // mir::Constant + // + span: $DIR/issue_62289.rs:11:18: 11:23 + // + literal: Const { ty: fn(Option) -> ControlFlow< as Try>::Residual, as Try>::Output> { as Try>::branch}, val: Value() } + } + + bb2: { + StorageDead(_7); // scope 0 at $DIR/issue_62289.rs:+3:22: +3:23 + _8 = discriminant(_6); // scope 0 at $DIR/issue_62289.rs:+3:18: +3:23 + switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb4]; // scope 0 at $DIR/issue_62289.rs:+3:18: +3:23 + } + + bb3: { + StorageLive(_12); // scope 0 at $DIR/issue_62289.rs:+3:18: +3:23 + _12 = ((_6 as Continue).0: u32); // scope 0 at $DIR/issue_62289.rs:+3:18: +3:23 + (*_5) = _12; // scope 5 at $DIR/issue_62289.rs:+3:18: +3:23 + StorageDead(_12); // scope 0 at $DIR/issue_62289.rs:+3:22: +3:23 + _1 = move _5; // scope 0 at $DIR/issue_62289.rs:+3:9: +3:24 + drop(_5) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/issue_62289.rs:+3:23: +3:24 + } + + bb4: { + unreachable; // scope 0 at $DIR/issue_62289.rs:+3:18: +3:23 + } + + bb5: { + StorageLive(_9); // scope 0 at $DIR/issue_62289.rs:+3:22: +3:23 + _9 = ((_6 as Break).0: std::option::Option); // scope 0 at $DIR/issue_62289.rs:+3:22: +3:23 + StorageLive(_11); // scope 3 at $DIR/issue_62289.rs:+3:22: +3:23 + _11 = _9; // scope 3 at $DIR/issue_62289.rs:+3:22: +3:23 + _0 = > as FromResidual>>::from_residual(move _11) -> [return: bb6, unwind: bb12]; // scope 3 at $DIR/issue_62289.rs:+3:18: +3:23 + // mir::Constant + // + span: $DIR/issue_62289.rs:11:22: 11:23 + // + literal: Const { ty: fn(Option) -> Option> {> as FromResidual>>::from_residual}, val: Value() } + } + + bb6: { + StorageDead(_11); // scope 3 at $DIR/issue_62289.rs:+3:22: +3:23 + StorageDead(_9); // scope 0 at $DIR/issue_62289.rs:+3:22: +3:23 + drop(_5) -> [return: bb9, unwind: bb13]; // scope 0 at $DIR/issue_62289.rs:+3:23: +3:24 + } + + bb7: { + StorageDead(_5); // scope 0 at $DIR/issue_62289.rs:+3:23: +3:24 + _0 = Option::>::Some(move _1); // scope 0 at $DIR/issue_62289.rs:+1:5: +4:6 + drop(_1) -> [return: bb8, unwind: bb13]; // scope 0 at $DIR/issue_62289.rs:+4:5: +4:6 + } + + bb8: { + StorageDead(_1); // scope 0 at $DIR/issue_62289.rs:+4:5: +4:6 + StorageDead(_6); // scope 0 at $DIR/issue_62289.rs:+5:1: +5:2 + goto -> bb10; // scope 0 at $DIR/issue_62289.rs:+5:2: +5:2 + } + + bb9: { + StorageDead(_5); // scope 0 at $DIR/issue_62289.rs:+3:23: +3:24 + StorageDead(_1); // scope 0 at $DIR/issue_62289.rs:+4:5: +4:6 + StorageDead(_6); // scope 0 at $DIR/issue_62289.rs:+5:1: +5:2 + goto -> bb10; // scope 0 at $DIR/issue_62289.rs:+5:2: +5:2 + } + + bb10: { + return; // scope 0 at $DIR/issue_62289.rs:+5:2: +5:2 + } + + bb11 (cleanup): { + drop(_1) -> [return: bb13, unwind terminate]; // scope 0 at $DIR/issue_62289.rs:+4:5: +4:6 + } + + bb12 (cleanup): { + drop(_5) -> [return: bb13, unwind terminate]; // scope 0 at $DIR/issue_62289.rs:+3:23: +3:24 + } + + bb13 (cleanup): { + resume; // scope 0 at $DIR/issue_62289.rs:+0:1: +5:2 + } +} diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir similarity index 100% rename from tests/mir-opt/issue_62289.test.ElaborateDrops.before.mir rename to tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir diff --git a/tests/mir-opt/issue_76432.rs b/tests/mir-opt/issue_76432.rs index 76bb11aae3d74..2a8e1283b0cf9 100644 --- a/tests/mir-opt/issue_76432.rs +++ b/tests/mir-opt/issue_76432.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Zmir-enable-passes=-NormalizeArrayLen // Check that we do not insert StorageDead at each target if StorageDead was never seen diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff new file mode 100644 index 0000000000000..6515aeceed3d2 --- /dev/null +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff @@ -0,0 +1,60 @@ +- // MIR for `test` before SimplifyComparisonIntegral ++ // MIR for `test` after SimplifyComparisonIntegral + + fn test(_1: T) -> () { + debug x => _1; // in scope 0 at $DIR/issue_76432.rs:+0:38: +0:39 + let mut _0: (); // return place in scope 0 at $DIR/issue_76432.rs:+0:44: +0:44 + let _2: &[T]; // in scope 0 at $DIR/issue_76432.rs:+1:9: +1:10 + let mut _3: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + let _4: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + let _5: [T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:20: +1:29 + let mut _6: T; // in scope 0 at $DIR/issue_76432.rs:+1:21: +1:22 + let mut _7: T; // in scope 0 at $DIR/issue_76432.rs:+1:24: +1:25 + let mut _8: T; // in scope 0 at $DIR/issue_76432.rs:+1:27: +1:28 + let mut _9: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 + let mut _10: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 + let mut _11: bool; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 + let mut _15: !; // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL + scope 1 { + debug v => _2; // in scope 1 at $DIR/issue_76432.rs:+1:9: +1:10 + let _12: &T; // in scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 + let _13: &T; // in scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 + let _14: &T; // in scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 + scope 2 { + debug v1 => &(*_2)[0 of 3]; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16 + debug v2 => &(*_2)[1 of 3]; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24 + debug v3 => &(*_2)[2 of 3]; // in scope 2 at $DIR/issue_76432.rs:+3:26: +3:32 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_76432.rs:+1:9: +1:10 + StorageLive(_5); // scope 0 at $DIR/issue_76432.rs:+1:20: +1:29 + _5 = [_1, _1, _1]; // scope 0 at $DIR/issue_76432.rs:+1:20: +1:29 + _4 = &_5; // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + _2 = _4 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + _9 = Len((*_2)); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + _10 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 +- _11 = Eq(move _9, const 3_usize); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 +- switchInt(move _11) -> [0: bb1, otherwise: bb2]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 ++ nop; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 ++ switchInt(move _9) -> [3: bb2, otherwise: bb1]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + } + + bb1: { + _15 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable; // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/panic.rs:LL:COL + // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value() } + // mir::Constant + // + span: $SRC_DIR/core/src/panic.rs:LL:COL + // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + + bb2: { + StorageDead(_5); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2 + StorageDead(_2); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2 + return; // scope 0 at $DIR/issue_76432.rs:+6:2: +6:2 + } + } + diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff similarity index 100% rename from tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff rename to tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..a25d8e2733017 --- /dev/null +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir @@ -0,0 +1,84 @@ +// MIR for `num_to_digit` after PreCodegen + +fn num_to_digit(_1: char) -> u32 { + debug num => _1; // in scope 0 at $DIR/issue_59352.rs:+0:21: +0:24 + let mut _0: u32; // return place in scope 0 at $DIR/issue_59352.rs:+0:35: +0:38 + let mut _5: std::option::Option; // in scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 + scope 1 (inlined char::methods::::is_digit) { // at $DIR/issue_59352.rs:15:12: 15:23 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + debug radix => const 8_u32; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let _2: std::option::Option; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let mut _3: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + scope 2 (inlined Option::::is_some) { // at $SRC_DIR/core/src/char/methods.rs:LL:COL + debug self => _3; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _4: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + scope 3 (inlined #[track_caller] Option::::unwrap) { // at $DIR/issue_59352.rs:15:42: 15:50 + debug self => _5; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _6: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _7: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + scope 4 { + debug val => _0; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + + bb0: { + StorageLive(_3); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageLive(_2); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _2 = char::methods::::to_digit(_1, const 8_u32) -> [return: bb1, unwind unreachable]; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/char/methods.rs:LL:COL + // + literal: Const { ty: fn(char, u32) -> Option {char::methods::::to_digit}, val: Value() } + } + + bb1: { + _3 = &_2; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _4 = discriminant((*_3)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_3); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageDead(_2); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + switchInt(move _4) -> [1: bb2, otherwise: bb7]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 + } + + bb2: { + StorageLive(_5); // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 + _5 = char::methods::::to_digit(_1, const 8_u32) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 + // mir::Constant + // + span: $DIR/issue_59352.rs:15:30: 15:38 + // + literal: Const { ty: fn(char, u32) -> Option {char::methods::::to_digit}, val: Value() } + } + + bb3: { + _6 = discriminant(_5); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb6]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb4: { + _7 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value") -> unwind unreachable; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/option.rs:LL:COL + // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value() } + // mir::Constant + // + span: $SRC_DIR/core/src/option.rs:LL:COL + // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + + bb5: { + _0 = move ((_5 as Some).0: u32); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_5); // scope 0 at $DIR/issue_59352.rs:+2:49: +2:50 + goto -> bb8; // scope 0 at $DIR/issue_59352.rs:+2:5: +2:63 + } + + bb6: { + unreachable; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb7: { + _0 = const 0_u32; // scope 0 at $DIR/issue_59352.rs:+2:60: +2:61 + goto -> bb8; // scope 0 at $DIR/issue_59352.rs:+2:5: +2:63 + } + + bb8: { + return; // scope 0 at $DIR/issue_59352.rs:+3:2: +3:2 + } +} diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir rename to tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir diff --git a/tests/mir-opt/issues/issue_59352.rs b/tests/mir-opt/issues/issue_59352.rs index 92011bd65887c..7cadf8f227ff5 100644 --- a/tests/mir-opt/issues/issue_59352.rs +++ b/tests/mir-opt/issues/issue_59352.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // This test is a mirror of codegen/issue-59352.rs. // The LLVM inliner doesn't inline `char::method::is_digit()` and so it doesn't recognize this case // as effectively `if x.is_some() { x.unwrap() } else { 0 }`. diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff new file mode 100644 index 0000000000000..8b7f69361864c --- /dev/null +++ b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff @@ -0,0 +1,64 @@ +- // MIR for `array_bound` before NormalizeArrayLen ++ // MIR for `array_bound` after NormalizeArrayLen + + fn array_bound(_1: usize, _2: &[u8; N]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41 + debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55 + let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72 + let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21 +- _5 = Len((*_6)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + } + + bb1: { + StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + switchInt(move _3) -> [0: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + } + + bb2: { + StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + } + + bb3: { + _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6 + goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6 + } + + bb4: { + _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11 + goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6 + } + + bb5: { + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6 + return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2 + } + } + diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff similarity index 100% rename from tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff rename to tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff new file mode 100644 index 0000000000000..50903ccb16180 --- /dev/null +++ b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff @@ -0,0 +1,77 @@ +- // MIR for `array_bound_mut` before NormalizeArrayLen ++ // MIR for `array_bound_mut` after NormalizeArrayLen + + fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45 + debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59 + let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80 + let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 + let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21 +- _5 = Len((*_6)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + } + + bb1: { + StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + switchInt(move _3) -> [0: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + } + + bb2: { + StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + } + + bb3: { + _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6 + goto -> bb6; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6 + } + + bb4: { + StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 + _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 + _12 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + _13 = Lt(_11, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind unreachable]; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + } + + bb5: { + (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22 + StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23 + _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11 + goto -> bb6; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6 + } + + bb6: { + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6 + return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2 + } + } + diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff similarity index 100% rename from tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff rename to tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff diff --git a/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff rename to tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-abort.diff diff --git a/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-unwind.diff new file mode 100644 index 0000000000000..66feff62f4246 --- /dev/null +++ b/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-unwind.diff @@ -0,0 +1,26 @@ +- // MIR for `array_len` before NormalizeArrayLen ++ // MIR for `array_len` after NormalizeArrayLen + + fn array_len(_1: &[u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57 + let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _3 = &(*_1); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8 +- _0 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14 + return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff rename to tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-abort.diff diff --git a/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-unwind.diff new file mode 100644 index 0000000000000..c0a277edc4670 --- /dev/null +++ b/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-unwind.diff @@ -0,0 +1,26 @@ +- // MIR for `array_len_by_value` before NormalizeArrayLen ++ // MIR for `array_len_by_value` after NormalizeArrayLen + + fn array_len_by_value(_1: [u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65 + let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _3 = &_1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8 +- _0 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14 + return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.diff rename to tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff diff --git a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff new file mode 100644 index 0000000000000..8b35fd57fa016 --- /dev/null +++ b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff @@ -0,0 +1,50 @@ +- // MIR for `array_len_raw` before NormalizeArrayLen ++ // MIR for `array_len_raw` after NormalizeArrayLen + + fn array_len_raw(_1: [u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:38: +0:41 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:55: +0:60 + let _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:9: +1:12 + let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:21: +1:25 + let _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:21: +1:25 + let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+3:5: +3:27 + let _7: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+3:14: +3:19 + scope 1 { + debug arr => _2; // in scope 1 at $DIR/lower_array_len.rs:+1:9: +1:12 + let _5: *const [u8]; // in scope 1 at $DIR/lower_array_len.rs:+2:9: +2:12 + scope 2 { + debug arr => _5; // in scope 2 at $DIR/lower_array_len.rs:+2:9: +2:12 + scope 3 { + } + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:9: +1:12 + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:21: +1:25 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:21: +1:25 + _4 = &_1; // scope 0 at $DIR/lower_array_len.rs:+1:21: +1:25 + _3 = &(*_4); // scope 0 at $DIR/lower_array_len.rs:+1:21: +1:25 + _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:21: +1:25 + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:24: +1:25 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:25: +1:26 + StorageLive(_5); // scope 1 at $DIR/lower_array_len.rs:+2:9: +2:12 + _5 = &raw const (*_2); // scope 1 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageLive(_6); // scope 2 at $DIR/lower_array_len.rs:+3:5: +3:27 + StorageLive(_7); // scope 2 at $DIR/lower_array_len.rs:+3:14: +3:19 + _7 = &(*_5); // scope 3 at $DIR/lower_array_len.rs:+3:14: +3:19 + _6 = &(*_7); // scope 2 at $DIR/lower_array_len.rs:+3:5: +3:27 +- _0 = Len((*_6)); // scope 2 at $DIR/lower_array_len.rs:+3:5: +3:27 ++ _0 = const N; // scope 2 at $DIR/lower_array_len.rs:+3:5: +3:27 + goto -> bb1; // scope 2 at $DIR/lower_array_len.rs:+3:5: +3:27 + } + + bb1: { + StorageDead(_6); // scope 2 at $DIR/lower_array_len.rs:+3:26: +3:27 + StorageDead(_5); // scope 1 at $DIR/lower_array_len.rs:+4:1: +4:2 + StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+4:1: +4:2 + StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+4:1: +4:2 + return; // scope 0 at $DIR/lower_array_len.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.diff rename to tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-abort.diff diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-unwind.diff new file mode 100644 index 0000000000000..8bdd2ede6bc41 --- /dev/null +++ b/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-unwind.diff @@ -0,0 +1,44 @@ +- // MIR for `array_len_reborrow` before NormalizeArrayLen ++ // MIR for `array_len_reborrow` after NormalizeArrayLen + + fn array_len_reborrow(_1: [u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:50 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:64: +0:69 + let _2: &mut [u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:9: +1:12 + let mut _3: &mut [u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:25: +1:33 + let mut _4: &mut [u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:25: +1:33 + let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+3:5: +3:14 + scope 1 { + debug arr => _2; // in scope 1 at $DIR/lower_array_len.rs:+1:9: +1:12 + let _5: &[u8]; // in scope 1 at $DIR/lower_array_len.rs:+2:9: +2:12 + scope 2 { + debug arr => _5; // in scope 2 at $DIR/lower_array_len.rs:+2:9: +2:12 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:9: +1:12 + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:25: +1:33 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:25: +1:33 + _4 = &mut _1; // scope 0 at $DIR/lower_array_len.rs:+1:25: +1:33 + _3 = &mut (*_4); // scope 0 at $DIR/lower_array_len.rs:+1:25: +1:33 + _2 = move _3 as &mut [u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:25: +1:33 + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:32: +1:33 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:33: +1:34 + StorageLive(_5); // scope 1 at $DIR/lower_array_len.rs:+2:9: +2:12 + _5 = &(*_2); // scope 1 at $DIR/lower_array_len.rs:+2:15: +2:20 + StorageLive(_6); // scope 2 at $DIR/lower_array_len.rs:+3:5: +3:14 + _6 = &(*_5); // scope 2 at $DIR/lower_array_len.rs:+3:5: +3:14 +- _0 = Len((*_6)); // scope 2 at $DIR/lower_array_len.rs:+3:5: +3:14 ++ _0 = const N; // scope 2 at $DIR/lower_array_len.rs:+3:5: +3:14 + goto -> bb1; // scope 2 at $DIR/lower_array_len.rs:+3:5: +3:14 + } + + bb1: { + StorageDead(_6); // scope 2 at $DIR/lower_array_len.rs:+3:13: +3:14 + StorageDead(_5); // scope 1 at $DIR/lower_array_len.rs:+4:1: +4:2 + StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+4:1: +4:2 + return; // scope 0 at $DIR/lower_array_len.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/lower_array_len.rs b/tests/mir-opt/lower_array_len.rs index e1bb51f2d1d9c..7d69e175921c9 100644 --- a/tests/mir-opt/lower_array_len.rs +++ b/tests/mir-opt/lower_array_len.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: NormalizeArrayLen // compile-flags: -Zmir-enable-passes=+LowerSliceLenCalls diff --git a/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..3530f4a807f2c --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,20 @@ +- // MIR for `align_of` before LowerIntrinsics ++ // MIR for `align_of` after LowerIntrinsics + + fn align_of() -> usize { + let mut _0: usize; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:30 + + bb0: { +- _0 = std::intrinsics::min_align_of::() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:27:5: 27:40 +- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::min_align_of::}, val: Value() } ++ _0 = AlignOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42 + } + + bb1: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..158ce62e209c2 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,26 @@ +- // MIR for `assume` before LowerIntrinsics ++ // MIR for `assume` after LowerIntrinsics + + fn assume() -> () { + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:17 + let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:38 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 +- _1 = std::intrinsics::assume(const true) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:112:9: 112:32 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(bool) {std::intrinsics::assume}, val: Value() } ++ assume(const true); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 + } + + bb1: { + StorageDead(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:38: +2:39 + _0 = const (); // scope 1 at $DIR/lower_intrinsics.rs:+1:5: +3:6 + return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-abort.diff new file mode 100644 index 0000000000000..63f5b80e2764d --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-abort.diff @@ -0,0 +1,115 @@ +- // MIR for `discriminant` before LowerIntrinsics ++ // MIR for `discriminant` after LowerIntrinsics + + fn discriminant(_1: T) -> () { + debug t => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:24: +0:25 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:30: +0:30 + let _2: ::Discriminant; // in scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 + let mut _3: &T; // in scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 + let _4: &T; // in scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 + let _5: u8; // in scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 + let mut _6: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + let _7: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + let _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:43: +2:44 + let _9: u8; // in scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 + let mut _10: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + let _11: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + let _12: (); // in scope 0 at $DIR/lower_intrinsics.rs:+3:43: +3:45 + let _13: isize; // in scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 + let mut _14: &E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + let _15: &E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + let _16: E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:43: +4:47 + let mut _17: &E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + let mut _18: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + let mut _19: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 + StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 + StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 + _4 = &_1; // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 + _3 = &(*_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 +- _2 = discriminant_value::(move _3) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:88:5: 88:41 +- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a T) -> ::Discriminant {discriminant_value::}, val: Value() } ++ _2 = discriminant((*_3)); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:44: +1:45 + StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 + StorageDead(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 + StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 + StorageLive(_6); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + StorageLive(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + _19 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:89:42: 89:44 + // + literal: Const { ty: &i32, val: Unevaluated(discriminant, [T], Some(promoted[2])) } + _7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + _6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 +- _5 = discriminant_value::(move _6) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:89:5: 89:41 +- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a i32) -> ::Discriminant {discriminant_value::}, val: Value() } ++ _5 = discriminant((*_6)); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 ++ goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 + } + + bb2: { + StorageDead(_6); // scope 0 at $DIR/lower_intrinsics.rs:+2:44: +2:45 + StorageDead(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:45: +2:46 + StorageDead(_5); // scope 0 at $DIR/lower_intrinsics.rs:+2:45: +2:46 + StorageLive(_9); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 + StorageLive(_10); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + StorageLive(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + _18 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:90:42: 90:45 + // + literal: Const { ty: &(), val: Unevaluated(discriminant, [T], Some(promoted[1])) } + _11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + _10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 +- _9 = discriminant_value::<()>(move _10) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:90:5: 90:41 +- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a ()) -> <() as DiscriminantKind>::Discriminant {discriminant_value::<()>}, val: Value() } ++ _9 = discriminant((*_10)); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 ++ goto -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 + } + + bb3: { + StorageDead(_10); // scope 0 at $DIR/lower_intrinsics.rs:+3:45: +3:46 + StorageDead(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:46: +3:47 + StorageDead(_9); // scope 0 at $DIR/lower_intrinsics.rs:+3:46: +3:47 + StorageLive(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 + StorageLive(_14); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + StorageLive(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + _17 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:91:42: 91:47 + // + literal: Const { ty: &E, val: Unevaluated(discriminant, [T], Some(promoted[0])) } + _15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + _14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 +- _13 = discriminant_value::(move _14) -> [return: bb4, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:91:5: 91:41 +- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a E) -> ::Discriminant {discriminant_value::}, val: Value() } ++ _13 = discriminant((*_14)); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 ++ goto -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 + } + + bb4: { + StorageDead(_14); // scope 0 at $DIR/lower_intrinsics.rs:+4:47: +4:48 + StorageDead(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:48: +4:49 + StorageDead(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:48: +4:49 + _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:30: +5:2 + drop(_1) -> [return: bb5, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+5:1: +5:2 + } + + bb5: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-unwind.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-unwind.diff diff --git a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..5b870ccf5ee28 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,72 @@ +- // MIR for `f_copy_nonoverlapping` before LowerIntrinsics ++ // MIR for `f_copy_nonoverlapping` after LowerIntrinsics + + fn f_copy_nonoverlapping() -> () { + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:32: +0:32 + let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12 + let _3: (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:9: +4:95 + let mut _4: *const i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:59 + let mut _5: *const (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + let mut _6: *const (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + let _7: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + let mut _8: *mut i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:91 + let mut _9: *mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + let mut _10: *mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + let mut _11: &mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + scope 1 { + debug src => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:12 + let mut _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16 + scope 2 { + debug dst => _2; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:16 + scope 3 { + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12 + _1 = (); // scope 0 at $DIR/lower_intrinsics.rs:+1:15: +1:17 + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16 + _2 = (); // scope 1 at $DIR/lower_intrinsics.rs:+2:19: +2:21 + StorageLive(_3); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 + StorageLive(_4); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59 + StorageLive(_5); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + StorageLive(_6); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + StorageLive(_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + _7 = &_1; // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + _6 = &raw const (*_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + _5 = _6; // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + _4 = move _5 as *const i32 (PtrToPtr); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59 + StorageDead(_5); // scope 3 at $DIR/lower_intrinsics.rs:+4:58: +4:59 + StorageLive(_8); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91 + StorageLive(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + StorageLive(_10); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + StorageLive(_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + _11 = &mut _2; // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + _10 = &raw mut (*_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + _9 = _10; // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + _8 = move _9 as *mut i32 (PtrToPtr); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91 + StorageDead(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:90: +4:91 +- _3 = copy_nonoverlapping::(move _4, move _8, const 0_usize) -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:105:9: 105:28 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, *mut i32, usize) {copy_nonoverlapping::}, val: Value() } ++ copy_nonoverlapping(dst = move _8, src = move _4, count = const 0_usize); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 ++ goto -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 + } + + bb1: { + StorageDead(_8); // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95 + StorageDead(_4); // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95 + StorageDead(_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_10); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_6); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_3); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + _0 = const (); // scope 3 at $DIR/lower_intrinsics.rs:+3:5: +5:6 + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+6:1: +6:2 + StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+6:1: +6:2 + return; // scope 0 at $DIR/lower_intrinsics.rs:+6:2: +6:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..582a79f48d8c8 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,29 @@ +- // MIR for `forget` before LowerIntrinsics ++ // MIR for `forget` after LowerIntrinsics + + fn forget(_1: T) -> () { + debug t => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:18: +0:19 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:24: +0:24 + let mut _2: T; // in scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31 + _2 = move _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31 +- _0 = std::intrinsics::forget::(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:32:5: 32:29 +- // + literal: Const { ty: extern "rust-intrinsic" fn(T) {std::intrinsics::forget::}, val: Value() } ++ _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32 + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:31: +1:32 + goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:1: +2:2 + } + + bb2: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..81ad97077b428 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,31 @@ +- // MIR for `non_const` before LowerIntrinsics ++ // MIR for `non_const` after LowerIntrinsics + + fn non_const() -> usize { + let mut _0: usize; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:26: +0:31 + let _1: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::}; // in scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:18 + let mut _2: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::}; // in scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:14 + scope 1 { + debug size_of_t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:18 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:18 + _1 = std::intrinsics::size_of::; // scope 0 at $DIR/lower_intrinsics.rs:+2:21: +2:51 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:43:21: 43:51 + // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::}, val: Value() } + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14 + _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14 +- _0 = move _2() -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:16 ++ _0 = SizeOf(T); // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:16 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:16 + } + + bb1: { + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+3:15: +3:16 + StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..edc66e2c75ce4 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,54 @@ +- // MIR for `option_payload` before LowerIntrinsics ++ // MIR for `option_payload` after LowerIntrinsics + + fn option_payload(_1: &Option, _2: &Option) -> () { + debug o => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:23: +0:24 + debug p => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:42: +0:43 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:62: +0:62 + let mut _4: *const std::option::Option; // in scope 0 at $DIR/lower_intrinsics.rs:+2:55: +2:56 + let mut _6: *const std::option::Option; // in scope 0 at $DIR/lower_intrinsics.rs:+3:55: +3:56 + scope 1 { + let _3: *const usize; // in scope 1 at $DIR/lower_intrinsics.rs:+2:13: +2:15 + scope 2 { + debug _x => _3; // in scope 2 at $DIR/lower_intrinsics.rs:+2:13: +2:15 + let _5: *const std::string::String; // in scope 2 at $DIR/lower_intrinsics.rs:+3:13: +3:15 + scope 3 { + debug _y => _5; // in scope 3 at $DIR/lower_intrinsics.rs:+3:13: +3:15 + } + } + } + + bb0: { + StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+2:13: +2:15 + StorageLive(_4); // scope 1 at $DIR/lower_intrinsics.rs:+2:55: +2:56 + _4 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:55: +2:56 +- _3 = option_payload_ptr::(move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:143:18: 143:54 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Option) -> *const usize {option_payload_ptr::}, val: Value() } ++ _3 = &raw const (((*_4) as Some).0: usize); // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57 + } + + bb1: { + StorageDead(_4); // scope 1 at $DIR/lower_intrinsics.rs:+2:56: +2:57 + StorageLive(_5); // scope 2 at $DIR/lower_intrinsics.rs:+3:13: +3:15 + StorageLive(_6); // scope 2 at $DIR/lower_intrinsics.rs:+3:55: +3:56 + _6 = &raw const (*_2); // scope 2 at $DIR/lower_intrinsics.rs:+3:55: +3:56 +- _5 = option_payload_ptr::(move _6) -> [return: bb2, unwind unreachable]; // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:144:18: 144:54 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Option) -> *const String {option_payload_ptr::}, val: Value() } ++ _5 = &raw const (((*_6) as Some).0: std::string::String); // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57 ++ goto -> bb2; // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57 + } + + bb2: { + StorageDead(_6); // scope 2 at $DIR/lower_intrinsics.rs:+3:56: +3:57 + _0 = const (); // scope 1 at $DIR/lower_intrinsics.rs:+1:5: +4:6 + StorageDead(_5); // scope 2 at $DIR/lower_intrinsics.rs:+4:5: +4:6 + StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:+4:5: +4:6 + return; // scope 0 at $DIR/lower_intrinsics.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..1760efe77d98f --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,30 @@ +- // MIR for `ptr_offset` before LowerIntrinsics ++ // MIR for `ptr_offset` after LowerIntrinsics + + fn ptr_offset(_1: *const i32, _2: isize) -> *const i32 { + debug p => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:26: +0:27 + debug d => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:41: +0:42 + let mut _0: *const i32; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:54: +0:64 + let mut _3: *const i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31 + let mut _4: isize; // in scope 0 at $DIR/lower_intrinsics.rs:+1:33: +1:34 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31 + _3 = _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31 + StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:33: +1:34 + _4 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:33: +1:34 +- _0 = offset::<*const i32, isize>(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:150:5: 150:29 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, isize) -> *const i32 {offset::<*const i32, isize>}, val: Value() } ++ _0 = Offset(move _3, move _4); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35 + } + + bb1: { + StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:34: +1:35 + StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:34: +1:35 + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..8583766348a6e --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,27 @@ +- // MIR for `read_via_copy_primitive` before LowerIntrinsics ++ // MIR for `read_via_copy_primitive` after LowerIntrinsics + + fn read_via_copy_primitive(_1: &i32) -> i32 { + debug r => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:32: +0:33 + let mut _0: i32; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:44: +0:47 + let mut _2: *const i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + _2 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47 +- _0 = read_via_copy::(move _2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:125:14: 125:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32) -> i32 {read_via_copy::}, val: Value() } ++ _0 = (*_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 + } + + bb1: { + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..f64bc9dcf620c --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,21 @@ +- // MIR for `read_via_copy_uninhabited` before LowerIntrinsics ++ // MIR for `read_via_copy_uninhabited` after LowerIntrinsics + + fn read_via_copy_uninhabited(_1: &Never) -> Never { + debug r => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:34: +0:35 + let mut _0: Never; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:48: +0:53 + let mut _2: *const Never; // in scope 0 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + _2 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47 +- _0 = read_via_copy::(move _2) -> unwind unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:130:14: 130:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Never) -> Never {read_via_copy::}, val: Value() } ++ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs index 30b5c78e647c8..876b4497034e3 100644 --- a/tests/mir-opt/lower_intrinsics.rs +++ b/tests/mir-opt/lower_intrinsics.rs @@ -1,5 +1,5 @@ // unit-test: LowerIntrinsics -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![feature(core_intrinsics, intrinsics, rustc_attrs)] #![crate_type = "lib"] diff --git a/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..a880df6a5c236 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,20 @@ +- // MIR for `size_of` before LowerIntrinsics ++ // MIR for `size_of` after LowerIntrinsics + + fn size_of() -> usize { + let mut _0: usize; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:24: +0:29 + + bb0: { +- _0 = std::intrinsics::size_of::() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:22:5: 22:35 +- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::}, val: Value() } ++ _0 = SizeOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37 + } + + bb1: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..cde7c64c57a56 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,27 @@ +- // MIR for `transmute_inhabited` before LowerIntrinsics ++ // MIR for `transmute_inhabited` after LowerIntrinsics + + fn transmute_inhabited(_1: std::cmp::Ordering) -> i8 { + debug c => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:28: +0:29 + let mut _0: i8; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:54: +0:56 + let mut _2: std::cmp::Ordering; // in scope 0 at $DIR/lower_intrinsics.rs:+1:34: +1:35 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:34: +1:35 + _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+1:34: +1:35 +- _0 = transmute::(move _2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:49:14: 49:33 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(std::cmp::Ordering) -> i8 {transmute::}, val: Value() } ++ _0 = move _2 as i8 (Transmute); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 + } + + bb1: { + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:35: +1:36 + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..6fc0f3d3e3fee --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,27 @@ +- // MIR for `transmute_ref_dst` before LowerIntrinsics ++ // MIR for `transmute_ref_dst` after LowerIntrinsics + + fn transmute_ref_dst(_1: &T) -> *const T { + debug u => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:44: +0:45 + let mut _0: *const T; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:54: +0:62 + let mut _2: &T; // in scope 0 at $DIR/lower_intrinsics.rs:+1:34: +1:35 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:34: +1:35 + _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+1:34: +1:35 +- _0 = transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:59:14: 59:33 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&T) -> *const T {transmute::<&T, *const T>}, val: Value() } ++ _0 = move _2 as *const T (Transmute); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 + } + + bb1: { + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:35: +1:36 + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..e6887a382a2d6 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,25 @@ +- // MIR for `transmute_to_box_uninhabited` before LowerIntrinsics ++ // MIR for `transmute_to_box_uninhabited` after LowerIntrinsics + + fn transmute_to_box_uninhabited() -> ! { + let mut _0: !; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:49: +0:50 + let _1: std::boxed::Box; // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10 +- _1 = transmute::>(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:76:25: 76:44 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize) -> Box {transmute::>}, val: Value() } ++ _1 = const 1_usize as std::boxed::Box (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 + } + + bb1: { + unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+2:11: +2:13 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..b2a44b7c56114 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,25 @@ +- // MIR for `transmute_to_mut_uninhabited` before LowerIntrinsics ++ // MIR for `transmute_to_mut_uninhabited` after LowerIntrinsics + + fn transmute_to_mut_uninhabited() -> ! { + let mut _0: !; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:49: +0:50 + let _1: &mut Never; // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10 +- _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:70:25: 70:44 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize) -> &mut Never {transmute::}, val: Value() } ++ _1 = const 1_usize as &mut Never (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 + } + + bb1: { + unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+2:11: +2:13 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..c49d3aeff70b6 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,25 @@ +- // MIR for `transmute_to_ref_uninhabited` before LowerIntrinsics ++ // MIR for `transmute_to_ref_uninhabited` after LowerIntrinsics + + fn transmute_to_ref_uninhabited() -> ! { + let mut _0: !; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:49: +0:50 + let _1: &Never; // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10 +- _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:64:21: 64:40 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize) -> &Never {transmute::}, val: Value() } ++ _1 = const 1_usize as &Never (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48 + } + + bb1: { + unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+2:11: +2:13 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..06759d74a3205 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,22 @@ +- // MIR for `transmute_uninhabited` before LowerIntrinsics ++ // MIR for `transmute_uninhabited` after LowerIntrinsics + + fn transmute_uninhabited(_1: ()) -> Never { + debug u => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:37: +0:38 + let mut _0: Never; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:47: +0:52 + let mut _2: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:47: +1:48 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 + _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 +- _0 = transmute::<(), Never>(move _2) -> unwind unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:49 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:54:14: 54:46 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(()) -> Never {transmute::<(), Never>}, val: Value() } ++ _0 = move _2 as Never (Transmute); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:49 ++ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:49 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..9bb43d850ebf3 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,60 @@ +- // MIR for `unchecked` before LowerIntrinsics ++ // MIR for `unchecked` after LowerIntrinsics + + fn unchecked(_1: i32, _2: i32) -> () { + debug a => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:26 + debug b => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:33: +0:34 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:41: +0:41 + let _3: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + let mut _4: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + let mut _5: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50 + let mut _7: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:46: +2:47 + let mut _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:49: +2:50 + scope 1 { + debug _x => _3; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + let _6: i32; // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + scope 2 { + debug _y => _6; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + _4 = _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50 + _5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50 +- _3 = unchecked_div::(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:51 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:16:14: 16:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_div::}, val: Value() } ++ _3 = Div(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:51 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:51 + } + + bb1: { + StorageDead(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51 + StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51 + StorageLive(_6); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + StorageLive(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:46: +2:47 + _7 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+2:46: +2:47 + StorageLive(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:49: +2:50 + _8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:49: +2:50 +- _6 = unchecked_rem::(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:51 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:17:14: 17:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_rem::}, val: Value() } ++ _6 = Rem(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:51 ++ goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:51 + } + + bb2: { + StorageDead(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:50: +2:51 + StorageDead(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:50: +2:51 + _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:41: +3:2 + StorageDead(_6); // scope 1 at $DIR/lower_intrinsics.rs:+3:1: +3:2 + StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+3:1: +3:2 + return; // scope 0 at $DIR/lower_intrinsics.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..83c9c508bc0b0 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,21 @@ +- // MIR for `unreachable` before LowerIntrinsics ++ // MIR for `unreachable` after LowerIntrinsics + + fn unreachable() -> ! { + let mut _0: !; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:26 + let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:45 + let mut _2: !; // in scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:45 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:47 + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45 +- _2 = std::intrinsics::unreachable() -> unwind unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:37:14: 37:43 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value() } ++ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..4ae4466a60038 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,83 @@ +- // MIR for `with_overflow` before LowerIntrinsics ++ // MIR for `with_overflow` after LowerIntrinsics + + fn with_overflow(_1: i32, _2: i32) -> () { + debug a => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:22: +0:23 + debug b => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:30: +0:31 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:38: +0:38 + let _3: (i32, bool); // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + let mut _4: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51 + let mut _5: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:53: +1:54 + let mut _7: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:50: +2:51 + let mut _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:53: +2:54 + let mut _10: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+3:50: +3:51 + let mut _11: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+3:53: +3:54 + scope 1 { + debug _x => _3; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + let _6: (i32, bool); // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + scope 2 { + debug _y => _6; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + let _9: (i32, bool); // in scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + scope 3 { + debug _z => _9; // in scope 3 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + } + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51 + _4 = _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51 + StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:53: +1:54 + _5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:53: +1:54 +- _3 = add_with_overflow::(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:118:14: 118:49 +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {add_with_overflow::}, val: Value() } ++ _3 = CheckedAdd(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55 + } + + bb1: { + StorageDead(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:54: +1:55 + StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:54: +1:55 + StorageLive(_6); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + StorageLive(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:50: +2:51 + _7 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+2:50: +2:51 + StorageLive(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:53: +2:54 + _8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:53: +2:54 +- _6 = sub_with_overflow::(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:119:14: 119:49 +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {sub_with_overflow::}, val: Value() } ++ _6 = CheckedSub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55 ++ goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55 + } + + bb2: { + StorageDead(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:54: +2:55 + StorageDead(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:54: +2:55 + StorageLive(_9); // scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + StorageLive(_10); // scope 2 at $DIR/lower_intrinsics.rs:+3:50: +3:51 + _10 = _1; // scope 2 at $DIR/lower_intrinsics.rs:+3:50: +3:51 + StorageLive(_11); // scope 2 at $DIR/lower_intrinsics.rs:+3:53: +3:54 + _11 = _2; // scope 2 at $DIR/lower_intrinsics.rs:+3:53: +3:54 +- _9 = mul_with_overflow::(move _10, move _11) -> [return: bb3, unwind unreachable]; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:120:14: 120:49 +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {mul_with_overflow::}, val: Value() } ++ _9 = CheckedMul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55 ++ goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55 + } + + bb3: { + StorageDead(_11); // scope 2 at $DIR/lower_intrinsics.rs:+3:54: +3:55 + StorageDead(_10); // scope 2 at $DIR/lower_intrinsics.rs:+3:54: +3:55 + _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:38: +4:2 + StorageDead(_9); // scope 2 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + StorageDead(_6); // scope 1 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..217f27efe5cc9 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,83 @@ +- // MIR for `wrapping` before LowerIntrinsics ++ // MIR for `wrapping` after LowerIntrinsics + + fn wrapping(_1: i32, _2: i32) -> () { + debug a => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:18 + debug b => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:26 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:33: +0:33 + let _3: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + let mut _4: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 + let mut _5: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49 + let mut _7: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:45: +2:46 + let mut _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:48: +2:49 + let mut _10: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+3:45: +3:46 + let mut _11: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+3:48: +3:49 + scope 1 { + debug _x => _3; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + let _6: i32; // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + scope 2 { + debug _y => _6; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + let _9: i32; // in scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + scope 3 { + debug _z => _9; // in scope 3 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + } + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 + _4 = _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 + StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49 + _5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49 +- _3 = std::intrinsics::wrapping_add::(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:9:14: 9:44 +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {std::intrinsics::wrapping_add::}, val: Value() } ++ _3 = Add(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50 + } + + bb1: { + StorageDead(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50 + StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50 + StorageLive(_6); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + StorageLive(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:45: +2:46 + _7 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+2:45: +2:46 + StorageLive(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:48: +2:49 + _8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:48: +2:49 +- _6 = std::intrinsics::wrapping_sub::(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:10:14: 10:44 +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {std::intrinsics::wrapping_sub::}, val: Value() } ++ _6 = Sub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50 ++ goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50 + } + + bb2: { + StorageDead(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:49: +2:50 + StorageDead(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:49: +2:50 + StorageLive(_9); // scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + StorageLive(_10); // scope 2 at $DIR/lower_intrinsics.rs:+3:45: +3:46 + _10 = _1; // scope 2 at $DIR/lower_intrinsics.rs:+3:45: +3:46 + StorageLive(_11); // scope 2 at $DIR/lower_intrinsics.rs:+3:48: +3:49 + _11 = _2; // scope 2 at $DIR/lower_intrinsics.rs:+3:48: +3:49 +- _9 = wrapping_mul::(move _10, move _11) -> [return: bb3, unwind unreachable]; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:11:14: 11:44 +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_mul::}, val: Value() } ++ _9 = Mul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50 ++ goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50 + } + + bb3: { + StorageDead(_11); // scope 2 at $DIR/lower_intrinsics.rs:+3:49: +3:50 + StorageDead(_10); // scope 2 at $DIR/lower_intrinsics.rs:+3:49: +3:50 + _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:33: +4:2 + StorageDead(_9); // scope 2 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + StorageDead(_6); // scope 1 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff similarity index 100% rename from tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.diff rename to tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff diff --git a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..2eabd7f626b69 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,36 @@ +- // MIR for `write_via_move_string` before LowerIntrinsics ++ // MIR for `write_via_move_string` after LowerIntrinsics + + fn write_via_move_string(_1: &mut String, _2: String) -> () { + debug r => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:30: +0:31 + debug v => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:46: +0:47 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:57: +0:57 + let mut _3: *mut std::string::String; // in scope 0 at $DIR/lower_intrinsics.rs:+1:47: +1:48 + let mut _4: std::string::String; // in scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51 + scope 1 { + } + + bb0: { + StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 + _3 = &raw mut (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 + StorageLive(_4); // scope 1 at $DIR/lower_intrinsics.rs:+1:50: +1:51 + _4 = move _2; // scope 1 at $DIR/lower_intrinsics.rs:+1:50: +1:51 +- _0 = write_via_move::(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:135:14: 135:46 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*mut String, String) {write_via_move::}, val: Value() } ++ (*_3) = move _4; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 + } + + bb1: { + StorageDead(_4); // scope 1 at $DIR/lower_intrinsics.rs:+1:51: +1:52 + StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:+1:51: +1:52 + goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:1: +2:2 + } + + bb2: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff new file mode 100644 index 0000000000000..8a9ac6b6673b0 --- /dev/null +++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff @@ -0,0 +1,63 @@ +- // MIR for `bound` before LowerSliceLenCalls ++ // MIR for `bound` after LowerSliceLenCalls + + fn bound(_1: usize, _2: &[u8]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_slice_len.rs:+0:14: +0:19 + debug slice => _2; // in scope 0 at $DIR/lower_slice_len.rs:+0:28: +0:33 + let mut _0: u8; // return place in scope 0 at $DIR/lower_slice_len.rs:+0:45: +0:47 + let mut _3: bool; // in scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 + let mut _6: &[u8]; // in scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 + let _7: usize; // in scope 0 at $DIR/lower_slice_len.rs:+2:15: +2:20 + let mut _8: usize; // in scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + let mut _9: bool; // in scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 + StorageLive(_6); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 + _6 = &(*_2); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 +- _5 = core::slice::::len(move _6) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 +- // mir::Constant +- // + span: $DIR/lower_slice_len.rs:6:22: 6:25 +- // + literal: Const { ty: for<'a> fn(&'a [u8]) -> usize {core::slice::::len}, val: Value() } ++ _5 = Len((*_6)); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 ++ goto -> bb1; // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 + } + + bb1: { + StorageDead(_6); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27 + switchInt(move _3) -> [0: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 + } + + bb2: { + StorageLive(_7); // scope 0 at $DIR/lower_slice_len.rs:+2:15: +2:20 + _7 = _1; // scope 0 at $DIR/lower_slice_len.rs:+2:15: +2:20 + _8 = Len((*_2)); // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + _9 = Lt(_7, _8); // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb3, unwind unreachable]; // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + } + + bb3: { + _0 = (*_2)[_7]; // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + StorageDead(_7); // scope 0 at $DIR/lower_slice_len.rs:+3:5: +3:6 + goto -> bb5; // scope 0 at $DIR/lower_slice_len.rs:+1:5: +5:6 + } + + bb4: { + _0 = const 42_u8; // scope 0 at $DIR/lower_slice_len.rs:+4:9: +4:11 + goto -> bb5; // scope 0 at $DIR/lower_slice_len.rs:+1:5: +5:6 + } + + bb5: { + StorageDead(_3); // scope 0 at $DIR/lower_slice_len.rs:+5:5: +5:6 + return; // scope 0 at $DIR/lower_slice_len.rs:+6:2: +6:2 + } + } + diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff similarity index 100% rename from tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff rename to tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff diff --git a/tests/mir-opt/lower_slice_len.rs b/tests/mir-opt/lower_slice_len.rs index 9c39c29fc4e4d..b0c512aec89d2 100644 --- a/tests/mir-opt/lower_slice_len.rs +++ b/tests/mir-opt/lower_slice_len.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: LowerSliceLenCalls // EMIT_MIR lower_slice_len.bound.LowerSliceLenCalls.diff diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff similarity index 100% rename from tests/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff rename to tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff new file mode 100644 index 0000000000000..3081e78f26db7 --- /dev/null +++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff @@ -0,0 +1,272 @@ +- // MIR for `complicated_match` after SimplifyCfg-initial ++ // MIR for `complicated_match` after ElaborateDrops + + fn complicated_match(_1: bool, _2: (bool, bool, String)) -> i32 { + debug cond => _1; // in scope 0 at $DIR/match_arm_scopes.rs:+0:22: +0:26 + debug items => _2; // in scope 0 at $DIR/match_arm_scopes.rs:+0:34: +0:39 + let mut _0: i32; // return place in scope 0 at $DIR/match_arm_scopes.rs:+0:66: +0:69 + let mut _3: &bool; // in scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 + let mut _4: &bool; // in scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 + let _5: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + let _6: &bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + let _7: std::string::String; // in scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + let _8: &std::string::String; // in scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + let mut _9: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + let mut _10: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 + let mut _11: !; // in scope 0 at $DIR/match_arm_scopes.rs:+2:52: +2:60 + let mut _12: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + let mut _13: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 + let mut _14: !; // in scope 0 at $DIR/match_arm_scopes.rs:+2:52: +2:60 + let _15: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+3:16: +3:17 + let _16: std::string::String; // in scope 0 at $DIR/match_arm_scopes.rs:+3:19: +3:20 + scope 1 { + debug a => _5; // in scope 1 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + debug a => _6; // in scope 1 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + debug s => _7; // in scope 1 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + debug s => _8; // in scope 1 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + } + scope 2 { + debug b => _15; // in scope 2 at $DIR/match_arm_scopes.rs:+3:16: +3:17 + debug t => _16; // in scope 2 at $DIR/match_arm_scopes.rs:+3:19: +3:20 + } + + bb0: { +- FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 +- switchInt((_2.0: bool)) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 ++ switchInt((_2.0: bool)) -> [0: bb5, otherwise: bb1]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 + } + + bb1: { +- falseEdge -> [real: bb8, imaginary: bb3]; // scope 0 at $DIR/match_arm_scopes.rs:+2:9: +2:22 ++ switchInt((_2.1: bool)) -> [0: bb10, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 + } + + bb2: { +- switchInt((_2.1: bool)) -> [0: bb3, otherwise: bb4]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 ++ switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb17]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 + } + + bb3: { +- falseEdge -> [real: bb13, imaginary: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+2:25: +2:38 +- } +- +- bb4: { +- switchInt((_2.0: bool)) -> [0: bb6, otherwise: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 +- } +- +- bb5: { +- falseEdge -> [real: bb20, imaginary: bb6]; // scope 0 at $DIR/match_arm_scopes.rs:+3:9: +3:21 +- } +- +- bb6: { + StorageLive(_15); // scope 0 at $DIR/match_arm_scopes.rs:+3:32: +3:33 + _15 = (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+3:32: +3:33 + StorageLive(_16); // scope 0 at $DIR/match_arm_scopes.rs:+3:35: +3:36 + _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+3:35: +3:36 +- goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 ++ goto -> bb16; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 + } + +- bb7: { ++ bb4: { + _0 = const 1_i32; // scope 1 at $DIR/match_arm_scopes.rs:+2:77: +2:78 +- drop(_7) -> [return: bb18, unwind: bb25]; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 ++ drop(_7) -> [return: bb15, unwind: bb22]; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + } + +- bb8: { ++ bb5: { + StorageLive(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + _6 = &(_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + StorageLive(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 +- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 +- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 + StorageLive(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + StorageLive(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 + _10 = _1; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 +- switchInt(move _10) -> [0: bb10, otherwise: bb9]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 ++ switchInt(move _10) -> [0: bb7, otherwise: bb6]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 + } + +- bb9: { ++ bb6: { + _0 = const 3_i32; // scope 0 at $DIR/match_arm_scopes.rs:+2:59: +2:60 + StorageDead(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- goto -> bb23; // scope 0 at no-location ++ goto -> bb20; // scope 0 at no-location + } + +- bb10: { ++ bb7: { + _9 = (*_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:70: +2:71 +- switchInt(move _9) -> [0: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ switchInt(move _9) -> [0: bb9, otherwise: bb8]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + } + +- bb11: { ++ bb8: { + StorageDead(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageLive(_5); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + _5 = (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + StorageLive(_7); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 +- goto -> bb7; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 ++ goto -> bb4; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 + } + +- bb12: { ++ bb9: { + StorageDead(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 +- falseEdge -> [real: bb2, imaginary: bb3]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ goto -> bb1; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + } + +- bb13: { ++ bb10: { + StorageLive(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27 + _6 = &(_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27 + StorageLive(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37 + _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37 +- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 +- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 + StorageLive(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + StorageLive(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 + _13 = _1; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 +- switchInt(move _13) -> [0: bb15, otherwise: bb14]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 ++ switchInt(move _13) -> [0: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 + } + +- bb14: { ++ bb11: { + _0 = const 3_i32; // scope 0 at $DIR/match_arm_scopes.rs:+2:59: +2:60 + StorageDead(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- goto -> bb23; // scope 0 at no-location ++ goto -> bb20; // scope 0 at no-location + } + +- bb15: { ++ bb12: { + _12 = (*_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:70: +2:71 +- switchInt(move _12) -> [0: bb17, otherwise: bb16]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ switchInt(move _12) -> [0: bb14, otherwise: bb13]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + } + +- bb16: { ++ bb13: { + StorageDead(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageLive(_5); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27 + _5 = (_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27 + StorageLive(_7); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37 + _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37 +- goto -> bb7; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 ++ goto -> bb4; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 + } + +- bb17: { ++ bb14: { + StorageDead(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 +- falseEdge -> [real: bb4, imaginary: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ goto -> bb2; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + } + +- bb18: { ++ bb15: { + StorageDead(_7); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_5); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 +- goto -> bb22; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 ++ goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + } + +- bb19: { ++ bb16: { + _0 = const 2_i32; // scope 2 at $DIR/match_arm_scopes.rs:+3:41: +3:42 +- drop(_16) -> [return: bb21, unwind: bb25]; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 ++ drop(_16) -> [return: bb18, unwind: bb22]; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 + } + +- bb20: { ++ bb17: { + StorageLive(_15); // scope 0 at $DIR/match_arm_scopes.rs:+3:16: +3:17 + _15 = (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+3:16: +3:17 + StorageLive(_16); // scope 0 at $DIR/match_arm_scopes.rs:+3:19: +3:20 + _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+3:19: +3:20 +- goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 ++ goto -> bb16; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 + } + +- bb21: { ++ bb18: { + StorageDead(_16); // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 + StorageDead(_15); // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 +- goto -> bb22; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 ++ goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 + } + +- bb22: { +- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 ++ bb19: { ++ goto -> bb26; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 + } + +- bb23: { ++ bb20: { + StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 +- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 ++ drop(_2) -> [return: bb21, unwind: bb23]; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 + } + +- bb24: { ++ bb21: { + return; // scope 0 at $DIR/match_arm_scopes.rs:+5:2: +5:2 + } + +- bb25 (cleanup): { +- drop(_2) -> [return: bb26, unwind terminate]; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 ++ bb22 (cleanup): { ++ goto -> bb27; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 + } + +- bb26 (cleanup): { ++ bb23 (cleanup): { + resume; // scope 0 at $DIR/match_arm_scopes.rs:+0:1: +5:2 ++ } ++ ++ bb24: { ++ goto -> bb21; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 ++ } ++ ++ bb25 (cleanup): { ++ goto -> bb23; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 ++ } ++ ++ bb26: { ++ goto -> bb24; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 ++ } ++ ++ bb27 (cleanup): { ++ goto -> bb23; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 + } + } + diff --git a/tests/mir-opt/match_arm_scopes.rs b/tests/mir-opt/match_arm_scopes.rs index 7b7de7788c2f6..e0249de860135 100644 --- a/tests/mir-opt/match_arm_scopes.rs +++ b/tests/mir-opt/match_arm_scopes.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Test that StorageDead and Drops are generated properly for bindings in // matches: // * The MIR should only contain a single drop of `s` and `t`: at the end diff --git a/tests/mir-opt/no_drop_for_inactive_variant.rs b/tests/mir-opt/no_drop_for_inactive_variant.rs index 34e2b1a134ff9..adbd1f353fcf9 100644 --- a/tests/mir-opt/no_drop_for_inactive_variant.rs +++ b/tests/mir-opt/no_drop_for_inactive_variant.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Ensure that there are no drop terminators in `unwrap` (except the one along the cleanup // path). diff --git a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir new file mode 100644 index 0000000000000..90b547913e48e --- /dev/null +++ b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir @@ -0,0 +1,44 @@ +// MIR for `unwrap` after SimplifyCfg-elaborate-drops + +fn unwrap(_1: Option) -> T { + debug opt => _1; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+0:14: +0:17 + let mut _0: T; // return place in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+0:33: +0:34 + let mut _2: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:9: +2:16 + let _3: T; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15 + let mut _4: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + let mut _5: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2 + let mut _6: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2 + let mut _7: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2 + scope 1 { + debug x => _3; // in scope 1 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15 + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:11: +1:14 + switchInt(move _2) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:5: +1:14 + } + + bb1: { + StorageLive(_4); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + _4 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value() } + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + + bb2: { + unreachable; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:11: +1:14 + } + + bb3: { + StorageLive(_3); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15 + _3 = move ((_1 as Some).0: T); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15 + _0 = move _3; // scope 1 at $DIR/no_drop_for_inactive_variant.rs:+2:20: +2:21 + StorageDead(_3); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:20: +2:21 + _5 = discriminant(_1); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2 + return; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:2: +5:2 + } +} diff --git a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir rename to tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-unwind.mir diff --git a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir new file mode 100644 index 0000000000000..14b315ad9a3ea --- /dev/null +++ b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir @@ -0,0 +1,49 @@ +// MIR for `main` before ElaborateDrops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/no_spurious_drop_after_call.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:5: +1:35 + let mut _2: std::string::String; // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + let mut _3: &str; // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + let _4: &str; // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:22 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:5: +1:35 + StorageLive(_2); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + StorageLive(_3); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + StorageLive(_4); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:22 + _4 = const ""; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:22 + // mir::Constant + // + span: $DIR/no_spurious_drop_after_call.rs:9:20: 9:22 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _3 = &(*_4); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + _2 = ::to_string(move _3) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + // mir::Constant + // + span: $DIR/no_spurious_drop_after_call.rs:9:23: 9:32 + // + literal: Const { ty: for<'a> fn(&'a str) -> String {::to_string}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:33: +1:34 + _1 = std::mem::drop::(move _2) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:5: +1:35 + // mir::Constant + // + span: $DIR/no_spurious_drop_after_call.rs:9:5: 9:19 + // + literal: Const { ty: fn(String) {std::mem::drop::}, val: Value() } + } + + bb2: { + StorageDead(_2); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:34: +1:35 + StorageDead(_4); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:35: +1:36 + StorageDead(_1); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:35: +1:36 + _0 = const (); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+0:11: +2:2 + return; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+2:2: +2:2 + } + + bb3 (cleanup): { + drop(_2) -> [return: bb4, unwind terminate]; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:34: +1:35 + } + + bb4 (cleanup): { + resume; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+0:1: +2:2 + } +} diff --git a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir similarity index 100% rename from tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir rename to tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir diff --git a/tests/mir-opt/no_spurious_drop_after_call.rs b/tests/mir-opt/no_spurious_drop_after_call.rs index bb5bb9aa4e5b6..71f050502cbab 100644 --- a/tests/mir-opt/no_spurious_drop_after_call.rs +++ b/tests/mir-opt/no_spurious_drop_after_call.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Test that after the call to `std::mem::drop` we do not generate a // MIR drop of the argument. (We used to have a `DROP(_2)` in the code diff --git a/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-abort.diff b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-abort.diff new file mode 100644 index 0000000000000..45b2efa3fe25e --- /dev/null +++ b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-abort.diff @@ -0,0 +1,43 @@ +- // MIR for `nrvo` before RenameReturnPlace ++ // MIR for `nrvo` after RenameReturnPlace + + fn nrvo(_1: for<'a> fn(&'a mut [u8; 1024])) -> [u8; 1024] { + debug init => _1; // in scope 0 at $DIR/nrvo_simple.rs:+0:9: +0:13 +- let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo_simple.rs:+0:39: +0:49 ++ let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo_simple.rs:+1:9: +1:16 + let mut _2: [u8; 1024]; // in scope 0 at $DIR/nrvo_simple.rs:+1:9: +1:16 + let _3: (); // in scope 0 at $DIR/nrvo_simple.rs:+2:5: +2:19 + let mut _4: for<'a> fn(&'a mut [u8; 1024]); // in scope 0 at $DIR/nrvo_simple.rs:+2:5: +2:9 + let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo_simple.rs:+2:10: +2:18 + let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo_simple.rs:+2:10: +2:18 + scope 1 { +- debug buf => _2; // in scope 1 at $DIR/nrvo_simple.rs:+1:9: +1:16 ++ debug buf => _0; // in scope 1 at $DIR/nrvo_simple.rs:+1:9: +1:16 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/nrvo_simple.rs:+1:9: +1:16 +- _2 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo_simple.rs:+1:19: +1:28 ++ _0 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo_simple.rs:+1:19: +1:28 + StorageLive(_3); // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:19 + StorageLive(_4); // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:9 + _4 = _1; // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:9 + StorageLive(_5); // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18 + StorageLive(_6); // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18 +- _6 = &mut _2; // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18 ++ _6 = &mut _0; // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18 + _5 = &mut (*_6); // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18 + _3 = move _4(move _5) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:19 + } + + bb1: { + StorageDead(_5); // scope 1 at $DIR/nrvo_simple.rs:+2:18: +2:19 + StorageDead(_4); // scope 1 at $DIR/nrvo_simple.rs:+2:18: +2:19 + StorageDead(_6); // scope 1 at $DIR/nrvo_simple.rs:+2:19: +2:20 + StorageDead(_3); // scope 1 at $DIR/nrvo_simple.rs:+2:19: +2:20 +- _0 = _2; // scope 1 at $DIR/nrvo_simple.rs:+3:5: +3:8 +- StorageDead(_2); // scope 0 at $DIR/nrvo_simple.rs:+4:1: +4:2 + return; // scope 0 at $DIR/nrvo_simple.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff similarity index 100% rename from tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff rename to tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff diff --git a/tests/mir-opt/nrvo_simple.rs b/tests/mir-opt/nrvo_simple.rs index 525dfe4262a46..9e822ed51d419 100644 --- a/tests/mir-opt/nrvo_simple.rs +++ b/tests/mir-opt/nrvo_simple.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: RenameReturnPlace // EMIT_MIR nrvo_simple.nrvo.RenameReturnPlace.diff diff --git a/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir new file mode 100644 index 0000000000000..f17682ae71d06 --- /dev/null +++ b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir @@ -0,0 +1,46 @@ +// MIR for `main` after SimplifyCfg-elaborate-drops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:11: +0:11 + let mut _1: Packed; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:9: +1:14 + let mut _2: Aligned; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42 + let mut _3: Droppy; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41 + let mut _4: Aligned; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29 + let mut _5: Droppy; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28 + let mut _6: Aligned; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + scope 1 { + debug x => _1; // in scope 1 at $DIR/packed_struct_drop_aligned.rs:+1:9: +1:14 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:9: +1:14 + StorageLive(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42 + StorageLive(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41 + _3 = Droppy(const 0_usize); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41 + _2 = Aligned(move _3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42 + StorageDead(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:41: +1:42 + _1 = Packed(move _2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:17: +1:43 + StorageDead(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:42: +1:43 + StorageLive(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29 + StorageLive(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28 + _5 = Droppy(const 0_usize); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28 + _4 = Aligned(move _5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29 + StorageDead(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:28: +2:29 + StorageLive(_6); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + drop(_6) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2 + return; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:2: +3:2 + } + + bb2: { + StorageDead(_6); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + StorageDead(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:28: +2:29 + _0 = const (); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:11: +3:2 + drop(_1) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2 + } +} diff --git a/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir rename to tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir diff --git a/tests/mir-opt/packed_struct_drop_aligned.rs b/tests/mir-opt/packed_struct_drop_aligned.rs index cb65242609086..f88a683535c12 100644 --- a/tests/mir-opt/packed_struct_drop_aligned.rs +++ b/tests/mir-opt/packed_struct_drop_aligned.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff new file mode 100644 index 0000000000000..eeb67c4412673 --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff @@ -0,0 +1,59 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _9: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + scope 1 { + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 2 { + debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + scope 3 { + debug z => _9; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 +- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 +- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + } + + bb1: { +- _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _6 = const 6_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 +- _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ _7 = const true; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + } + + bb2: { +- _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + _9 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.diff rename to tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff new file mode 100644 index 0000000000000..eeb67c4412673 --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff @@ -0,0 +1,59 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _9: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + scope 1 { + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 2 { + debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + scope 3 { + debug z => _9; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 +- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 +- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + } + + bb1: { +- _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _6 = const 6_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 +- _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ _7 = const true; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + } + + bb2: { +- _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + _9 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.diff rename to tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.32bit.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.32bit.panic-abort.mir similarity index 100% rename from tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.32bit.mir rename to tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.32bit.panic-abort.mir diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.32bit.panic-unwind.mir similarity index 100% rename from tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.mir rename to tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.32bit.panic-unwind.mir diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.panic-abort.mir new file mode 100644 index 0000000000000..7886bf19e0c17 --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.panic-abort.mir @@ -0,0 +1,18 @@ +// MIR for `main` after PreCodegen + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + scope 1 { + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 2 { + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 3 { + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.panic-unwind.mir new file mode 100644 index 0000000000000..7886bf19e0c17 --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.panic-unwind.mir @@ -0,0 +1,18 @@ +// MIR for `main` after PreCodegen + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + scope 1 { + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 2 { + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 3 { + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff new file mode 100644 index 0000000000000..2c0e15fc74ad5 --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff @@ -0,0 +1,71 @@ +- // MIR for `main` before ScalarReplacementOfAggregates ++ // MIR for `main` after ScalarReplacementOfAggregates + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + scope 1 { + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 2 { + debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + scope 3 { + debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + } + + bb1: { + _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _6 = Len(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + } + + bb2: { + _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 +- StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 +- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 ++ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 + nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 + StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff rename to tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff new file mode 100644 index 0000000000000..2c0e15fc74ad5 --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff @@ -0,0 +1,71 @@ +- // MIR for `main` before ScalarReplacementOfAggregates ++ // MIR for `main` after ScalarReplacementOfAggregates + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + scope 1 { + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 2 { + debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + scope 3 { + debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + } + + bb1: { + _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _6 = Len(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> [success: bb2, unwind unreachable]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + } + + bb2: { + _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 +- StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 +- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 ++ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 + nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 + StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff rename to tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.panic-abort.mir similarity index 100% rename from tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir rename to tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.panic-abort.mir diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.panic-unwind.mir similarity index 100% rename from tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir rename to tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.panic-unwind.mir diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.panic-abort.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.panic-abort.mir new file mode 100644 index 0000000000000..5bea94c7fe839 --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.panic-abort.mir @@ -0,0 +1,18 @@ +// MIR for `main` after SimplifyLocals-final + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + scope 1 { + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 2 { + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 3 { + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.panic-unwind.mir new file mode 100644 index 0000000000000..5bea94c7fe839 --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.panic-unwind.mir @@ -0,0 +1,18 @@ +// MIR for `main` after SimplifyLocals-final + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + scope 1 { + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 2 { + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 3 { + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.rs b/tests/mir-opt/pre-codegen/optimizes_into_variable.rs index bb32cd3afb140..704f8f887e3ea 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.rs +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -C overflow-checks=on struct Point { diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..d150a57a898e5 --- /dev/null +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -0,0 +1,137 @@ +// MIR for `forward_loop` after PreCodegen + +fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { + debug start => _1; // in scope 0 at $DIR/range_iter.rs:+0:21: +0:26 + debug end => _2; // in scope 0 at $DIR/range_iter.rs:+0:33: +0:36 + debug f => _3; // in scope 0 at $DIR/range_iter.rs:+0:43: +0:44 + let mut _0: (); // return place in scope 0 at $DIR/range_iter.rs:+0:60: +0:60 + let mut _4: std::ops::Range; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + let mut _5: std::ops::Range; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + let mut _6: &mut std::ops::Range; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + let mut _12: std::option::Option; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + let mut _15: isize; // in scope 0 at $DIR/range_iter.rs:+1:5: +3:6 + let mut _17: &impl Fn(u32); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:10 + let mut _18: (u32,); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:13 + let _19: (); // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + scope 1 { + debug iter => _5; // in scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + let _16: u32; // in scope 1 at $DIR/range_iter.rs:+1:9: +1:10 + scope 2 { + debug x => _16; // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10 + } + scope 4 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:22:14: 22:24 + debug self => _6; // in scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL + scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL + debug self => _6; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _7: &u32; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _8: &u32; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _11: bool; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let _13: u32; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _14: u32; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + scope 6 { + debug old => _13; // in scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + scope 7 { + } + } + scope 8 (inlined cmp::impls::::lt) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL + debug self => _7; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => _8; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _9: u32; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _10: u32; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + } + } + } + } + scope 3 (inlined as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:22:14: 22:24 + debug self => _4; // in scope 3 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + + bb0: { + _4 = std::ops::Range:: { start: _1, end: _2 }; // scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + StorageLive(_5); // scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + _5 = move _4; // scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6 + } + + bb1: { + StorageLive(_12); // scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + _6 = &mut _5; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_11); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_7); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _7 = &((*_6).0: u32); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_8); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _8 = &((*_6).1: u32); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_9); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + _9 = (*_7); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageLive(_10); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + _10 = (*_8); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + _11 = Lt(move _9, move _10); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_10); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_9); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_8); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageDead(_7); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + switchInt(move _11) -> [0: bb2, otherwise: bb3]; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb2: { + _12 = Option::::None; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + goto -> bb5; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb3: { + _13 = ((*_6).0: u32); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_14); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _14 = ::forward_unchecked(_13, const 1_usize) -> [return: bb4, unwind unreachable]; // scope 7 at $SRC_DIR/core/src/iter/range.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + literal: Const { ty: unsafe fn(u32, usize) -> u32 {::forward_unchecked}, val: Value() } + } + + bb4: { + ((*_6).0: u32) = move _14; // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageDead(_14); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _12 = Option::::Some(_13); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + goto -> bb5; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb5: { + StorageDead(_11); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _15 = discriminant(_12); // scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + } + + bb6: { + StorageDead(_12); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6 + StorageDead(_5); // scope 0 at $DIR/range_iter.rs:+3:5: +3:6 + drop(_3) -> [return: bb7, unwind unreachable]; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2 + } + + bb7: { + return; // scope 0 at $DIR/range_iter.rs:+4:2: +4:2 + } + + bb8: { + _16 = ((_12 as Some).0: u32); // scope 1 at $DIR/range_iter.rs:+1:9: +1:10 + StorageLive(_17); // scope 2 at $DIR/range_iter.rs:+2:9: +2:10 + _17 = &_3; // scope 2 at $DIR/range_iter.rs:+2:9: +2:10 + StorageLive(_18); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + _18 = (_16,); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + _19 = >::call(move _17, move _18) -> [return: bb9, unwind unreachable]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + // mir::Constant + // + span: $DIR/range_iter.rs:23:9: 23:10 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> >::Output {>::call}, val: Value() } + } + + bb9: { + StorageDead(_18); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13 + StorageDead(_17); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13 + StorageDead(_12); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6 + goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6 + } + + bb10: { + unreachable; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + } +} diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir similarity index 98% rename from tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 06a4e35f1f900..28ec230619fe9 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -19,7 +19,7 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { scope 2 { debug x => _16; // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10 } - scope 4 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:21:14: 21:24 + scope 4 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:22:14: 22:24 debug self => _6; // in scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL debug self => _6; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL @@ -42,7 +42,7 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } } } - scope 3 (inlined as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:21:14: 21:24 + scope 3 (inlined as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:22:14: 22:24 debug self => _4; // in scope 3 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL } @@ -120,7 +120,7 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { _18 = (_16,); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 // mir::Constant - // + span: $DIR/range_iter.rs:22:9: 22:10 + // + span: $DIR/range_iter.rs:23:9: 23:10 // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> >::Output {>::call}, val: Value() } } diff --git a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..e242f519c5d52 --- /dev/null +++ b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir @@ -0,0 +1,87 @@ +// MIR for `inclusive_loop` after PreCodegen + +fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { + debug start => _1; // in scope 0 at $DIR/range_iter.rs:+0:23: +0:28 + debug end => _2; // in scope 0 at $DIR/range_iter.rs:+0:35: +0:38 + debug f => _3; // in scope 0 at $DIR/range_iter.rs:+0:45: +0:46 + let mut _0: (); // return place in scope 0 at $DIR/range_iter.rs:+0:62: +0:62 + let mut _4: std::ops::RangeInclusive; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + let mut _5: std::ops::RangeInclusive; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + let mut _6: &mut std::ops::RangeInclusive; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + let mut _7: std::option::Option; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + let mut _8: isize; // in scope 0 at $DIR/range_iter.rs:+1:5: +3:6 + let mut _10: &impl Fn(u32); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:10 + let mut _11: (u32,); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:13 + let _12: (); // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + scope 1 { + debug iter => _5; // in scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + let _9: u32; // in scope 1 at $DIR/range_iter.rs:+1:9: +1:10 + scope 2 { + debug x => _9; // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10 + } + scope 5 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:29:14: 29:25 + debug self => _6; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + } + scope 3 (inlined RangeInclusive::::new) { // at $DIR/range_iter.rs:29:14: 29:25 + debug start => _1; // in scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL + debug end => _2; // in scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL + } + scope 4 (inlined as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:29:14: 29:25 + debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + + bb0: { + _4 = RangeInclusive:: { start: _1, end: _2, exhausted: const false }; // scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL + StorageLive(_5); // scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + _5 = move _4; // scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6 + } + + bb1: { + StorageLive(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + _6 = &mut _5; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + _7 = as iter::range::RangeInclusiveIteratorImpl>::spec_next(_6) -> [return: bb2, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + literal: Const { ty: for<'a> fn(&'a mut RangeInclusive) -> Option< as iter::range::RangeInclusiveIteratorImpl>::Item> { as iter::range::RangeInclusiveIteratorImpl>::spec_next}, val: Value() } + } + + bb2: { + _8 = discriminant(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb7]; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + } + + bb3: { + StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6 + StorageDead(_5); // scope 0 at $DIR/range_iter.rs:+3:5: +3:6 + drop(_3) -> [return: bb4, unwind unreachable]; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2 + } + + bb4: { + return; // scope 0 at $DIR/range_iter.rs:+4:2: +4:2 + } + + bb5: { + _9 = ((_7 as Some).0: u32); // scope 1 at $DIR/range_iter.rs:+1:9: +1:10 + StorageLive(_10); // scope 2 at $DIR/range_iter.rs:+2:9: +2:10 + _10 = &_3; // scope 2 at $DIR/range_iter.rs:+2:9: +2:10 + StorageLive(_11); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + _11 = (_9,); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + _12 = >::call(move _10, move _11) -> [return: bb6, unwind unreachable]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + // mir::Constant + // + span: $DIR/range_iter.rs:30:9: 30:10 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> >::Output {>::call}, val: Value() } + } + + bb6: { + StorageDead(_11); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13 + StorageDead(_10); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13 + StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6 + goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6 + } + + bb7: { + unreachable; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + } +} diff --git a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir similarity index 97% rename from tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir index a187d650a7772..e24bcb3045dff 100644 --- a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir @@ -19,15 +19,15 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { scope 2 { debug x => _9; // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10 } - scope 5 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:28:14: 28:25 + scope 5 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:29:14: 29:25 debug self => _6; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL } } - scope 3 (inlined RangeInclusive::::new) { // at $DIR/range_iter.rs:28:14: 28:25 + scope 3 (inlined RangeInclusive::::new) { // at $DIR/range_iter.rs:29:14: 29:25 debug start => _1; // in scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL debug end => _2; // in scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL } - scope 4 (inlined as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:28:14: 28:25 + scope 4 (inlined as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:29:14: 29:25 debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL } @@ -70,7 +70,7 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { _11 = (_9,); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 _12 = >::call(move _10, move _11) -> [return: bb6, unwind: bb8]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 // mir::Constant - // + span: $DIR/range_iter.rs:29:9: 29:10 + // + span: $DIR/range_iter.rs:30:9: 30:10 // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> >::Output {>::call}, val: Value() } } diff --git a/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..347ccba28c5ad --- /dev/null +++ b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-abort.mir @@ -0,0 +1,20 @@ +// MIR for `range_inclusive_iter_next` after PreCodegen + +fn range_inclusive_iter_next(_1: &mut RangeInclusive) -> Option { + debug it => _1; // in scope 0 at $DIR/range_iter.rs:+0:34: +0:36 + let mut _0: std::option::Option; // return place in scope 0 at $DIR/range_iter.rs:+0:67: +0:78 + scope 1 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:17:8: 17:14 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb0: { + _0 = as iter::range::RangeInclusiveIteratorImpl>::spec_next(_1) -> [return: bb1, unwind unreachable]; // scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + literal: Const { ty: for<'a> fn(&'a mut RangeInclusive) -> Option< as iter::range::RangeInclusiveIteratorImpl>::Item> { as iter::range::RangeInclusiveIteratorImpl>::spec_next}, val: Value() } + } + + bb1: { + return; // scope 0 at $DIR/range_iter.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir similarity index 95% rename from tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir index d013b1b946269..e5f257d199dbd 100644 --- a/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir @@ -3,7 +3,7 @@ fn range_inclusive_iter_next(_1: &mut RangeInclusive) -> Option { debug it => _1; // in scope 0 at $DIR/range_iter.rs:+0:34: +0:36 let mut _0: std::option::Option; // return place in scope 0 at $DIR/range_iter.rs:+0:67: +0:78 - scope 1 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:16:8: 16:14 + scope 1 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:17:8: 17:14 debug self => _1; // in scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL } diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..35f85f173ea02 --- /dev/null +++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir @@ -0,0 +1,74 @@ +// MIR for `range_iter_next` after PreCodegen + +fn range_iter_next(_1: &mut std::ops::Range) -> Option { + debug it => _1; // in scope 0 at $DIR/range_iter.rs:+0:24: +0:26 + let mut _0: std::option::Option; // return place in scope 0 at $DIR/range_iter.rs:+0:48: +0:59 + scope 1 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:12:8: 12:14 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL + scope 2 (inlined as iter::range::RangeIteratorImpl>::spec_next) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL + debug self => _1; // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _2: &u32; // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _3: &u32; // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _6: bool; // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let _7: u32; // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _8: u32; // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + scope 3 { + debug old => _7; // in scope 3 at $SRC_DIR/core/src/iter/range.rs:LL:COL + scope 4 { + } + } + scope 5 (inlined cmp::impls::::lt) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL + debug self => _2; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => _3; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _4: u32; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _5: u32; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + } + } + } + + bb0: { + StorageLive(_7); // scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_6); // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_2); // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _2 = &((*_1).0: u32); // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _3 = &((*_1).1: u32); // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_4); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + _4 = (*_2); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageLive(_5); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + _5 = (*_3); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + _6 = Lt(move _4, move _5); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_5); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_4); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_3); // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageDead(_2); // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + switchInt(move _6) -> [0: bb1, otherwise: bb2]; // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb1: { + _0 = Option::::None; // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + goto -> bb4; // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb2: { + _7 = ((*_1).0: u32); // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_8); // scope 3 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _8 = ::forward_unchecked(_7, const 1_usize) -> [return: bb3, unwind unreachable]; // scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + literal: Const { ty: unsafe fn(u32, usize) -> u32 {::forward_unchecked}, val: Value() } + } + + bb3: { + ((*_1).0: u32) = move _8; // scope 3 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageDead(_8); // scope 3 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _0 = Option::::Some(_7); // scope 3 at $SRC_DIR/core/src/iter/range.rs:LL:COL + goto -> bb4; // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb4: { + StorageDead(_6); // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageDead(_7); // scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL + return; // scope 0 at $DIR/range_iter.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir similarity index 98% rename from tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir index f15722deee013..09b9539681fdc 100644 --- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir @@ -3,7 +3,7 @@ fn range_iter_next(_1: &mut std::ops::Range) -> Option { debug it => _1; // in scope 0 at $DIR/range_iter.rs:+0:24: +0:26 let mut _0: std::option::Option; // return place in scope 0 at $DIR/range_iter.rs:+0:48: +0:59 - scope 1 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:11:8: 11:14 + scope 1 (inlined iter::range::>::next) { // at $DIR/range_iter.rs:12:8: 12:14 debug self => _1; // in scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL scope 2 (inlined as iter::range::RangeIteratorImpl>::spec_next) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL debug self => _1; // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL diff --git a/tests/mir-opt/pre-codegen/range_iter.rs b/tests/mir-opt/pre-codegen/range_iter.rs index fe21d4dfde437..cabd9419e9202 100644 --- a/tests/mir-opt/pre-codegen/range_iter.rs +++ b/tests/mir-opt/pre-codegen/range_iter.rs @@ -1,6 +1,7 @@ // compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 // only-64bit // ignore-debug +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] diff --git a/tests/mir-opt/pre-codegen/slice_index.rs b/tests/mir-opt/pre-codegen/slice_index.rs index 44b45627607ef..d80bff50c31c7 100644 --- a/tests/mir-opt/pre-codegen/slice_index.rs +++ b/tests/mir-opt/pre-codegen/slice_index.rs @@ -1,6 +1,7 @@ // compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 // only-64bit // ignore-debug +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir similarity index 99% rename from tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir index 6c3062805365c..0e2821ab5fc8a 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir @@ -4,7 +4,7 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:28: +0:33 debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:47: +0:52 let mut _0: std::option::Option<&mut u32>; // return place in scope 0 at $DIR/slice_index.rs:+0:64: +0:80 - scope 1 (inlined core::slice::::get_mut::) { // at $DIR/slice_index.rs:16:11: 16:25 + scope 1 (inlined core::slice::::get_mut::) { // at $DIR/slice_index.rs:17:11: 17:25 debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL scope 2 (inlined >::get_mut) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir new file mode 100644 index 0000000000000..0e2821ab5fc8a --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,99 @@ +// MIR for `slice_get_mut_usize` after PreCodegen + +fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { + debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:28: +0:33 + debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:47: +0:52 + let mut _0: std::option::Option<&mut u32>; // return place in scope 0 at $DIR/slice_index.rs:+0:64: +0:80 + scope 1 (inlined core::slice::::get_mut::) { // at $DIR/slice_index.rs:17:11: 17:25 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + scope 2 (inlined >::get_mut) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug self => _2; // in scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug slice => _1; // in scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _3: &[u32]; // in scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _4: usize; // in scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _5: bool; // in scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _6: *mut [u32]; // in scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _8: *mut u32; // in scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _9: &mut u32; // in scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + scope 3 { + scope 4 (inlined >::get_unchecked_mut) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug self => _2; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug slice => _6; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _7: *mut u32; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL + scope 5 { + debug this => _2; // in scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + scope 6 { + scope 7 (inlined >::get_unchecked_mut::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug this => _2; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug slice => _6; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 8 (inlined ptr::mut_ptr::::len) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug self => _6; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _10: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 9 (inlined std::ptr::metadata::<[u32]>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _10; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + scope 10 { + } + } + } + } + scope 11 (inlined ptr::mut_ptr::::as_mut_ptr) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug self => _6; // in scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + } + scope 12 (inlined ptr::mut_ptr::::add) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug self => _7; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug count => _2; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 13 { + } + } + } + } + } + } + } + } + + bb0: { + StorageLive(_9); // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_4); // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _3 = &(*_1); // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _4 = Len((*_3)); // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_3); // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _5 = Lt(_2, move _4); // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_4); // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + switchInt(move _5) -> [0: bb1, otherwise: bb2]; // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + } + + bb1: { + _0 = const Option::<&mut u32>::None; // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: Option<&mut u32>, val: Value(Scalar(0x0000000000000000)) } + goto -> bb3; // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + } + + bb2: { + StorageLive(_8); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_6); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _6 = &raw mut (*_1); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_10); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _7 = _6 as *mut u32 (PtrToPtr); // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + _8 = Offset(_7, _2); // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + StorageDead(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_10); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_6); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _9 = &mut (*_8); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _0 = Option::<&mut u32>::Some(_9); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_8); // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + goto -> bb3; // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + } + + bb3: { + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_9); // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + return; // scope 0 at $DIR/slice_index.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir similarity index 99% rename from tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir index 727ccc1de5350..646d88ded5211 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir @@ -6,7 +6,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> let mut _0: &mut [u32]; // return place in scope 0 at $DIR/slice_index.rs:+0:88: +0:98 let mut _3: usize; // in scope 0 at $DIR/slice_index.rs:+1:29: +1:34 let mut _4: usize; // in scope 0 at $DIR/slice_index.rs:+1:29: +1:34 - scope 1 (inlined core::slice::::get_unchecked_mut::>) { // at $DIR/slice_index.rs:26:11: 26:35 + scope 1 (inlined core::slice::::get_unchecked_mut::>) { // at $DIR/slice_index.rs:27:11: 27:35 debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL debug index => std::ops::Range{ .0 => _3, .1 => _4, }; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL let mut _5: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir new file mode 100644 index 0000000000000..646d88ded5211 --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,123 @@ +// MIR for `slice_get_unchecked_mut_range` after PreCodegen + +fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> &mut [u32] { + debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:45: +0:50 + debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:64: +0:69 + let mut _0: &mut [u32]; // return place in scope 0 at $DIR/slice_index.rs:+0:88: +0:98 + let mut _3: usize; // in scope 0 at $DIR/slice_index.rs:+1:29: +1:34 + let mut _4: usize; // in scope 0 at $DIR/slice_index.rs:+1:29: +1:34 + scope 1 (inlined core::slice::::get_unchecked_mut::>) { // at $DIR/slice_index.rs:27:11: 27:35 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug index => std::ops::Range{ .0 => _3, .1 => _4, }; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _5: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _14: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + scope 2 { + scope 3 (inlined as SliceIndex<[u32]>>::get_unchecked_mut) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug self => std::ops::Range{ .0 => _3, .1 => _4, }; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug slice => _5; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _7: *mut u32; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _8: *mut u32; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _9: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let _16: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let _17: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + scope 4 { + debug this => std::ops::Range{ .0 => _16, .1 => _17, }; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL + scope 5 { + let _6: usize; // in scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + scope 6 { + debug new_len => _6; // in scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + scope 11 (inlined ptr::mut_ptr::::as_mut_ptr) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug self => _5; // in scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + } + scope 12 (inlined ptr::mut_ptr::::add) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug self => _7; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug count => _3; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 13 { + } + } + scope 14 (inlined slice_from_raw_parts_mut::) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug data => _8; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + debug len => _9; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + let mut _10: *mut (); // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + scope 15 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + debug self => _8; // in scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + } + scope 16 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { // at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + debug data_address => _10; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug metadata => _9; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _11: *const (); // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _12: std::ptr::metadata::PtrComponents<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _13: std::ptr::metadata::PtrRepr<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + scope 17 { + } + } + } + } + scope 7 (inlined as SliceIndex<[T]>>::get_unchecked_mut::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug this => std::ops::Range{ .0 => _16, .1 => _17, }; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug slice => _5; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 8 (inlined ptr::mut_ptr::::len) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug self => _5; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _15: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 9 (inlined std::ptr::metadata::<[u32]>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _15; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + scope 10 { + } + } + } + } + } + } + } + } + } + + bb0: { + _3 = move (_2.0: usize); // scope 0 at $DIR/slice_index.rs:+1:29: +1:34 + _4 = move (_2.1: usize); // scope 0 at $DIR/slice_index.rs:+1:29: +1:34 + StorageLive(_14); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _5 = &raw mut (*_1); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_15); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_16); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_17); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_6); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _6 = unchecked_sub::(_4, _3) -> [return: bb1, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/slice/index.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize, usize) -> usize {unchecked_sub::}, val: Value() } + } + + bb1: { + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _7 = _5 as *mut u32 (PtrToPtr); // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + _8 = Offset(_7, _3); // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + StorageDead(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_9); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _9 = _6; // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_10); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + _10 = _8 as *mut () (PtrToPtr); // scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + StorageLive(_13); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageLive(_12); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageLive(_11); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _11 = _10 as *const () (Pointer(MutToConstPointer)); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _12 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _11, metadata: _9 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_11); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _13 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _12 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_12); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _14 = (_13.1: *mut [u32]); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_13); // scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_10); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_9); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_6); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_17); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_16); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_15); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _0 = &mut (*_14); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_14); // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + return; // scope 0 at $DIR/slice_index.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..4739693d2597f --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-abort.mir @@ -0,0 +1,26 @@ +// MIR for `slice_index_range` after PreCodegen + +fn slice_index_range(_1: &[u32], _2: std::ops::Range) -> &[u32] { + debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:26: +0:31 + debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:41: +0:46 + let mut _0: &[u32]; // return place in scope 0 at $DIR/slice_index.rs:+0:65: +0:71 + scope 1 (inlined #[track_caller] core::slice::index::> for [u32]>::index) { // at $DIR/slice_index.rs:22:6: 22:18 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let _3: &[u32]; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + } + + bb0: { + StorageLive(_3); // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _3 = as SliceIndex<[u32]>>::index(move _2, _1) -> [return: bb1, unwind unreachable]; // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/slice/index.rs:LL:COL + // + literal: Const { ty: for<'a> fn(std::ops::Range, &'a [u32]) -> &'a as SliceIndex<[u32]>>::Output { as SliceIndex<[u32]>>::index}, val: Value() } + } + + bb1: { + _0 = _3; // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_3); // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + return; // scope 0 at $DIR/slice_index.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir similarity index 98% rename from tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir index dcf79a4a4e7fd..3136282c82781 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir @@ -4,7 +4,7 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range) -> &[u32] { debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:26: +0:31 debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:41: +0:46 let mut _0: &[u32]; // return place in scope 0 at $DIR/slice_index.rs:+0:65: +0:71 - scope 1 (inlined #[track_caller] core::slice::index::> for [u32]>::index) { // at $DIR/slice_index.rs:21:6: 21:18 + scope 1 (inlined #[track_caller] core::slice::index::> for [u32]>::index) { // at $DIR/slice_index.rs:22:6: 22:18 debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL let _3: &[u32]; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..d3a64d5feb530 --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir @@ -0,0 +1,20 @@ +// MIR for `slice_index_usize` after PreCodegen + +fn slice_index_usize(_1: &[u32], _2: usize) -> u32 { + debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:26: +0:31 + debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:41: +0:46 + let mut _0: u32; // return place in scope 0 at $DIR/slice_index.rs:+0:58: +0:61 + let mut _3: usize; // in scope 0 at $DIR/slice_index.rs:+1:5: +1:17 + let mut _4: bool; // in scope 0 at $DIR/slice_index.rs:+1:5: +1:17 + + bb0: { + _3 = Len((*_1)); // scope 0 at $DIR/slice_index.rs:+1:5: +1:17 + _4 = Lt(_2, _3); // scope 0 at $DIR/slice_index.rs:+1:5: +1:17 + assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind unreachable]; // scope 0 at $DIR/slice_index.rs:+1:5: +1:17 + } + + bb1: { + _0 = (*_1)[_2]; // scope 0 at $DIR/slice_index.rs:+1:5: +1:17 + return; // scope 0 at $DIR/slice_index.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..e1446291bff52 --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -0,0 +1,205 @@ +// MIR for `enumerated_loop` after PreCodegen + +fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { + debug slice => _1; // in scope 0 at $DIR/slice_iter.rs:+0:31: +0:36 + debug f => _2; // in scope 0 at $DIR/slice_iter.rs:+0:47: +0:48 + let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:70: +0:70 + let mut _13: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:19: +1:31 + let mut _14: std::iter::Enumerate>; // in scope 0 at $DIR/slice_iter.rs:+1:19: +1:43 + let mut _15: std::iter::Enumerate>; // in scope 0 at $DIR/slice_iter.rs:+1:19: +1:43 + let mut _16: &mut std::iter::Enumerate>; // in scope 0 at $DIR/slice_iter.rs:+1:19: +1:43 + let mut _17: std::option::Option<(usize, &T)>; // in scope 0 at $DIR/slice_iter.rs:+1:19: +1:43 + let mut _18: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6 + let mut _21: &impl Fn(usize, &T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10 + let mut _22: (usize, &T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:16 + let _23: (); // in scope 0 at $DIR/slice_iter.rs:+1:19: +1:43 + scope 1 { + debug iter => _15; // in scope 1 at $DIR/slice_iter.rs:+1:19: +1:43 + let _19: usize; // in scope 1 at $DIR/slice_iter.rs:+1:10: +1:11 + let _20: &T; // in scope 1 at $DIR/slice_iter.rs:+1:13: +1:14 + scope 2 { + debug i => _19; // in scope 2 at $DIR/slice_iter.rs:+1:10: +1:11 + debug x => _20; // in scope 2 at $DIR/slice_iter.rs:+1:13: +1:14 + } + } + scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:43:25: 43:31 + debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let _4: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _5: bool; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _6: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _8: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _9: *mut T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _11: std::ptr::NonNull; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _12: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 5 { + debug ptr => _4; // in scope 5 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 6 { + let _7: *const T; // in scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 7 { + debug end => _7; // in scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 13 (inlined NonNull::::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug ptr => _9; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _10: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + scope 14 { + scope 15 (inlined NonNull::::new_unchecked::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug ptr => _9; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 16 (inlined ptr::mut_ptr::::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + debug self => _9; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _24: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 17 { + scope 18 (inlined ptr::mut_ptr::::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _24; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 19 (inlined ptr::mut_ptr::::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _24; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 20 { + scope 21 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _24; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + } + } + } + } + } + } + } + } + } + } + scope 9 (inlined invalid::) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug addr => _8; // in scope 9 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + scope 10 { + } + } + scope 11 (inlined ptr::const_ptr::::add) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _4; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + debug count => _6; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + scope 12 { + } + } + } + } + scope 8 (inlined core::slice::::as_ptr) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _1; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _3: *const [T]; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + } + } + } + scope 22 (inlined as Iterator>::enumerate) { // at $DIR/slice_iter.rs:43:32: 43:43 + debug self => _13; // in scope 22 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + scope 23 (inlined Enumerate::>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + debug iter => _13; // in scope 23 at $SRC_DIR/core/src/iter/adapters/enumerate.rs:LL:COL + } + } + scope 24 (inlined > as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:43:19: 43:43 + debug self => _14; // in scope 24 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + + bb0: { + StorageLive(_13); // scope 0 at $DIR/slice_iter.rs:+1:19: +1:31 + StorageLive(_4); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_3); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _3 = &raw const (*_1); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _4 = move _3 as *const T (PtrToPtr); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_3); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_7); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_5); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _5 = const _; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + switchInt(move _5) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb1: { + StorageLive(_6); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _6 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _7 = Offset(_4, _6); // scope 12 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + StorageDead(_6); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb3; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb2: { + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _8 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _7 = _8 as *const T (Transmute); // scope 10 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb3; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb3: { + StorageDead(_5); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_11); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_9); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _9 = _4 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_10); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _10 = _9 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + _11 = NonNull:: { pointer: _10 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + StorageDead(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_10); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_9); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_12); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _12 = _7; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _13 = std::slice::Iter::<'_, T> { ptr: move _11, end: move _12, _marker: const ZeroSized: PhantomData<&T> }; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: PhantomData<&T>, val: Value() } + // adt + // + user_ty: UserType(1) + StorageDead(_12); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_11); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_7); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_4); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _14 = Enumerate::> { iter: move _13, count: const 0_usize }; // scope 23 at $SRC_DIR/core/src/iter/adapters/enumerate.rs:LL:COL + StorageDead(_13); // scope 0 at $DIR/slice_iter.rs:+1:42: +1:43 + StorageLive(_15); // scope 0 at $DIR/slice_iter.rs:+1:19: +1:43 + _15 = move _14; // scope 0 at $DIR/slice_iter.rs:+1:19: +1:43 + goto -> bb4; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 + } + + bb4: { + StorageLive(_17); // scope 1 at $DIR/slice_iter.rs:+1:19: +1:43 + _16 = &mut _15; // scope 1 at $DIR/slice_iter.rs:+1:19: +1:43 + _17 = > as Iterator>::next(_16) -> [return: bb5, unwind unreachable]; // scope 1 at $DIR/slice_iter.rs:+1:19: +1:43 + // mir::Constant + // + span: $DIR/slice_iter.rs:43:19: 43:43 + // + literal: Const { ty: for<'a> fn(&'a mut Enumerate>) -> Option<> as Iterator>::Item> {> as Iterator>::next}, val: Value() } + } + + bb5: { + _18 = discriminant(_17); // scope 1 at $DIR/slice_iter.rs:+1:19: +1:43 + switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10]; // scope 1 at $DIR/slice_iter.rs:+1:19: +1:43 + } + + bb6: { + StorageDead(_17); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_15); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 + drop(_2) -> [return: bb7, unwind unreachable]; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2 + } + + bb7: { + return; // scope 0 at $DIR/slice_iter.rs:+4:2: +4:2 + } + + bb8: { + _19 = (((_17 as Some).0: (usize, &T)).0: usize); // scope 1 at $DIR/slice_iter.rs:+1:10: +1:11 + _20 = (((_17 as Some).0: (usize, &T)).1: &T); // scope 1 at $DIR/slice_iter.rs:+1:13: +1:14 + StorageLive(_21); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + _21 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + StorageLive(_22); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:16 + _22 = (_19, _20); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:16 + _23 = >::call(move _21, move _22) -> [return: bb9, unwind unreachable]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:16 + // mir::Constant + // + span: $DIR/slice_iter.rs:44:9: 44:10 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(usize, &T), (usize, &T)) -> >::Output {>::call}, val: Value() } + } + + bb9: { + StorageDead(_22); // scope 2 at $DIR/slice_iter.rs:+2:15: +2:16 + StorageDead(_21); // scope 2 at $DIR/slice_iter.rs:+2:15: +2:16 + StorageDead(_17); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + goto -> bb4; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 + } + + bb10: { + unreachable; // scope 1 at $DIR/slice_iter.rs:+1:19: +1:43 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir similarity index 98% rename from tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 4dd11c1e52953..f35ea0fa05742 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -22,7 +22,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug x => _20; // in scope 2 at $DIR/slice_iter.rs:+1:13: +1:14 } } - scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:42:25: 42:31 + scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:43:25: 43:31 debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL @@ -85,13 +85,13 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } } - scope 22 (inlined as Iterator>::enumerate) { // at $DIR/slice_iter.rs:42:32: 42:43 + scope 22 (inlined as Iterator>::enumerate) { // at $DIR/slice_iter.rs:43:32: 43:43 debug self => _13; // in scope 22 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL scope 23 (inlined Enumerate::>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL debug iter => _13; // in scope 23 at $SRC_DIR/core/src/iter/adapters/enumerate.rs:LL:COL } } - scope 24 (inlined > as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:42:19: 42:43 + scope 24 (inlined > as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:43:19: 43:43 debug self => _14; // in scope 24 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL } @@ -160,7 +160,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _16 = &mut _15; // scope 1 at $DIR/slice_iter.rs:+1:19: +1:43 _17 = > as Iterator>::next(_16) -> [return: bb5, unwind: bb11]; // scope 1 at $DIR/slice_iter.rs:+1:19: +1:43 // mir::Constant - // + span: $DIR/slice_iter.rs:42:19: 42:43 + // + span: $DIR/slice_iter.rs:43:19: 43:43 // + literal: Const { ty: for<'a> fn(&'a mut Enumerate>) -> Option<> as Iterator>::Item> {> as Iterator>::next}, val: Value() } } @@ -188,7 +188,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _22 = (_19, _20); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:16 _23 = >::call(move _21, move _22) -> [return: bb9, unwind: bb11]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:16 // mir::Constant - // + span: $DIR/slice_iter.rs:43:9: 43:10 + // + span: $DIR/slice_iter.rs:44:9: 44:10 // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(usize, &T), (usize, &T)) -> >::Output {>::call}, val: Value() } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..1ffda32509e6c --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -0,0 +1,192 @@ +// MIR for `forward_loop` after PreCodegen + +fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { + debug slice => _1; // in scope 0 at $DIR/slice_iter.rs:+0:28: +0:33 + debug f => _2; // in scope 0 at $DIR/slice_iter.rs:+0:44: +0:45 + let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:60: +0:60 + let mut _13: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _14: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _15: &mut std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _16: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _17: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6 + let mut _19: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10 + let mut _20: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13 + let _21: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + scope 1 { + debug iter => _14; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + let _18: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + scope 2 { + debug x => _18; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 + } + } + scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:29:20: 29:26 + debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let _4: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _5: bool; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _6: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _8: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _9: *mut T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _11: std::ptr::NonNull; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _12: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 5 { + debug ptr => _4; // in scope 5 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 6 { + let _7: *const T; // in scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 7 { + debug end => _7; // in scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 13 (inlined NonNull::::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug ptr => _9; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _10: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + scope 14 { + scope 15 (inlined NonNull::::new_unchecked::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug ptr => _9; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 16 (inlined ptr::mut_ptr::::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + debug self => _9; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _22: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 17 { + scope 18 (inlined ptr::mut_ptr::::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _22; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 19 (inlined ptr::mut_ptr::::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _22; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 20 { + scope 21 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _22; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + } + } + } + } + } + } + } + } + } + } + scope 9 (inlined invalid::) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug addr => _8; // in scope 9 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + scope 10 { + } + } + scope 11 (inlined ptr::const_ptr::::add) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _4; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + debug count => _6; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + scope 12 { + } + } + } + } + scope 8 (inlined core::slice::::as_ptr) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _1; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _3: *const [T]; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + } + } + } + scope 22 (inlined as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:29:14: 29:26 + debug self => _13; // in scope 22 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + + bb0: { + StorageLive(_4); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_3); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _3 = &raw const (*_1); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _4 = move _3 as *const T (PtrToPtr); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_3); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_7); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_5); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _5 = const _; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + switchInt(move _5) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb1: { + StorageLive(_6); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _6 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _7 = Offset(_4, _6); // scope 12 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + StorageDead(_6); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb3; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb2: { + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _8 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _7 = _8 as *const T (Transmute); // scope 10 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb3; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb3: { + StorageDead(_5); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_11); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_9); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _9 = _4 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_10); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _10 = _9 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + _11 = NonNull:: { pointer: _10 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + StorageDead(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_10); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_9); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_12); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _12 = _7; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _13 = std::slice::Iter::<'_, T> { ptr: move _11, end: move _12, _marker: const ZeroSized: PhantomData<&T> }; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: PhantomData<&T>, val: Value() } + // adt + // + user_ty: UserType(1) + StorageDead(_12); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_11); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_7); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_4); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_14); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + _14 = move _13; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + goto -> bb4; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 + } + + bb4: { + StorageLive(_16); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + _15 = &mut _14; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + _16 = as Iterator>::next(_15) -> [return: bb5, unwind unreachable]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + // mir::Constant + // + span: $DIR/slice_iter.rs:29:14: 29:26 + // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option< as Iterator>::Item> { as Iterator>::next}, val: Value() } + } + + bb5: { + _17 = discriminant(_16); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + } + + bb6: { + StorageDead(_16); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_14); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 + drop(_2) -> [return: bb7, unwind unreachable]; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2 + } + + bb7: { + return; // scope 0 at $DIR/slice_iter.rs:+4:2: +4:2 + } + + bb8: { + _18 = ((_16 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + StorageLive(_19); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + _19 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + StorageLive(_20); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _20 = (_18,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _21 = >::call(move _19, move _20) -> [return: bb9, unwind unreachable]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + // mir::Constant + // + span: $DIR/slice_iter.rs:30:9: 30:10 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> >::Output {>::call}, val: Value() } + } + + bb9: { + StorageDead(_20); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 + StorageDead(_19); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 + StorageDead(_16); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + goto -> bb4; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 + } + + bb10: { + unreachable; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir similarity index 99% rename from tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 0c18fb84bcd74..899e5f58a988b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -19,7 +19,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug x => _18; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 } } - scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:28:20: 28:26 + scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:29:20: 29:26 debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL @@ -82,7 +82,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } } - scope 22 (inlined as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:28:14: 28:26 + scope 22 (inlined as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:29:14: 29:26 debug self => _13; // in scope 22 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL } @@ -148,7 +148,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _15 = &mut _14; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 _16 = as Iterator>::next(_15) -> [return: bb5, unwind: bb11]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 // mir::Constant - // + span: $DIR/slice_iter.rs:28:14: 28:26 + // + span: $DIR/slice_iter.rs:29:14: 29:26 // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option< as Iterator>::Item> { as Iterator>::next}, val: Value() } } @@ -175,7 +175,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _20 = (_18,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 // mir::Constant - // + span: $DIR/slice_iter.rs:29:9: 29:10 + // + span: $DIR/slice_iter.rs:30:9: 30:10 // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> >::Output {>::call}, val: Value() } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..119b68bdac402 --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir @@ -0,0 +1,153 @@ +// MIR for `range_loop` after PreCodegen + +fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { + debug slice => _1; // in scope 0 at $DIR/slice_iter.rs:+0:26: +0:31 + debug f => _2; // in scope 0 at $DIR/slice_iter.rs:+0:42: +0:43 + let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:65: +0:65 + let mut _3: usize; // in scope 0 at $DIR/slice_iter.rs:+1:17: +1:28 + let mut _4: std::ops::Range; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:28 + let mut _5: std::ops::Range; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:28 + let mut _6: &mut std::ops::Range; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:28 + let mut _12: std::option::Option; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:28 + let mut _15: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +4:6 + let mut _17: usize; // in scope 0 at $DIR/slice_iter.rs:+2:18: +2:26 + let mut _18: bool; // in scope 0 at $DIR/slice_iter.rs:+2:18: +2:26 + let mut _20: &impl Fn(usize, &T); // in scope 0 at $DIR/slice_iter.rs:+3:9: +3:10 + let mut _21: (usize, &T); // in scope 0 at $DIR/slice_iter.rs:+3:9: +3:16 + let _22: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:28 + scope 1 { + debug iter => _5; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:28 + let _16: usize; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + scope 2 { + debug i => _16; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 + let _19: &T; // in scope 2 at $DIR/slice_iter.rs:+2:13: +2:14 + scope 3 { + debug x => _19; // in scope 3 at $DIR/slice_iter.rs:+2:13: +2:14 + } + } + scope 5 (inlined iter::range::>::next) { // at $DIR/slice_iter.rs:50:14: 50:28 + debug self => _6; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + scope 6 (inlined as iter::range::RangeIteratorImpl>::spec_next) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL + debug self => _6; // in scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _7: &usize; // in scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _8: &usize; // in scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _11: bool; // in scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let _13: usize; // in scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _14: usize; // in scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + scope 7 { + debug old => _13; // in scope 7 at $SRC_DIR/core/src/iter/range.rs:LL:COL + scope 8 { + } + } + scope 9 (inlined cmp::impls::::lt) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL + debug self => _7; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => _8; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _9: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _10: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + } + } + } + } + scope 4 (inlined as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:50:14: 50:28 + debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/slice_iter.rs:+1:17: +1:28 + _3 = Len((*_1)); // scope 0 at $DIR/slice_iter.rs:+1:17: +1:28 + _4 = std::ops::Range:: { start: const 0_usize, end: move _3 }; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:28 + StorageDead(_3); // scope 0 at $DIR/slice_iter.rs:+1:27: +1:28 + StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:28 + _5 = move _4; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:28 + goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +4:6 + } + + bb1: { + StorageLive(_12); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:28 + _6 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:28 + StorageLive(_13); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_11); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_7); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _7 = &((*_6).0: usize); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _8 = &((*_6).1: usize); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_9); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + _9 = (*_7); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageLive(_10); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + _10 = (*_8); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + _11 = Lt(move _9, move _10); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_10); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_9); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageDead(_7); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + switchInt(move _11) -> [0: bb2, otherwise: bb3]; // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb2: { + _12 = Option::::None; // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + goto -> bb5; // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb3: { + _13 = ((*_6).0: usize); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageLive(_14); // scope 7 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _14 = ::forward_unchecked(_13, const 1_usize) -> [return: bb4, unwind unreachable]; // scope 8 at $SRC_DIR/core/src/iter/range.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + literal: Const { ty: unsafe fn(usize, usize) -> usize {::forward_unchecked}, val: Value() } + } + + bb4: { + ((*_6).0: usize) = move _14; // scope 7 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageDead(_14); // scope 7 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _12 = Option::::Some(_13); // scope 7 at $SRC_DIR/core/src/iter/range.rs:LL:COL + goto -> bb5; // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb5: { + StorageDead(_11); // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL + StorageDead(_13); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _15 = discriminant(_12); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:28 + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb11]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:28 + } + + bb6: { + StorageDead(_12); // scope 1 at $DIR/slice_iter.rs:+4:5: +4:6 + StorageDead(_5); // scope 0 at $DIR/slice_iter.rs:+4:5: +4:6 + drop(_2) -> [return: bb7, unwind unreachable]; // scope 0 at $DIR/slice_iter.rs:+5:1: +5:2 + } + + bb7: { + return; // scope 0 at $DIR/slice_iter.rs:+5:2: +5:2 + } + + bb8: { + _16 = ((_12 as Some).0: usize); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + _17 = Len((*_1)); // scope 2 at $DIR/slice_iter.rs:+2:18: +2:26 + _18 = Lt(_16, _17); // scope 2 at $DIR/slice_iter.rs:+2:18: +2:26 + assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, _16) -> [success: bb9, unwind unreachable]; // scope 2 at $DIR/slice_iter.rs:+2:18: +2:26 + } + + bb9: { + _19 = &(*_1)[_16]; // scope 2 at $DIR/slice_iter.rs:+2:17: +2:26 + StorageLive(_20); // scope 3 at $DIR/slice_iter.rs:+3:9: +3:10 + _20 = &_2; // scope 3 at $DIR/slice_iter.rs:+3:9: +3:10 + StorageLive(_21); // scope 3 at $DIR/slice_iter.rs:+3:9: +3:16 + _21 = (_16, _19); // scope 3 at $DIR/slice_iter.rs:+3:9: +3:16 + _22 = >::call(move _20, move _21) -> [return: bb10, unwind unreachable]; // scope 3 at $DIR/slice_iter.rs:+3:9: +3:16 + // mir::Constant + // + span: $DIR/slice_iter.rs:52:9: 52:10 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(usize, &T), (usize, &T)) -> >::Output {>::call}, val: Value() } + } + + bb10: { + StorageDead(_21); // scope 3 at $DIR/slice_iter.rs:+3:15: +3:16 + StorageDead(_20); // scope 3 at $DIR/slice_iter.rs:+3:15: +3:16 + StorageDead(_12); // scope 1 at $DIR/slice_iter.rs:+4:5: +4:6 + goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +4:6 + } + + bb11: { + unreachable; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:28 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir similarity index 98% rename from tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir index 870496f14ea90..2ec1ffd875c73 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir @@ -25,7 +25,7 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug x => _19; // in scope 3 at $DIR/slice_iter.rs:+2:13: +2:14 } } - scope 5 (inlined iter::range::>::next) { // at $DIR/slice_iter.rs:49:14: 49:28 + scope 5 (inlined iter::range::>::next) { // at $DIR/slice_iter.rs:50:14: 50:28 debug self => _6; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL scope 6 (inlined as iter::range::RangeIteratorImpl>::spec_next) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL debug self => _6; // in scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL @@ -48,7 +48,7 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } } - scope 4 (inlined as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:49:14: 49:28 + scope 4 (inlined as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:50:14: 50:28 debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL } @@ -136,7 +136,7 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _21 = (_16, _19); // scope 3 at $DIR/slice_iter.rs:+3:9: +3:16 _22 = >::call(move _20, move _21) -> [return: bb10, unwind: bb12]; // scope 3 at $DIR/slice_iter.rs:+3:9: +3:16 // mir::Constant - // + span: $DIR/slice_iter.rs:51:9: 51:10 + // + span: $DIR/slice_iter.rs:52:9: 52:10 // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(usize, &T), (usize, &T)) -> >::Output {>::call}, val: Value() } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..bb76212c8bab4 --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -0,0 +1,209 @@ +// MIR for `reverse_loop` after PreCodegen + +fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { + debug slice => _1; // in scope 0 at $DIR/slice_iter.rs:+0:28: +0:33 + debug f => _2; // in scope 0 at $DIR/slice_iter.rs:+0:44: +0:45 + let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:60: +0:60 + let mut _13: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _14: std::iter::Rev>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + let mut _15: std::iter::Rev>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + let mut _16: &mut std::iter::Rev>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + let mut _18: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + let mut _19: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6 + let mut _21: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10 + let mut _22: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13 + let _23: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + scope 1 { + debug iter => _15; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + let _20: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + scope 2 { + debug x => _20; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 + } + scope 25 (inlined > as Iterator>::next) { // at $DIR/slice_iter.rs:36:14: 36:32 + debug self => _16; // in scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + let mut _17: &mut std::slice::Iter<'_, T>; // in scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + } + } + scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:36:20: 36:26 + debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let _4: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _5: bool; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _6: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _8: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _9: *mut T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _11: std::ptr::NonNull; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _12: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 5 { + debug ptr => _4; // in scope 5 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 6 { + let _7: *const T; // in scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 7 { + debug end => _7; // in scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 13 (inlined NonNull::::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug ptr => _9; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _10: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + scope 14 { + scope 15 (inlined NonNull::::new_unchecked::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug ptr => _9; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 16 (inlined ptr::mut_ptr::::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + debug self => _9; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _24: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 17 { + scope 18 (inlined ptr::mut_ptr::::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _24; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 19 (inlined ptr::mut_ptr::::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _24; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 20 { + scope 21 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _24; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + } + } + } + } + } + } + } + } + } + } + scope 9 (inlined invalid::) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug addr => _8; // in scope 9 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + scope 10 { + } + } + scope 11 (inlined ptr::const_ptr::::add) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _4; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + debug count => _6; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + scope 12 { + } + } + } + } + scope 8 (inlined core::slice::::as_ptr) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _1; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _3: *const [T]; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + } + } + } + scope 22 (inlined as Iterator>::rev) { // at $DIR/slice_iter.rs:36:27: 36:32 + debug self => _13; // in scope 22 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + scope 23 (inlined Rev::>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + debug iter => _13; // in scope 23 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + } + } + scope 24 (inlined > as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:36:14: 36:32 + debug self => _14; // in scope 24 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + + bb0: { + StorageLive(_13); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + StorageLive(_4); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_3); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _3 = &raw const (*_1); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _4 = move _3 as *const T (PtrToPtr); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_3); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_7); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_5); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _5 = const _; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + switchInt(move _5) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb1: { + StorageLive(_6); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _6 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _7 = Offset(_4, _6); // scope 12 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + StorageDead(_6); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb3; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb2: { + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _8 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _7 = _8 as *const T (Transmute); // scope 10 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb3; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb3: { + StorageDead(_5); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_11); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_9); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _9 = _4 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_10); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _10 = _9 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + _11 = NonNull:: { pointer: _10 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + StorageDead(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_10); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_9); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_12); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _12 = _7; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _13 = std::slice::Iter::<'_, T> { ptr: move _11, end: move _12, _marker: const ZeroSized: PhantomData<&T> }; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: PhantomData<&T>, val: Value() } + // adt + // + user_ty: UserType(1) + StorageDead(_12); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_11); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_7); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_4); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _14 = Rev::> { iter: move _13 }; // scope 23 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + StorageDead(_13); // scope 0 at $DIR/slice_iter.rs:+1:31: +1:32 + StorageLive(_15); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + _15 = move _14; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + goto -> bb4; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 + } + + bb4: { + StorageLive(_18); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + _16 = &mut _15; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + StorageLive(_17); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + _17 = &mut ((*_16).0: std::slice::Iter<'_, T>); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + _18 = as DoubleEndedIterator>::next_back(move _17) -> [return: bb5, unwind unreachable]; // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option< as Iterator>::Item> { as DoubleEndedIterator>::next_back}, val: Value() } + } + + bb5: { + StorageDead(_17); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + _19 = discriminant(_18); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + switchInt(move _19) -> [0: bb6, 1: bb8, otherwise: bb10]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + } + + bb6: { + StorageDead(_18); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_15); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 + drop(_2) -> [return: bb7, unwind unreachable]; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2 + } + + bb7: { + return; // scope 0 at $DIR/slice_iter.rs:+4:2: +4:2 + } + + bb8: { + _20 = ((_18 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + StorageLive(_21); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + _21 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + StorageLive(_22); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _22 = (_20,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _23 = >::call(move _21, move _22) -> [return: bb9, unwind unreachable]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + // mir::Constant + // + span: $DIR/slice_iter.rs:37:9: 37:10 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> >::Output {>::call}, val: Value() } + } + + bb9: { + StorageDead(_22); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 + StorageDead(_21); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 + StorageDead(_18); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + goto -> bb4; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 + } + + bb10: { + unreachable; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir similarity index 98% rename from tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index 1aa05cbeb9770..6058e5fba59e9 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -19,12 +19,12 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { scope 2 { debug x => _20; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 } - scope 25 (inlined > as Iterator>::next) { // at $DIR/slice_iter.rs:35:14: 35:32 + scope 25 (inlined > as Iterator>::next) { // at $DIR/slice_iter.rs:36:14: 36:32 debug self => _16; // in scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL let mut _17: &mut std::slice::Iter<'_, T>; // in scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL } } - scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:35:20: 35:26 + scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:36:20: 36:26 debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL @@ -87,13 +87,13 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } } - scope 22 (inlined as Iterator>::rev) { // at $DIR/slice_iter.rs:35:27: 35:32 + scope 22 (inlined as Iterator>::rev) { // at $DIR/slice_iter.rs:36:27: 36:32 debug self => _13; // in scope 22 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL scope 23 (inlined Rev::>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL debug iter => _13; // in scope 23 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL } } - scope 24 (inlined > as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:35:14: 35:32 + scope 24 (inlined > as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:36:14: 36:32 debug self => _14; // in scope 24 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL } @@ -192,7 +192,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _22 = (_20,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 _23 = >::call(move _21, move _22) -> [return: bb9, unwind: bb11]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 // mir::Constant - // + span: $DIR/slice_iter.rs:36:9: 36:10 + // + span: $DIR/slice_iter.rs:37:9: 37:10 // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> >::Output {>::call}, val: Value() } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.rs b/tests/mir-opt/pre-codegen/slice_iter.rs index a1cd85e753f63..4e954aa343305 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.rs +++ b/tests/mir-opt/pre-codegen/slice_iter.rs @@ -1,6 +1,7 @@ // compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 // only-64bit // ignore-debug +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..bc0257b8db23b --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir @@ -0,0 +1,17 @@ +// MIR for `slice_iter_mut_next_back` after PreCodegen + +fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { + debug it => _1; // in scope 0 at $DIR/slice_iter.rs:+0:40: +0:42 + let mut _0: std::option::Option<&mut T>; // return place in scope 0 at $DIR/slice_iter.rs:+0:80: +0:97 + + bb0: { + _0 = as DoubleEndedIterator>::next_back(_1) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/slice_iter.rs:+1:5: +1:19 + // mir::Constant + // + span: $DIR/slice_iter.rs:24:8: 24:17 + // + literal: Const { ty: for<'a> fn(&'a mut std::slice::IterMut<'_, T>) -> Option< as Iterator>::Item> { as DoubleEndedIterator>::next_back}, val: Value() } + } + + bb1: { + return; // scope 0 at $DIR/slice_iter.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir similarity index 98% rename from tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir index a1431d473bc61..a1de522826d7c 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir @@ -7,7 +7,7 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut bb0: { _0 = as DoubleEndedIterator>::next_back(_1) -> bb1; // scope 0 at $DIR/slice_iter.rs:+1:5: +1:19 // mir::Constant - // + span: $DIR/slice_iter.rs:23:8: 23:17 + // + span: $DIR/slice_iter.rs:24:8: 24:17 // + literal: Const { ty: for<'a> fn(&'a mut std::slice::IterMut<'_, T>) -> Option< as Iterator>::Item> { as DoubleEndedIterator>::next_back}, val: Value() } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..1dfcb04c421be --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir @@ -0,0 +1,17 @@ +// MIR for `slice_iter_next` after PreCodegen + +fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { + debug it => _1; // in scope 0 at $DIR/slice_iter.rs:+0:31: +0:33 + let mut _0: std::option::Option<&T>; // return place in scope 0 at $DIR/slice_iter.rs:+0:68: +0:81 + + bb0: { + _0 = as Iterator>::next(_1) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/slice_iter.rs:+1:5: +1:14 + // mir::Constant + // + span: $DIR/slice_iter.rs:19:8: 19:12 + // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option< as Iterator>::Item> { as Iterator>::next}, val: Value() } + } + + bb1: { + return; // scope 0 at $DIR/slice_iter.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir similarity index 97% rename from tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.mir rename to tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir index d2a963cad12a6..2aef35e771e63 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir @@ -7,7 +7,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { bb0: { _0 = as Iterator>::next(_1) -> bb1; // scope 0 at $DIR/slice_iter.rs:+1:5: +1:14 // mir::Constant - // + span: $DIR/slice_iter.rs:18:8: 18:12 + // + span: $DIR/slice_iter.rs:19:8: 19:12 // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option< as Iterator>::Item> { as Iterator>::next}, val: Value() } } diff --git a/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-abort.diff similarity index 100% rename from tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff rename to tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-abort.diff diff --git a/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-unwind.diff b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-unwind.diff new file mode 100644 index 0000000000000..0b3da98a5a192 --- /dev/null +++ b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-unwind.diff @@ -0,0 +1,74 @@ +- // MIR for `match_guard` before CleanupPostBorrowck ++ // MIR for `match_guard` after CleanupPostBorrowck + + fn match_guard(_1: Option<&&i32>, _2: bool) -> i32 { + debug x => _1; // in scope 0 at $DIR/remove_fake_borrows.rs:+0:16: +0:17 + debug c => _2; // in scope 0 at $DIR/remove_fake_borrows.rs:+0:34: +0:35 + let mut _0: i32; // return place in scope 0 at $DIR/remove_fake_borrows.rs:+0:46: +0:49 + let mut _3: isize; // in scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 + let mut _4: &std::option::Option<&&i32>; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + let mut _5: &&i32; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + let mut _6: &&&i32; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + let mut _7: &i32; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + let mut _8: bool; // in scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + + bb0: { +- FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + _3 = discriminant(_1); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + switchInt(move _3) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12 + } + + bb1: { + _0 = const 1_i32; // scope 0 at $DIR/remove_fake_borrows.rs:+3:14: +3:15 + goto -> bb7; // scope 0 at $DIR/remove_fake_borrows.rs:+3:14: +3:15 + } + + bb2: { + switchInt((*(*((_1 as Some).0: &&i32)))) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12 + } + + bb3: { +- falseEdge -> [real: bb4, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 ++ goto -> bb4; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 + } + + bb4: { +- _4 = &shallow _1; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 +- _5 = &shallow (*((_1 as Some).0: &&i32)); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 +- _6 = &shallow ((_1 as Some).0: &&i32); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 +- _7 = &shallow (*(*((_1 as Some).0: &&i32))); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + StorageLive(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + _8 = _2; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + switchInt(move _8) -> [0: bb6, otherwise: bb5]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + } + + bb5: { + StorageDead(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- FakeRead(ForMatchGuard, _6); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- FakeRead(ForMatchGuard, _7); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + _0 = const 0_i32; // scope 0 at $DIR/remove_fake_borrows.rs:+2:25: +2:26 + goto -> bb7; // scope 0 at $DIR/remove_fake_borrows.rs:+2:25: +2:26 + } + + bb6: { + StorageDead(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ goto -> bb1; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + } + + bb7: { + return; // scope 0 at $DIR/remove_fake_borrows.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/remove_fake_borrows.rs b/tests/mir-opt/remove_fake_borrows.rs index d26c6f5d7e51b..f0ee98f777c61 100644 --- a/tests/mir-opt/remove_fake_borrows.rs +++ b/tests/mir-opt/remove_fake_borrows.rs @@ -1,6 +1,6 @@ // Test that the fake borrows for matches are removed after borrow checking. -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR remove_fake_borrows.match_guard.CleanupPostBorrowck.diff fn match_guard(x: Option<&&i32>, c: bool) -> i32 { diff --git a/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-abort.diff b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-abort.diff new file mode 100644 index 0000000000000..895c62bb5d082 --- /dev/null +++ b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-abort.diff @@ -0,0 +1,98 @@ +- // MIR for `main` before RemoveStorageMarkers ++ // MIR for `main` after RemoveStorageMarkers + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/remove_storage_markers.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/remove_storage_markers.rs:+1:9: +1:16 + let mut _2: std::ops::Range; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _3: std::ops::Range; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _5: (); // in scope 0 at $DIR/remove_storage_markers.rs:+0:1: +5:2 + let _6: (); // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _7: std::option::Option; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _8: &mut std::ops::Range; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _9: &mut std::ops::Range; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _10: isize; // in scope 0 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + let mut _11: !; // in scope 0 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + let mut _13: i32; // in scope 0 at $DIR/remove_storage_markers.rs:+3:16: +3:17 + scope 1 { + debug sum => _1; // in scope 1 at $DIR/remove_storage_markers.rs:+1:9: +1:16 + let mut _4: std::ops::Range; // in scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + scope 2 { + debug iter => _4; // in scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let _12: i32; // in scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10 + scope 3 { + debug i => _12; // in scope 3 at $DIR/remove_storage_markers.rs:+2:9: +2:10 + } + } + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/remove_storage_markers.rs:+1:9: +1:16 + _1 = const 0_i32; // scope 0 at $DIR/remove_storage_markers.rs:+1:19: +1:20 +- StorageLive(_2); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 +- StorageLive(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + _3 = std::ops::Range:: { start: const 0_i32, end: const 10_i32 }; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + _2 = as IntoIterator>::into_iter(move _3) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + // mir::Constant + // + span: $DIR/remove_storage_markers.rs:11:14: 11:19 + // + literal: Const { ty: fn(std::ops::Range) -> as IntoIterator>::IntoIter { as IntoIterator>::into_iter}, val: Value() } + } + + bb1: { +- StorageDead(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:18: +2:19 +- StorageLive(_4); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + _4 = move _2; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + goto -> bb2; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + } + + bb2: { +- StorageLive(_6); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 +- StorageLive(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 +- StorageLive(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 +- StorageLive(_9); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + _9 = &mut _4; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + _8 = &mut (*_9); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + _7 = as Iterator>::next(move _8) -> [return: bb3, unwind unreachable]; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + // mir::Constant + // + span: $DIR/remove_storage_markers.rs:11:14: 11:19 + // + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range) -> Option< as Iterator>::Item> { as Iterator>::next}, val: Value() } + } + + bb3: { +- StorageDead(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:18: +2:19 + _10 = discriminant(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + } + + bb4: { +- StorageLive(_12); // scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10 + _12 = ((_7 as Some).0: i32); // scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10 +- StorageLive(_13); // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17 + _13 = _12; // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17 + _1 = Add(_1, move _13); // scope 3 at $DIR/remove_storage_markers.rs:+3:9: +3:17 +- StorageDead(_13); // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17 + _6 = const (); // scope 3 at $DIR/remove_storage_markers.rs:+2:20: +4:6 +- StorageDead(_12); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_9); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_7); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_6); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 + _5 = const (); // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + goto -> bb2; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + } + + bb5: { + unreachable; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + } + + bb6: { + _0 = const (); // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6 +- StorageDead(_9); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_7); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_6); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_4); // scope 1 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_2); // scope 1 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_1); // scope 0 at $DIR/remove_storage_markers.rs:+5:1: +5:2 + return; // scope 0 at $DIR/remove_storage_markers.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-unwind.diff similarity index 100% rename from tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff rename to tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-unwind.diff diff --git a/tests/mir-opt/remove_storage_markers.rs b/tests/mir-opt/remove_storage_markers.rs index 480db8ac155b5..330264461d7cc 100644 --- a/tests/mir-opt/remove_storage_markers.rs +++ b/tests/mir-opt/remove_storage_markers.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: RemoveStorageMarkers // Checks that storage markers are removed at opt-level=0. diff --git a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-abort.diff new file mode 100644 index 0000000000000..3c8f40d13e4ad --- /dev/null +++ b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-abort.diff @@ -0,0 +1,27 @@ +- // MIR for `cannot_opt_generic` before RemoveUnneededDrops ++ // MIR for `cannot_opt_generic` after RemoveUnneededDrops + + fn cannot_opt_generic(_1: T) -> () { + debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:26: +0:27 + let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:32: +0:32 + let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + let mut _3: T; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + scope 1 (inlined std::mem::drop::) { // at $DIR/remove_unneeded_drops.rs:21:5: 21:12 + debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb0: { + nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + _3 = move _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + drop(_3) -> [return: bb1, unwind unreachable]; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12 + nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13 + nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:32: +2:2 + return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-unwind.diff similarity index 100% rename from tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff rename to tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-unwind.diff diff --git a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-abort.diff new file mode 100644 index 0000000000000..1a7e1a7fa67ea --- /dev/null +++ b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-abort.diff @@ -0,0 +1,27 @@ +- // MIR for `dont_opt` before RemoveUnneededDrops ++ // MIR for `dont_opt` after RemoveUnneededDrops + + fn dont_opt(_1: Vec) -> () { + debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:13: +0:14 + let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:27: +0:27 + let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + let mut _3: std::vec::Vec; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + scope 1 (inlined std::mem::drop::>) { // at $DIR/remove_unneeded_drops.rs:9:5: 9:12 + debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb0: { + nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + _3 = move _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + drop(_3) -> [return: bb1, unwind unreachable]; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12 + nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13 + nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:27: +2:2 + return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-unwind.diff similarity index 100% rename from tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff rename to tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-unwind.diff diff --git a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-abort.diff new file mode 100644 index 0000000000000..4a1517b5b93bf --- /dev/null +++ b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-abort.diff @@ -0,0 +1,27 @@ +- // MIR for `opt` before RemoveUnneededDrops ++ // MIR for `opt` after RemoveUnneededDrops + + fn opt(_1: bool) -> () { + debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:8: +0:9 + let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:17: +0:17 + let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + let mut _3: bool; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + scope 1 (inlined std::mem::drop::) { // at $DIR/remove_unneeded_drops.rs:4:5: 4:12 + debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb0: { +- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + _3 = _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 +- drop(_3) -> [return: bb1, unwind unreachable]; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL +- } +- +- bb1: { + StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12 +- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13 +- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:17: +2:2 + return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff similarity index 100% rename from tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff rename to tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff diff --git a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-abort.diff new file mode 100644 index 0000000000000..a7325d92e68f0 --- /dev/null +++ b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-abort.diff @@ -0,0 +1,27 @@ +- // MIR for `opt_generic_copy` before RemoveUnneededDrops ++ // MIR for `opt_generic_copy` after RemoveUnneededDrops + + fn opt_generic_copy(_1: T) -> () { + debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:30: +0:31 + let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:36: +0:36 + let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + let mut _3: T; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + scope 1 (inlined std::mem::drop::) { // at $DIR/remove_unneeded_drops.rs:14:5: 14:12 + debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb0: { +- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + _3 = _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 +- drop(_3) -> [return: bb1, unwind unreachable]; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL +- } +- +- bb1: { + StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12 +- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13 +- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:36: +2:2 + return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff similarity index 100% rename from tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff rename to tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff diff --git a/tests/mir-opt/remove_unneeded_drops.rs b/tests/mir-opt/remove_unneeded_drops.rs index 1052f2886770d..178d0924c5e0c 100644 --- a/tests/mir-opt/remove_unneeded_drops.rs +++ b/tests/mir-opt/remove_unneeded_drops.rs @@ -1,4 +1,4 @@ -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR remove_unneeded_drops.opt.RemoveUnneededDrops.diff fn opt(x: bool) { drop(x); diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir new file mode 100644 index 0000000000000..ff0f12fd63df5 --- /dev/null +++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir @@ -0,0 +1,188 @@ +// MIR for `array_casts` after SimplifyCfg-elaborate-drops + +fn array_casts() -> () { + let mut _0: (); // return place in scope 0 at $DIR/retag.rs:+0:18: +0:18 + let mut _1: [usize; 2]; // in scope 0 at $DIR/retag.rs:+1:9: +1:14 + let mut _3: *mut [usize; 2]; // in scope 0 at $DIR/retag.rs:+2:13: +2:19 + let mut _4: &mut [usize; 2]; // in scope 0 at $DIR/retag.rs:+2:13: +2:19 + let _5: (); // in scope 0 at $DIR/retag.rs:+3:5: +3:30 + let mut _6: *mut usize; // in scope 0 at $DIR/retag.rs:+3:15: +3:23 + let mut _7: *mut usize; // in scope 0 at $DIR/retag.rs:+3:15: +3:16 + let mut _10: *const [usize; 2]; // in scope 0 at $DIR/retag.rs:+6:13: +6:15 + let _11: &[usize; 2]; // in scope 0 at $DIR/retag.rs:+6:13: +6:15 + let _12: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _13: (&usize, &usize); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _14: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _15: usize; // in scope 0 at $DIR/retag.rs:+7:16: +7:36 + let mut _16: *const usize; // in scope 0 at $DIR/retag.rs:+7:26: +7:34 + let mut _17: *const usize; // in scope 0 at $DIR/retag.rs:+7:26: +7:27 + let mut _18: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _19: usize; // in scope 0 at $DIR/retag.rs:+7:38: +7:39 + let mut _22: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _24: usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _25: usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _26: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _28: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _29: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _30: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _31: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _32: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _33: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _34: std::option::Option>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 1 { + debug x => _1; // in scope 1 at $DIR/retag.rs:+1:9: +1:14 + let _2: *mut usize; // in scope 1 at $DIR/retag.rs:+2:9: +2:10 + scope 2 { + debug p => _2; // in scope 2 at $DIR/retag.rs:+2:9: +2:10 + let _8: [usize; 2]; // in scope 2 at $DIR/retag.rs:+5:9: +5:10 + scope 3 { + } + scope 4 { + debug x => _8; // in scope 4 at $DIR/retag.rs:+5:9: +5:10 + let _9: *const usize; // in scope 4 at $DIR/retag.rs:+6:9: +6:10 + scope 5 { + debug p => _9; // in scope 5 at $DIR/retag.rs:+6:9: +6:10 + let _20: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _21: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _35: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 6 { + } + scope 7 { + debug left_val => _20; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _21; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _27: core::panicking::AssertKind; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 8 { + debug kind => _27; // in scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/retag.rs:+1:9: +1:14 + _1 = [const 0_usize, const 0_usize]; // scope 0 at $DIR/retag.rs:+1:29: +1:35 + StorageLive(_2); // scope 1 at $DIR/retag.rs:+2:9: +2:10 + StorageLive(_3); // scope 1 at $DIR/retag.rs:+2:13: +2:19 + StorageLive(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19 + _4 = &mut _1; // scope 1 at $DIR/retag.rs:+2:13: +2:19 + _3 = &raw mut (*_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19 + _2 = move _3 as *mut usize (Pointer(ArrayToPointer)); // scope 1 at $DIR/retag.rs:+2:13: +2:33 + StorageDead(_3); // scope 1 at $DIR/retag.rs:+2:32: +2:33 + StorageDead(_4); // scope 1 at $DIR/retag.rs:+2:33: +2:34 + StorageLive(_5); // scope 2 at $DIR/retag.rs:+3:5: +3:30 + StorageLive(_6); // scope 3 at $DIR/retag.rs:+3:15: +3:23 + StorageLive(_7); // scope 3 at $DIR/retag.rs:+3:15: +3:16 + _7 = _2; // scope 3 at $DIR/retag.rs:+3:15: +3:16 + _6 = ptr::mut_ptr::::add(move _7, const 1_usize) -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/retag.rs:+3:15: +3:23 + // mir::Constant + // + span: $DIR/retag.rs:61:17: 61:20 + // + literal: Const { ty: unsafe fn(*mut usize, usize) -> *mut usize {ptr::mut_ptr::::add}, val: Value() } + } + + bb1: { + StorageDead(_7); // scope 3 at $DIR/retag.rs:+3:22: +3:23 + (*_6) = const 1_usize; // scope 3 at $DIR/retag.rs:+3:14: +3:27 + StorageDead(_6); // scope 3 at $DIR/retag.rs:+3:27: +3:28 + _5 = const (); // scope 3 at $DIR/retag.rs:+3:5: +3:30 + StorageDead(_5); // scope 2 at $DIR/retag.rs:+3:29: +3:30 + StorageLive(_8); // scope 2 at $DIR/retag.rs:+5:9: +5:10 + _8 = [const 0_usize, const 1_usize]; // scope 2 at $DIR/retag.rs:+5:25: +5:31 + StorageLive(_9); // scope 4 at $DIR/retag.rs:+6:9: +6:10 + StorageLive(_10); // scope 4 at $DIR/retag.rs:+6:13: +6:15 + StorageLive(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15 + _11 = &_8; // scope 4 at $DIR/retag.rs:+6:13: +6:15 + _10 = &raw const (*_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15 + _9 = move _10 as *const usize (Pointer(ArrayToPointer)); // scope 4 at $DIR/retag.rs:+6:13: +6:31 + StorageDead(_10); // scope 4 at $DIR/retag.rs:+6:30: +6:31 + StorageDead(_11); // scope 4 at $DIR/retag.rs:+6:31: +6:32 + StorageLive(_12); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_15); // scope 5 at $DIR/retag.rs:+7:16: +7:36 + StorageLive(_16); // scope 6 at $DIR/retag.rs:+7:26: +7:34 + StorageLive(_17); // scope 6 at $DIR/retag.rs:+7:26: +7:27 + _17 = _9; // scope 6 at $DIR/retag.rs:+7:26: +7:27 + _16 = ptr::const_ptr::::add(move _17, const 1_usize) -> [return: bb2, unwind unreachable]; // scope 6 at $DIR/retag.rs:+7:26: +7:34 + // mir::Constant + // + span: $DIR/retag.rs:65:28: 65:31 + // + literal: Const { ty: unsafe fn(*const usize, usize) -> *const usize {ptr::const_ptr::::add}, val: Value() } + } + + bb2: { + StorageDead(_17); // scope 6 at $DIR/retag.rs:+7:33: +7:34 + _15 = (*_16); // scope 6 at $DIR/retag.rs:+7:25: +7:34 + _14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _35 = const _; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) } + Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = (move _14, move _18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _20 = (_13.0: &usize); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = (_13.1: &usize); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_24); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _24 = (*_20); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = (*_21); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _23 = Eq(move _24, move _25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_24); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _22 = Not(move _23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _22) -> [0: bb4, otherwise: bb3]; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb3: { + StorageLive(_27); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _27 = core::panicking::AssertKind::Eq; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_28); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_29); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _29 = move _27; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _31 = &(*_20); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _30 = &(*_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _33 = &(*_21); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _32 = &(*_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _34 = Option::>::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _28 = core::panicking::assert_failed::(move _29, move _30, move _32, move _34) -> unwind unreachable; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a usize, &'b usize, Option>) -> ! {core::panicking::assert_failed::}, val: Value() } + } + + bb4: { + _12 = const (); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_22); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_12); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _0 = const (); // scope 0 at $DIR/retag.rs:+0:18: +8:2 + StorageDead(_9); // scope 4 at $DIR/retag.rs:+8:1: +8:2 + StorageDead(_8); // scope 2 at $DIR/retag.rs:+8:1: +8:2 + StorageDead(_2); // scope 1 at $DIR/retag.rs:+8:1: +8:2 + StorageDead(_1); // scope 0 at $DIR/retag.rs:+8:1: +8:2 + return; // scope 0 at $DIR/retag.rs:+8:2: +8:2 + } +} diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir rename to tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir diff --git a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir new file mode 100644 index 0000000000000..7de6c67980a19 --- /dev/null +++ b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir @@ -0,0 +1,26 @@ +// MIR for `std::ptr::drop_in_place` after SimplifyCfg-make_shim + +fn std::ptr::drop_in_place(_1: *mut Test) -> () { + let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _2: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _3: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _4: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + + bb0: { + _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + Retag([fn entry] _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _3 = &mut (*_2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _4 = ::drop(move _3) -> [return: bb2, unwind: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + // mir::Constant + // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL + // + literal: Const { ty: for<'a> fn(&'a mut Test) {::drop}, val: Value() } + } + + bb1 (cleanup): { + resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb2: { + return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } +} diff --git a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir rename to tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir diff --git a/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.panic-abort.mir similarity index 100% rename from tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir rename to tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.panic-abort.mir diff --git a/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.panic-unwind.mir new file mode 100644 index 0000000000000..9e5c119a2b24e --- /dev/null +++ b/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.panic-unwind.mir @@ -0,0 +1,21 @@ +// MIR for `main::{closure#0}` after SimplifyCfg-elaborate-drops + +fn main::{closure#0}(_1: &[closure@main::{closure#0}], _2: &i32) -> &i32 { + debug x => _2; // in scope 0 at $DIR/retag.rs:+0:32: +0:33 + let mut _0: &i32; // return place in scope 0 at $DIR/retag.rs:+0:44: +0:48 + let _3: &i32; // in scope 0 at $DIR/retag.rs:+1:13: +1:15 + scope 1 { + debug _y => _3; // in scope 1 at $DIR/retag.rs:+1:13: +1:15 + } + + bb0: { + Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:31: +3:6 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:32: +0:33 + StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:13: +1:15 + _3 = _2; // scope 0 at $DIR/retag.rs:+1:18: +1:19 + Retag(_3); // scope 0 at $DIR/retag.rs:+1:18: +1:19 + _0 = &(*_2); // scope 1 at $DIR/retag.rs:+2:9: +2:10 + StorageDead(_3); // scope 0 at $DIR/retag.rs:+3:5: +3:6 + return; // scope 0 at $DIR/retag.rs:+3:6: +3:6 + } +} diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir new file mode 100644 index 0000000000000..32d70a33bb68e --- /dev/null +++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir @@ -0,0 +1,187 @@ +// MIR for `main` after SimplifyCfg-elaborate-drops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/retag.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/retag.rs:+1:9: +1:14 + let _2: (); // in scope 0 at $DIR/retag.rs:+2:5: +8:6 + let mut _4: &Test; // in scope 0 at $DIR/retag.rs:+3:17: +3:36 + let _5: Test; // in scope 0 at $DIR/retag.rs:+3:17: +3:24 + let mut _6: &mut i32; // in scope 0 at $DIR/retag.rs:+3:29: +3:35 + let mut _7: &mut i32; // in scope 0 at $DIR/retag.rs:+3:29: +3:35 + let mut _9: &mut i32; // in scope 0 at $DIR/retag.rs:+4:19: +4:20 + let mut _12: *mut i32; // in scope 0 at $DIR/retag.rs:+7:18: +7:29 + let mut _14: [closure@main::{closure#0}]; // in scope 0 at $DIR/retag.rs:+11:31: +14:6 + let mut _16: for<'a> fn(&'a i32) -> &'a i32; // in scope 0 at $DIR/retag.rs:+15:14: +15:15 + let mut _17: &i32; // in scope 0 at $DIR/retag.rs:+15:16: +15:18 + let _18: &i32; // in scope 0 at $DIR/retag.rs:+15:16: +15:18 + let _19: &i32; // in scope 0 at $DIR/retag.rs:+18:5: +18:24 + let mut _20: &Test; // in scope 0 at $DIR/retag.rs:+18:5: +18:24 + let _21: Test; // in scope 0 at $DIR/retag.rs:+18:5: +18:12 + let mut _22: &i32; // in scope 0 at $DIR/retag.rs:+18:21: +18:23 + let _23: &i32; // in scope 0 at $DIR/retag.rs:+18:21: +18:23 + let _24: i32; // in scope 0 at $DIR/retag.rs:+18:22: +18:23 + let mut _26: *const i32; // in scope 0 at $DIR/retag.rs:+21:14: +21:28 + let _27: (); // in scope 0 at $DIR/retag.rs:+23:5: +23:18 + scope 1 { + debug x => _1; // in scope 1 at $DIR/retag.rs:+1:9: +1:14 + let _3: &mut i32; // in scope 1 at $DIR/retag.rs:+3:13: +3:14 + let _13: for<'a> fn(&'a i32) -> &'a i32; // in scope 1 at $DIR/retag.rs:+11:9: +11:10 + scope 2 { + debug v => _3; // in scope 2 at $DIR/retag.rs:+3:13: +3:14 + let _8: &mut i32; // in scope 2 at $DIR/retag.rs:+4:13: +4:14 + scope 3 { + debug w => _8; // in scope 3 at $DIR/retag.rs:+4:13: +4:14 + let _10: &mut i32; // in scope 3 at $DIR/retag.rs:+5:13: +5:14 + scope 4 { + debug w => _10; // in scope 4 at $DIR/retag.rs:+5:13: +5:14 + let _11: *mut i32; // in scope 4 at $DIR/retag.rs:+7:13: +7:15 + scope 5 { + debug _w => _11; // in scope 5 at $DIR/retag.rs:+7:13: +7:15 + } + } + } + } + scope 6 { + debug c => _13; // in scope 6 at $DIR/retag.rs:+11:9: +11:10 + let _15: &i32; // in scope 6 at $DIR/retag.rs:+15:9: +15:11 + scope 7 { + debug _w => _15; // in scope 7 at $DIR/retag.rs:+15:9: +15:11 + let _25: *const i32; // in scope 7 at $DIR/retag.rs:+21:9: +21:11 + let mut _28: &i32; // in scope 7 at $DIR/retag.rs:+18:21: +18:23 + scope 8 { + debug _w => _25; // in scope 8 at $DIR/retag.rs:+21:9: +21:11 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/retag.rs:+1:9: +1:14 + _1 = const 0_i32; // scope 0 at $DIR/retag.rs:+1:17: +1:18 + StorageLive(_2); // scope 1 at $DIR/retag.rs:+2:5: +8:6 + StorageLive(_3); // scope 1 at $DIR/retag.rs:+3:13: +3:14 + StorageLive(_4); // scope 1 at $DIR/retag.rs:+3:17: +3:36 + StorageLive(_5); // scope 1 at $DIR/retag.rs:+3:17: +3:24 + _5 = Test(const 0_i32); // scope 1 at $DIR/retag.rs:+3:17: +3:24 + _4 = &_5; // scope 1 at $DIR/retag.rs:+3:17: +3:36 + StorageLive(_6); // scope 1 at $DIR/retag.rs:+3:29: +3:35 + StorageLive(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35 + _7 = &mut _1; // scope 1 at $DIR/retag.rs:+3:29: +3:35 + _6 = &mut (*_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35 + _3 = Test::foo(move _4, move _6) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/retag.rs:+3:17: +3:36 + // mir::Constant + // + span: $DIR/retag.rs:33:25: 33:28 + // + literal: Const { ty: for<'a, 'x> fn(&'a Test, &'x mut i32) -> &'x mut i32 {Test::foo}, val: Value() } + } + + bb1: { + Retag(_3); // scope 1 at $DIR/retag.rs:+3:17: +3:36 + StorageDead(_6); // scope 1 at $DIR/retag.rs:+3:35: +3:36 + StorageDead(_4); // scope 1 at $DIR/retag.rs:+3:35: +3:36 + StorageDead(_7); // scope 1 at $DIR/retag.rs:+3:36: +3:37 + drop(_5) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/retag.rs:+3:36: +3:37 + } + + bb2: { + StorageDead(_5); // scope 1 at $DIR/retag.rs:+3:36: +3:37 + StorageLive(_8); // scope 2 at $DIR/retag.rs:+4:13: +4:14 + StorageLive(_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20 + _9 = move _3; // scope 2 at $DIR/retag.rs:+4:19: +4:20 + Retag(_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20 + _8 = &mut (*_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20 + StorageDead(_9); // scope 2 at $DIR/retag.rs:+4:22: +4:23 + StorageLive(_10); // scope 3 at $DIR/retag.rs:+5:13: +5:14 + _10 = move _8; // scope 3 at $DIR/retag.rs:+5:17: +5:18 + Retag(_10); // scope 3 at $DIR/retag.rs:+5:17: +5:18 + StorageLive(_11); // scope 4 at $DIR/retag.rs:+7:13: +7:15 + StorageLive(_12); // scope 4 at $DIR/retag.rs:+7:18: +7:29 + _12 = &raw mut (*_10); // scope 4 at $DIR/retag.rs:+7:18: +7:19 + _11 = _12; // scope 4 at $DIR/retag.rs:+7:18: +7:29 + StorageDead(_12); // scope 4 at $DIR/retag.rs:+7:29: +7:30 + _2 = const (); // scope 1 at $DIR/retag.rs:+2:5: +8:6 + StorageDead(_11); // scope 4 at $DIR/retag.rs:+8:5: +8:6 + StorageDead(_10); // scope 3 at $DIR/retag.rs:+8:5: +8:6 + StorageDead(_8); // scope 2 at $DIR/retag.rs:+8:5: +8:6 + StorageDead(_3); // scope 1 at $DIR/retag.rs:+8:5: +8:6 + StorageDead(_2); // scope 1 at $DIR/retag.rs:+8:5: +8:6 + StorageLive(_13); // scope 1 at $DIR/retag.rs:+11:9: +11:10 + StorageLive(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6 + _14 = [closure@main::{closure#0}]; // scope 1 at $DIR/retag.rs:+11:31: +14:6 + // closure + // + def_id: DefId(0:14 ~ retag[7654]::main::{closure#0}) + // + substs: [ + // i8, + // for<'a> extern "rust-call" fn((&'a i32,)) -> &'a i32, + // (), + // ] + Retag(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6 + _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (Pointer(ClosureFnPointer(Normal))); // scope 1 at $DIR/retag.rs:+11:31: +14:6 + StorageDead(_14); // scope 1 at $DIR/retag.rs:+11:47: +11:48 + StorageLive(_15); // scope 6 at $DIR/retag.rs:+15:9: +15:11 + StorageLive(_16); // scope 6 at $DIR/retag.rs:+15:14: +15:15 + _16 = _13; // scope 6 at $DIR/retag.rs:+15:14: +15:15 + StorageLive(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18 + StorageLive(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18 + _18 = &_1; // scope 6 at $DIR/retag.rs:+15:16: +15:18 + _17 = &(*_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18 + _15 = move _16(move _17) -> [return: bb3, unwind unreachable]; // scope 6 at $DIR/retag.rs:+15:14: +15:19 + } + + bb3: { + Retag(_15); // scope 6 at $DIR/retag.rs:+15:14: +15:19 + StorageDead(_17); // scope 6 at $DIR/retag.rs:+15:18: +15:19 + StorageDead(_16); // scope 6 at $DIR/retag.rs:+15:18: +15:19 + StorageDead(_18); // scope 6 at $DIR/retag.rs:+15:19: +15:20 + StorageLive(_19); // scope 7 at $DIR/retag.rs:+18:5: +18:24 + StorageLive(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24 + StorageLive(_21); // scope 7 at $DIR/retag.rs:+18:5: +18:12 + _21 = Test(const 0_i32); // scope 7 at $DIR/retag.rs:+18:5: +18:12 + _20 = &_21; // scope 7 at $DIR/retag.rs:+18:5: +18:24 + StorageLive(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + StorageLive(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + _28 = const _; // scope 7 at $DIR/retag.rs:+18:21: +18:23 + // mir::Constant + // + span: $DIR/retag.rs:48:21: 48:23 + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } + Retag(_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + _23 = &(*_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + _22 = &(*_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + _19 = Test::foo_shr(move _20, move _22) -> [return: bb4, unwind unreachable]; // scope 7 at $DIR/retag.rs:+18:5: +18:24 + // mir::Constant + // + span: $DIR/retag.rs:48:13: 48:20 + // + literal: Const { ty: for<'a, 'x> fn(&'a Test, &'x i32) -> &'x i32 {Test::foo_shr}, val: Value() } + } + + bb4: { + Retag(_19); // scope 7 at $DIR/retag.rs:+18:5: +18:24 + StorageDead(_22); // scope 7 at $DIR/retag.rs:+18:23: +18:24 + StorageDead(_20); // scope 7 at $DIR/retag.rs:+18:23: +18:24 + StorageDead(_23); // scope 7 at $DIR/retag.rs:+18:24: +18:25 + drop(_21) -> [return: bb5, unwind unreachable]; // scope 7 at $DIR/retag.rs:+18:24: +18:25 + } + + bb5: { + StorageDead(_21); // scope 7 at $DIR/retag.rs:+18:24: +18:25 + StorageDead(_19); // scope 7 at $DIR/retag.rs:+18:24: +18:25 + StorageLive(_25); // scope 7 at $DIR/retag.rs:+21:9: +21:11 + StorageLive(_26); // scope 7 at $DIR/retag.rs:+21:14: +21:28 + _26 = &raw const (*_15); // scope 7 at $DIR/retag.rs:+21:14: +21:16 + _25 = _26; // scope 7 at $DIR/retag.rs:+21:14: +21:28 + StorageDead(_26); // scope 7 at $DIR/retag.rs:+21:28: +21:29 + StorageLive(_27); // scope 8 at $DIR/retag.rs:+23:5: +23:18 + _27 = array_casts() -> [return: bb6, unwind unreachable]; // scope 8 at $DIR/retag.rs:+23:5: +23:18 + // mir::Constant + // + span: $DIR/retag.rs:53:5: 53:16 + // + literal: Const { ty: fn() {array_casts}, val: Value() } + } + + bb6: { + StorageDead(_27); // scope 8 at $DIR/retag.rs:+23:18: +23:19 + _0 = const (); // scope 0 at $DIR/retag.rs:+0:11: +24:2 + StorageDead(_25); // scope 7 at $DIR/retag.rs:+24:1: +24:2 + StorageDead(_15); // scope 6 at $DIR/retag.rs:+24:1: +24:2 + StorageDead(_13); // scope 1 at $DIR/retag.rs:+24:1: +24:2 + StorageDead(_1); // scope 0 at $DIR/retag.rs:+24:1: +24:2 + return; // scope 0 at $DIR/retag.rs:+24:2: +24:2 + } +} diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir rename to tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir diff --git a/tests/mir-opt/retag.rs b/tests/mir-opt/retag.rs index 86deb0e7ccded..e0696de4df379 100644 --- a/tests/mir-opt/retag.rs +++ b/tests/mir-opt/retag.rs @@ -1,5 +1,5 @@ // unit-test: AddRetag -// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // ignore-tidy-linelength // compile-flags: -Z mir-emit-retag -Z mir-opt-level=0 -Z span_free_formats diff --git a/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.panic-abort.mir similarity index 100% rename from tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir rename to tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.panic-abort.mir diff --git a/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.panic-unwind.mir new file mode 100644 index 0000000000000..4b50205fa8081 --- /dev/null +++ b/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.panic-unwind.mir @@ -0,0 +1,18 @@ +// MIR for `::foo` after SimplifyCfg-elaborate-drops + +fn ::foo(_1: &Test, _2: &mut i32) -> &mut i32 { + debug self => _1; // in scope 0 at $DIR/retag.rs:+0:16: +0:21 + debug x => _2; // in scope 0 at $DIR/retag.rs:+0:23: +0:24 + let mut _0: &mut i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:53 + let mut _3: &mut i32; // in scope 0 at $DIR/retag.rs:+1:9: +1:10 + + bb0: { + Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:16: +0:21 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:23: +0:24 + StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10 + _3 = &mut (*_2); // scope 0 at $DIR/retag.rs:+1:9: +1:10 + _0 = &mut (*_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10 + StorageDead(_3); // scope 0 at $DIR/retag.rs:+2:5: +2:6 + return; // scope 0 at $DIR/retag.rs:+2:6: +2:6 + } +} diff --git a/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.panic-abort.mir similarity index 100% rename from tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir rename to tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.panic-abort.mir diff --git a/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.panic-unwind.mir new file mode 100644 index 0000000000000..f32a84e4c791b --- /dev/null +++ b/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.panic-unwind.mir @@ -0,0 +1,15 @@ +// MIR for `::foo_shr` after SimplifyCfg-elaborate-drops + +fn ::foo_shr(_1: &Test, _2: &i32) -> &i32 { + debug self => _1; // in scope 0 at $DIR/retag.rs:+0:20: +0:25 + debug x => _2; // in scope 0 at $DIR/retag.rs:+0:27: +0:28 + let mut _0: &i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:49 + + bb0: { + Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:20: +0:25 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:27: +0:28 + _0 = _2; // scope 0 at $DIR/retag.rs:+1:9: +1:10 + Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10 + return; // scope 0 at $DIR/retag.rs:+2:6: +2:6 + } +} diff --git a/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-abort.diff b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-abort.diff new file mode 100644 index 0000000000000..2159f9dd6cc46 --- /dev/null +++ b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-abort.diff @@ -0,0 +1,36 @@ +- // MIR for `main` before SimplifyConstCondition-after-const-prop ++ // MIR for `main` after SimplifyConstCondition-after-const-prop + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_if.rs:+0:11: +0:11 + let mut _1: bool; // in scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 + let _2: (); // in scope 0 at $DIR/simplify_if.rs:+2:9: +2:15 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 + _1 = const false; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 +- switchInt(const false) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 ++ goto -> bb3; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 + } + + bb1: { + _2 = noop() -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/simplify_if.rs:+2:9: +2:15 + // mir::Constant + // + span: $DIR/simplify_if.rs:8:9: 8:13 + // + literal: Const { ty: fn() {noop}, val: Value() } + } + + bb2: { + goto -> bb4; // scope 0 at $DIR/simplify_if.rs:+1:5: +3:6 + } + + bb3: { + goto -> bb4; // scope 0 at $DIR/simplify_if.rs:+1:5: +3:6 + } + + bb4: { + StorageDead(_1); // scope 0 at $DIR/simplify_if.rs:+3:5: +3:6 + return; // scope 0 at $DIR/simplify_if.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff similarity index 100% rename from tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff rename to tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff diff --git a/tests/mir-opt/simplify_if.rs b/tests/mir-opt/simplify_if.rs index b86f80a8038bf..fff23b3ce7f2a 100644 --- a/tests/mir-opt/simplify_if.rs +++ b/tests/mir-opt/simplify_if.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #[inline(never)] fn noop() {} diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff new file mode 100644 index 0000000000000..e45b3b9c4bb6c --- /dev/null +++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff @@ -0,0 +1,50 @@ +- // MIR for `foo` before SimplifyLocals-final ++ // MIR for `foo` after SimplifyLocals-final + + fn foo() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+0:13: +0:13 + let mut _1: (std::option::Option, std::option::Option); // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + let mut _2: std::option::Option; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + let mut _3: std::option::Option; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + let mut _4: isize; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:22: +1:26 + let mut _5: isize; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:13: +1:20 + scope 1 { + debug a => _6; // in scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 + let _6: u8; // in scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + StorageLive(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + _2 = Option::::None; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + StorageLive(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + _3 = Option::::None; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + _1 = (move _2, move _3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + StorageDead(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69 + StorageDead(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69 + _5 = discriminant((_1.0: std::option::Option)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + switchInt(move _5) -> [1: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + } + + bb1: { + _4 = discriminant((_1.1: std::option::Option)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + switchInt(move _4) -> [0: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + } + + bb2: { + StorageLive(_6); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 + _6 = (((_1.0: std::option::Option) as Some).0: u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 + StorageDead(_6); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+5:5: +5:6 + goto -> bb3; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:5: +5:6 + } + + bb3: { + drop(_1) -> [return: bb4, unwind unreachable]; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:1: +6:2 + } + + bb4: { + StorageDead(_1); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:2: +6:2 + } + } + diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff similarity index 100% rename from tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff rename to tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff diff --git a/tests/mir-opt/simplify_locals_fixedpoint.rs b/tests/mir-opt/simplify_locals_fixedpoint.rs index 7c41e8b7c20ee..4da18b7fe58a6 100644 --- a/tests/mir-opt/simplify_locals_fixedpoint.rs +++ b/tests/mir-opt/simplify_locals_fixedpoint.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Zmir-opt-level=1 fn foo() { diff --git a/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.panic-abort.diff b/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.panic-abort.diff new file mode 100644 index 0000000000000..232f63aba11a3 --- /dev/null +++ b/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.panic-abort.diff @@ -0,0 +1,101 @@ +- // MIR for `main` before SimplifyLocals-before-const-prop ++ // MIR for `main` after SimplifyLocals-before-const-prop + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +0:11 +- let mut _1: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- let mut _2: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 +- let mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 +- let _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 +- let mut _5: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- let mut _6: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 +- let mut _7: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 +- let _8: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 +- let mut _9: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 +- let mut _10: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 +- let mut _11: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ let _1: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 ++ let mut _2: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ let mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ let mut _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ let _5: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ let mut _6: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ let mut _7: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ let mut _8: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- StorageLive(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 +- _2 = (); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 +- StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 +- _3 = (); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 +- _1 = (move _2, move _3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:28: +1:29 +- StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 +- StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 +- _6 = (); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 +- StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 +- _7 = (); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 +- _5 = (move _6, move _7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 +- StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 +- _4 = use_zst(move _5) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 ++ StorageLive(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 ++ StorageLive(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ StorageLive(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ _3 = (); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ _4 = (); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ _2 = (move _3, move _4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 ++ StorageDead(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 ++ _1 = use_zst(move _2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 + // mir::Constant + // + span: $DIR/simplify_locals_removes_unused_consts.rs:16:5: 16:12 + // + literal: Const { ty: fn(((), ())) {use_zst}, val: Value() } + } + + bb1: { +- StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22 +- StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23 +- StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 +- StorageLive(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 +- StorageLive(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 +- StorageLive(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 +- _11 = Temp { x: const 40_u8 }; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 +- _10 = (_11.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 +- _9 = Add(move _10, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 +- StorageDead(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34 +- _8 = use_u8(move _9) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ StorageDead(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22 ++ StorageDead(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23 ++ StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ _8 = Temp { x: const 40_u8 }; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ _7 = (_8.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ _6 = Add(move _7, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34 ++ _5 = use_u8(move _6) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 + // mir::Constant + // + span: $DIR/simplify_locals_removes_unused_consts.rs:18:5: 18:11 + // + literal: Const { ty: fn(u8) {use_u8}, val: Value() } + } + + bb2: { +- StorageDead(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35 +- StorageDead(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 ++ StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35 + StorageDead(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 ++ StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 + _0 = const (); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +5:2 + return; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.panic-unwind.diff similarity index 100% rename from tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff rename to tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.panic-unwind.diff diff --git a/tests/mir-opt/simplify_locals_removes_unused_consts.rs b/tests/mir-opt/simplify_locals_removes_unused_consts.rs index 983d8004e2ed4..1e404c3a48c57 100644 --- a/tests/mir-opt/simplify_locals_removes_unused_consts.rs +++ b/tests/mir-opt/simplify_locals_removes_unused_consts.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: SimplifyLocals-before-const-prop // compile-flags: -C overflow-checks=no diff --git a/tests/mir-opt/simplify_match.main.ConstProp.panic-abort.diff b/tests/mir-opt/simplify_match.main.ConstProp.panic-abort.diff new file mode 100644 index 0000000000000..f25b8fe64ff0d --- /dev/null +++ b/tests/mir-opt/simplify_match.main.ConstProp.panic-abort.diff @@ -0,0 +1,33 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_match.rs:+0:11: +0:11 + let mut _1: bool; // in scope 0 at $DIR/simplify_match.rs:+1:11: +1:31 + let _2: bool; // in scope 0 at $DIR/simplify_match.rs:+1:17: +1:18 + scope 1 { + debug x => _2; // in scope 1 at $DIR/simplify_match.rs:+1:17: +1:18 + } + + bb0: { + _2 = const false; // scope 0 at $DIR/simplify_match.rs:+1:21: +1:26 +- switchInt(_2) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31 ++ switchInt(const false) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31 + } + + bb1: { + goto -> bb3; // scope 0 at $DIR/simplify_match.rs:+3:18: +3:20 + } + + bb2: { + _0 = noop() -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/simplify_match.rs:+2:17: +2:23 + // mir::Constant + // + span: $DIR/simplify_match.rs:8:17: 8:21 + // + literal: Const { ty: fn() {noop}, val: Value() } + } + + bb3: { + return; // scope 0 at $DIR/simplify_match.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/simplify_match.main.ConstProp.diff b/tests/mir-opt/simplify_match.main.ConstProp.panic-unwind.diff similarity index 100% rename from tests/mir-opt/simplify_match.main.ConstProp.diff rename to tests/mir-opt/simplify_match.main.ConstProp.panic-unwind.diff diff --git a/tests/mir-opt/simplify_match.rs b/tests/mir-opt/simplify_match.rs index 6a2a6f2171967..5d8e94b093568 100644 --- a/tests/mir-opt/simplify_match.rs +++ b/tests/mir-opt/simplify_match.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY #[inline(never)] fn noop() {} diff --git a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-abort.diff b/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-abort.diff new file mode 100644 index 0000000000000..a53facea506d5 --- /dev/null +++ b/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-abort.diff @@ -0,0 +1,70 @@ +- // MIR for `main` before UnreachablePropagation ++ // MIR for `main` after UnreachablePropagation + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/unreachable.rs:+0:11: +0:11 + let mut _1: std::option::Option; // in scope 0 at $DIR/unreachable.rs:+1:23: +1:30 + let mut _2: isize; // in scope 0 at $DIR/unreachable.rs:+1:12: +1:20 + let _5: (); // in scope 0 at $DIR/unreachable.rs:+4:9: +8:10 + let mut _6: bool; // in scope 0 at $DIR/unreachable.rs:+4:12: +4:16 + let mut _7: !; // in scope 0 at $DIR/unreachable.rs:+10:9: +10:21 + scope 1 { + debug _x => _3; // in scope 1 at $DIR/unreachable.rs:+1:17: +1:19 + let _3: Empty; // in scope 1 at $DIR/unreachable.rs:+1:17: +1:19 + let mut _4: i32; // in scope 1 at $DIR/unreachable.rs:+2:13: +2:19 + scope 2 { + debug _y => _4; // in scope 2 at $DIR/unreachable.rs:+2:13: +2:19 + } + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/unreachable.rs:+1:23: +1:30 + _1 = empty() -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/unreachable.rs:+1:23: +1:30 + // mir::Constant + // + span: $DIR/unreachable.rs:10:23: 10:28 + // + literal: Const { ty: fn() -> Option {empty}, val: Value() } + } + + bb1: { + _2 = discriminant(_1); // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 +- switchInt(move _2) -> [1: bb2, otherwise: bb6]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 ++ switchInt(move _2) -> [1: bb2, otherwise: bb3]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 + } + + bb2: { +- StorageLive(_3); // scope 1 at $DIR/unreachable.rs:+1:17: +1:19 +- _3 = move ((_1 as Some).0: Empty); // scope 1 at $DIR/unreachable.rs:+1:17: +1:19 +- StorageLive(_4); // scope 1 at $DIR/unreachable.rs:+2:13: +2:19 +- StorageLive(_5); // scope 2 at $DIR/unreachable.rs:+4:9: +8:10 +- StorageLive(_6); // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 +- _6 = const true; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 +- switchInt(move _6) -> [0: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 ++ unreachable; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 + } + + bb3: { +- _4 = const 21_i32; // scope 2 at $DIR/unreachable.rs:+5:13: +5:20 +- _5 = const (); // scope 2 at $DIR/unreachable.rs:+4:17: +6:10 +- goto -> bb5; // scope 2 at $DIR/unreachable.rs:+4:9: +8:10 +- } +- +- bb4: { +- _4 = const 42_i32; // scope 2 at $DIR/unreachable.rs:+7:13: +7:20 +- _5 = const (); // scope 2 at $DIR/unreachable.rs:+6:16: +8:10 +- goto -> bb5; // scope 2 at $DIR/unreachable.rs:+4:9: +8:10 +- } +- +- bb5: { +- StorageDead(_6); // scope 2 at $DIR/unreachable.rs:+8:9: +8:10 +- StorageDead(_5); // scope 2 at $DIR/unreachable.rs:+8:9: +8:10 +- StorageLive(_7); // scope 2 at $DIR/unreachable.rs:+10:9: +10:21 +- unreachable; // scope 2 at $DIR/unreachable.rs:+10:15: +10:17 +- } +- +- bb6: { + _0 = const (); // scope 0 at $DIR/unreachable.rs:+11:6: +11:6 + StorageDead(_1); // scope 0 at $DIR/unreachable.rs:+12:1: +12:2 + return; // scope 0 at $DIR/unreachable.rs:+12:2: +12:2 + } + } + diff --git a/tests/mir-opt/unreachable.main.UnreachablePropagation.diff b/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff similarity index 100% rename from tests/mir-opt/unreachable.main.UnreachablePropagation.diff rename to tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff diff --git a/tests/mir-opt/unreachable.rs b/tests/mir-opt/unreachable.rs index 97093729dd137..23fad4737fe9a 100644 --- a/tests/mir-opt/unreachable.rs +++ b/tests/mir-opt/unreachable.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY enum Empty {} fn empty() -> Option { diff --git a/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.panic-abort.diff b/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.panic-abort.diff new file mode 100644 index 0000000000000..b0ca8ab933fcc --- /dev/null +++ b/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.panic-abort.diff @@ -0,0 +1,71 @@ +- // MIR for `main` before UnreachablePropagation ++ // MIR for `main` after UnreachablePropagation + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/unreachable_diverging.rs:+0:11: +0:11 + let _1: bool; // in scope 0 at $DIR/unreachable_diverging.rs:+1:9: +1:10 + let mut _2: std::option::Option; // in scope 0 at $DIR/unreachable_diverging.rs:+2:25: +2:32 + let mut _3: isize; // in scope 0 at $DIR/unreachable_diverging.rs:+2:12: +2:22 + let _5: (); // in scope 0 at $DIR/unreachable_diverging.rs:+3:9: +5:10 + let mut _6: bool; // in scope 0 at $DIR/unreachable_diverging.rs:+3:12: +3:13 + let mut _7: !; // in scope 0 at $DIR/unreachable_diverging.rs:+6:9: +6:22 + scope 1 { + debug x => _1; // in scope 1 at $DIR/unreachable_diverging.rs:+1:9: +1:10 + scope 2 { + debug bomb => _4; // in scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21 + let _4: Empty; // in scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/unreachable_diverging.rs:+1:9: +1:10 + _1 = const true; // scope 0 at $DIR/unreachable_diverging.rs:+1:13: +1:17 + StorageLive(_2); // scope 2 at $DIR/unreachable_diverging.rs:+2:25: +2:32 + _2 = empty() -> [return: bb1, unwind unreachable]; // scope 2 at $DIR/unreachable_diverging.rs:+2:25: +2:32 + // mir::Constant + // + span: $DIR/unreachable_diverging.rs:15:25: 15:30 + // + literal: Const { ty: fn() -> Option {empty}, val: Value() } + } + + bb1: { + _3 = discriminant(_2); // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22 + switchInt(move _3) -> [1: bb2, otherwise: bb6]; // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22 + } + + bb2: { + StorageLive(_4); // scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21 + _4 = move ((_2 as Some).0: Empty); // scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21 + StorageLive(_5); // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10 + StorageLive(_6); // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 + _6 = _1; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 + switchInt(move _6) -> [0: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 + } + + bb3: { + _5 = loop_forever() -> [return: bb5, unwind unreachable]; // scope 2 at $DIR/unreachable_diverging.rs:+4:13: +4:27 + // mir::Constant + // + span: $DIR/unreachable_diverging.rs:17:13: 17:25 + // + literal: Const { ty: fn() {loop_forever}, val: Value() } + } + + bb4: { +- _5 = const (); // scope 2 at $DIR/unreachable_diverging.rs:+5:10: +5:10 +- goto -> bb5; // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10 ++ unreachable; // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10 + } + + bb5: { +- StorageDead(_6); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10 +- StorageDead(_5); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10 +- StorageLive(_7); // scope 2 at $DIR/unreachable_diverging.rs:+6:9: +6:22 + unreachable; // scope 2 at $DIR/unreachable_diverging.rs:+6:15: +6:19 + } + + bb6: { + _0 = const (); // scope 1 at $DIR/unreachable_diverging.rs:+7:6: +7:6 + StorageDead(_1); // scope 0 at $DIR/unreachable_diverging.rs:+8:1: +8:2 + StorageDead(_2); // scope 0 at $DIR/unreachable_diverging.rs:+8:1: +8:2 + return; // scope 0 at $DIR/unreachable_diverging.rs:+8:2: +8:2 + } + } + diff --git a/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff b/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.panic-unwind.diff similarity index 100% rename from tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff rename to tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.panic-unwind.diff diff --git a/tests/mir-opt/unreachable_diverging.rs b/tests/mir-opt/unreachable_diverging.rs index 24e776148c123..b7d308b863060 100644 --- a/tests/mir-opt/unreachable_diverging.rs +++ b/tests/mir-opt/unreachable_diverging.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY pub enum Empty {} fn empty() -> Option { diff --git a/tests/mir-opt/while_storage.rs b/tests/mir-opt/while_storage.rs index d10048dd908ae..d4fb54da5758b 100644 --- a/tests/mir-opt/while_storage.rs +++ b/tests/mir-opt/while_storage.rs @@ -1,4 +1,4 @@ -// ignore-wasm32 compiled with panic=abort by default +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Test that we correctly generate StorageDead statements for while loop // conditions on all branches diff --git a/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..c12f35918818f --- /dev/null +++ b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-abort.mir @@ -0,0 +1,52 @@ +// MIR for `while_loop` after PreCodegen + +fn while_loop(_1: bool) -> () { + debug c => _1; // in scope 0 at $DIR/while_storage.rs:+0:15: +0:16 + let mut _0: (); // return place in scope 0 at $DIR/while_storage.rs:+0:24: +0:24 + let mut _2: bool; // in scope 0 at $DIR/while_storage.rs:+1:11: +1:22 + let mut _3: bool; // in scope 0 at $DIR/while_storage.rs:+2:12: +2:23 + + bb0: { + goto -> bb1; // scope 0 at $DIR/while_storage.rs:+1:5: +5:6 + } + + bb1: { + StorageLive(_2); // scope 0 at $DIR/while_storage.rs:+1:11: +1:22 + _2 = get_bool(_1) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/while_storage.rs:+1:11: +1:22 + // mir::Constant + // + span: $DIR/while_storage.rs:11:11: 11:19 + // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value() } + } + + bb2: { + switchInt(move _2) -> [0: bb7, otherwise: bb3]; // scope 0 at $DIR/while_storage.rs:+1:11: +1:22 + } + + bb3: { + StorageLive(_3); // scope 0 at $DIR/while_storage.rs:+2:12: +2:23 + _3 = get_bool(_1) -> [return: bb4, unwind unreachable]; // scope 0 at $DIR/while_storage.rs:+2:12: +2:23 + // mir::Constant + // + span: $DIR/while_storage.rs:12:12: 12:20 + // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value() } + } + + bb4: { + switchInt(move _3) -> [0: bb5, otherwise: bb6]; // scope 0 at $DIR/while_storage.rs:+2:12: +2:23 + } + + bb5: { + StorageDead(_3); // scope 0 at $DIR/while_storage.rs:+4:9: +4:10 + StorageDead(_2); // scope 0 at $DIR/while_storage.rs:+5:5: +5:6 + goto -> bb1; // scope 0 at $DIR/while_storage.rs:+1:5: +5:6 + } + + bb6: { + StorageDead(_3); // scope 0 at $DIR/while_storage.rs:+4:9: +4:10 + goto -> bb7; // scope 0 at no-location + } + + bb7: { + StorageDead(_2); // scope 0 at $DIR/while_storage.rs:+5:5: +5:6 + return; // scope 0 at $DIR/while_storage.rs:+6:2: +6:2 + } +} diff --git a/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir similarity index 100% rename from tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir rename to tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir diff --git a/tests/rustdoc-gui/headers-color.goml b/tests/rustdoc-gui/headers-color.goml index 7d83833a8bd0c..a7ac94c4943cc 100644 --- a/tests/rustdoc-gui/headers-color.goml +++ b/tests/rustdoc-gui/headers-color.goml @@ -42,29 +42,29 @@ call-function: ( "check-colors", { "theme": "ayu", - "color": "rgb(197, 197, 197)", - "code_header_color": "rgb(230, 225, 207)", + "color": "#c5c5c5", + "code_header_color": "#e6e1cf", "focus_background_color": "rgba(255, 236, 164, 0.06)", - "headings_color": "rgb(57, 175, 215)", + "headings_color": "#39afd7", }, ) call-function: ( "check-colors", { "theme": "dark", - "color": "rgb(221, 221, 221)", - "code_header_color": "rgb(221, 221, 221)", - "focus_background_color": "rgb(73, 74, 61)", - "headings_color": "rgb(210, 153, 29)", + "color": "#ddd", + "code_header_color": "#ddd", + "focus_background_color": "#494a3d", + "headings_color": "#d2991d", }, ) call-function: ( "check-colors", { "theme": "light", - "color": "rgb(0, 0, 0)", - "code_header_color": "rgb(0, 0, 0)", - "focus_background_color": "rgb(253, 255, 211)", - "headings_color": "rgb(56, 115, 173)", + "color": "black", + "code_header_color": "black", + "focus_background_color": "#fdffd3", + "headings_color": "#3873ad", }, ) diff --git a/tests/rustdoc-gui/search-reexport.goml b/tests/rustdoc-gui/search-reexport.goml index fd817b58990c5..c5c386ce750ce 100644 --- a/tests/rustdoc-gui/search-reexport.goml +++ b/tests/rustdoc-gui/search-reexport.goml @@ -17,7 +17,7 @@ assert-attribute: ( assert-text: ("//a[@class='result-import']", "test_docs::TheStdReexport") click: "//a[@class='result-import']" // We check that it has the background modified thanks to the focus. -wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgb(73, 74, 61)"}) +wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "#494a3d"}) // We now check that the alias is working as well on the reexport. // To be SURE that the search will be run. @@ -30,4 +30,4 @@ assert-text: ( ) // Same thing again, we click on it to ensure the background is once again set as expected. click: "//a[@class='result-import']" -wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgb(73, 74, 61)"}) +wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "#494a3d"}) diff --git a/tests/rustdoc-gui/shortcuts.goml b/tests/rustdoc-gui/shortcuts.goml index 667df89ec9b00..2c61ee5428b86 100644 --- a/tests/rustdoc-gui/shortcuts.goml +++ b/tests/rustdoc-gui/shortcuts.goml @@ -13,7 +13,7 @@ press-key: "Escape" assert-css: ("#help-button .popover", {"display": "none"}) // Checking doc collapse and expand. // It should be displaying a "-": -assert-text: ("#toggle-all-docs", "[\u2212]") +assert-text: ("#toggle-all-docs", "[−]") press-key: "-" wait-for-text: ("#toggle-all-docs", "[+]") assert-attribute: ("#toggle-all-docs", {"class": "will-expand"}) @@ -23,9 +23,9 @@ assert-text: ("#toggle-all-docs", "[+]") assert-attribute: ("#toggle-all-docs", {"class": "will-expand"}) // Expanding now. press-key: "+" -wait-for-text: ("#toggle-all-docs", "[\u2212]") +wait-for-text: ("#toggle-all-docs", "[−]") assert-attribute: ("#toggle-all-docs", {"class": ""}) // Pressing it again shouldn't do anything. press-key: "+" -assert-text: ("#toggle-all-docs", "[\u2212]") +assert-text: ("#toggle-all-docs", "[−]") assert-attribute: ("#toggle-all-docs", {"class": ""}) diff --git a/tests/rustdoc-gui/source-code-page.goml b/tests/rustdoc-gui/source-code-page.goml index d5dd511b1d31f..f8f73398d9b99 100644 --- a/tests/rustdoc-gui/source-code-page.goml +++ b/tests/rustdoc-gui/source-code-page.goml @@ -64,23 +64,23 @@ call-function: ("check-colors", { compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y")) // Check the `href` property so that users can treat anchors as links. assert-property: (".src-line-numbers > a:nth-child(1)", { - "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#1" -}) + "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#1" +}, ENDS_WITH) assert-property: (".src-line-numbers > a:nth-child(2)", { - "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#2" -}) + "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#2" +}, ENDS_WITH) assert-property: (".src-line-numbers > a:nth-child(3)", { - "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#3" -}) + "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#3" +}, ENDS_WITH) assert-property: (".src-line-numbers > a:nth-child(4)", { - "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4" -}) + "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#4" +}, ENDS_WITH) assert-property: (".src-line-numbers > a:nth-child(5)", { - "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#5" -}) + "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#5" +}, ENDS_WITH) assert-property: (".src-line-numbers > a:nth-child(6)", { - "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#6" -}) + "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#6" +}, ENDS_WITH) // Assert that the line numbers text is aligned to the right. assert-css: (".src-line-numbers", {"text-align": "right"}) diff --git a/tests/rustdoc-js-std/bufread-fill-buf.js b/tests/rustdoc-js-std/bufread-fill-buf.js new file mode 100644 index 0000000000000..3828cf76026ea --- /dev/null +++ b/tests/rustdoc-js-std/bufread-fill-buf.js @@ -0,0 +1,13 @@ +// ignore-order + +const EXPECTED = [ + { + 'query': 'bufread -> result', + 'others': [ + { 'path': 'std::io::Split', 'name': 'next' }, + { 'path': 'std::boxed::Box', 'name': 'fill_buf' }, + { 'path': 'std::io::Chain', 'name': 'fill_buf' }, + { 'path': 'std::io::Take', 'name': 'fill_buf' }, + ], + }, +]; diff --git a/tests/rustdoc-js-std/never.js b/tests/rustdoc-js-std/never.js index ed3776b3c2ae0..27d415b5e486d 100644 --- a/tests/rustdoc-js-std/never.js +++ b/tests/rustdoc-js-std/never.js @@ -1,6 +1,14 @@ -const EXPECTED = { - 'query': '!', - 'others': [ - { 'path': 'std', 'name': 'never' }, - ], -}; +const EXPECTED = [ + { + 'query': '!', + 'others': [ + { 'path': 'std', 'name': 'never' }, + ], + }, + { + 'query': '!::clone', + 'others': [ + { 'path': 'std::never', 'name': 'clone' }, + ], + }, +]; diff --git a/tests/rustdoc-js-std/option-type-signatures.js b/tests/rustdoc-js-std/option-type-signatures.js index 8f6b0450dd319..2599785066145 100644 --- a/tests/rustdoc-js-std/option-type-signatures.js +++ b/tests/rustdoc-js-std/option-type-signatures.js @@ -12,4 +12,11 @@ const EXPECTED = [ { 'path': 'std::option::Option', 'name': 'get_or_insert_default' }, ], }, + { + 'query': 'option -> []', + 'others': [ + { 'path': 'std::option::Option', 'name': 'as_slice' }, + { 'path': 'std::option::Option', 'name': 'as_mut_slice' }, + ], + }, ]; diff --git a/tests/rustdoc-js-std/osstring-to-string.js b/tests/rustdoc-js-std/osstring-to-string.js new file mode 100644 index 0000000000000..17bb602a502af --- /dev/null +++ b/tests/rustdoc-js-std/osstring-to-string.js @@ -0,0 +1,9 @@ +// exact-match + +// https://github.com/rust-lang/rust/issues/60485#issuecomment-663900624 +const EXPECTED = { + 'query': 'OsString -> String', + 'others': [ + { 'path': 'std::ffi::OsString', 'name': 'into_string' }, + ] +}; diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js index aa8ee86d67247..af7f63f99cbdf 100644 --- a/tests/rustdoc-js-std/parser-errors.js +++ b/tests/rustdoc-js-std/parser-errors.js @@ -359,6 +359,15 @@ const PARSED = [ userQuery: "mod:a!", error: 'Invalid search type: macro `!` and `mod` both specified', }, + { + query: "mod:!", + elems: [], + foundElems: 0, + original: "mod:!", + returned: [], + userQuery: "mod:!", + error: 'Invalid search type: primitive never type `!` and `mod` both specified', + }, { query: "a!::a", elems: [], diff --git a/tests/rustdoc-js-std/parser-ident.js b/tests/rustdoc-js-std/parser-ident.js index d9ee5fb564b68..f65a7ce6692b0 100644 --- a/tests/rustdoc-js-std/parser-ident.js +++ b/tests/rustdoc-js-std/parser-ident.js @@ -8,11 +8,12 @@ const PARSED = [ pathLast: "r", generics: [ { - name: "!", - fullPath: ["!"], + name: "never", + fullPath: ["never"], pathWithoutLast: [], - pathLast: "!", + pathLast: "never", generics: [], + typeFilter: 15, }, ], typeFilter: -1, @@ -26,12 +27,12 @@ const PARSED = [ { query: "!", elems: [{ - name: "!", - fullPath: ["!"], + name: "never", + fullPath: ["never"], pathWithoutLast: [], - pathLast: "!", + pathLast: "never", generics: [], - typeFilter: -1, + typeFilter: 15, }], foundElems: 1, original: "!", @@ -64,12 +65,21 @@ const PARSED = [ userQuery: "a!::b", error: "Cannot have associated items in macros", }, + { + query: "!", + elems: [], + foundElems: 0, + original: "!", + returned: [], + userQuery: "!", + error: "Never type `!` does not accept generic parameters", + }, { query: "!::b", elems: [{ name: "!::b", - fullPath: ["!", "b"], - pathWithoutLast: ["!"], + fullPath: ["never", "b"], + pathWithoutLast: ["never"], pathLast: "b", generics: [], typeFilter: -1, @@ -80,6 +90,58 @@ const PARSED = [ userQuery: "!::b", error: null, }, + { + query: "b::!", + elems: [], + foundElems: 0, + original: "b::!", + returned: [], + userQuery: "b::!", + error: "Never type `!` is not associated item", + }, + { + query: "!::!", + elems: [], + foundElems: 0, + original: "!::!", + returned: [], + userQuery: "!::!", + error: "Never type `!` is not associated item", + }, + { + query: "b::!::c", + elems: [], + foundElems: 0, + original: "b::!::c", + returned: [], + userQuery: "b::!::c", + error: "Never type `!` is not associated item", + }, + { + query: "!::b", + elems: [{ + name: "!::b", + fullPath: ["never", "b"], + pathWithoutLast: ["never"], + pathLast: "b", + generics: [ + { + name: "t", + fullPath: ["t"], + pathWithoutLast: [], + pathLast: "t", + generics: [], + typeFilter: -1, + } + ], + typeFilter: -1, + }], + foundElems: 1, + original: "!::b", + returned: [], + userQuery: "!::b", + error: null, + }, { query: "a!::b!", elems: [], diff --git a/tests/rustdoc-js-std/parser-returned.js b/tests/rustdoc-js-std/parser-returned.js index 665e2a9b2e3d7..6ea86609115bf 100644 --- a/tests/rustdoc-js-std/parser-returned.js +++ b/tests/rustdoc-js-std/parser-returned.js @@ -84,12 +84,12 @@ const PARSED = [ foundElems: 1, original: "-> !", returned: [{ - name: "!", - fullPath: ["!"], + name: "never", + fullPath: ["never"], pathWithoutLast: [], - pathLast: "!", + pathLast: "never", generics: [], - typeFilter: -1, + typeFilter: 15, }], userQuery: "-> !", error: null, diff --git a/tests/rustdoc-js-std/parser-slice-array.js b/tests/rustdoc-js-std/parser-slice-array.js new file mode 100644 index 0000000000000..f85dd19974188 --- /dev/null +++ b/tests/rustdoc-js-std/parser-slice-array.js @@ -0,0 +1,305 @@ +const PARSED = [ + { + query: '[[[D, []]]', + elems: [], + foundElems: 0, + original: '[[[D, []]]', + returned: [], + userQuery: '[[[d, []]]', + error: 'Unclosed `[`', + }, + { + query: '[[[D, []]]]', + elems: [ + { + name: "[]", + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics: [ + { + name: "[]", + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics: [ + { + name: "[]", + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics: [ + { + name: "d", + fullPath: ["d"], + pathWithoutLast: [], + pathLast: "d", + generics: [], + typeFilter: -1, + }, + { + name: "[]", + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics: [], + typeFilter: 15, + }, + ], + typeFilter: 15, + }, + ], + typeFilter: 15, + }, + ], + typeFilter: 15, + }, + ], + foundElems: 1, + original: '[[[D, []]]]', + returned: [], + userQuery: '[[[d, []]]]', + error: null, + }, + { + query: '[] u8', + elems: [ + { + name: "[]", + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics: [], + typeFilter: 15, + }, + { + name: "u8", + fullPath: ["u8"], + pathWithoutLast: [], + pathLast: "u8", + generics: [], + typeFilter: -1, + }, + ], + foundElems: 2, + original: "[] u8", + returned: [], + userQuery: "[] u8", + error: null, + }, + { + query: '[u8]', + elems: [ + { + name: "[]", + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics: [ + { + name: "u8", + fullPath: ["u8"], + pathWithoutLast: [], + pathLast: "u8", + generics: [], + typeFilter: -1, + }, + ], + typeFilter: 15, + }, + ], + foundElems: 1, + original: "[u8]", + returned: [], + userQuery: "[u8]", + error: null, + }, + { + query: '[u8,u8]', + elems: [ + { + name: "[]", + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics: [ + { + name: "u8", + fullPath: ["u8"], + pathWithoutLast: [], + pathLast: "u8", + generics: [], + typeFilter: -1, + }, + { + name: "u8", + fullPath: ["u8"], + pathWithoutLast: [], + pathLast: "u8", + generics: [], + typeFilter: -1, + }, + ], + typeFilter: 15, + }, + ], + foundElems: 1, + original: "[u8,u8]", + returned: [], + userQuery: "[u8,u8]", + error: null, + }, + { + query: '[u8]', + elems: [ + { + name: "[]", + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics: [ + { + name: "u8", + fullPath: ["u8"], + pathWithoutLast: [], + pathLast: "u8", + generics: [ + { + name: "u8", + fullPath: ["u8"], + pathWithoutLast: [], + pathLast: "u8", + generics: [], + typeFilter: -1, + }, + ], + typeFilter: -1, + }, + ], + typeFilter: 15, + }, + ], + foundElems: 1, + original: "[u8]", + returned: [], + userQuery: "[u8]", + error: null, + }, + { + query: '[]', + elems: [ + { + name: "[]", + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics: [], + typeFilter: 15, + }, + ], + foundElems: 1, + original: "[]", + returned: [], + userQuery: "[]", + error: null, + }, + { + query: '[>', + elems: [], + foundElems: 0, + original: "[>", + returned: [], + userQuery: "[>", + error: "Unexpected `>` after `[`", + }, + { + query: '[<', + elems: [], + foundElems: 0, + original: "[<", + returned: [], + userQuery: "[<", + error: "Found generics without a path", + }, + { + query: '[a>', + elems: [], + foundElems: 0, + original: "[a>", + returned: [], + userQuery: "[a>", + error: "Unexpected `>` after `[`", + }, + { + query: '[a<', + elems: [], + foundElems: 0, + original: "[a<", + returned: [], + userQuery: "[a<", + error: "Unclosed `<`", + }, + { + query: '[a', + elems: [], + foundElems: 0, + original: "[a", + returned: [], + userQuery: "[a", + error: "Unclosed `[`", + }, + { + query: '[', + elems: [], + foundElems: 0, + original: "[", + returned: [], + userQuery: "[", + error: "Unclosed `[`", + }, + { + query: ']', + elems: [], + foundElems: 0, + original: "]", + returned: [], + userQuery: "]", + error: "Unexpected `]`", + }, + { + query: 'primitive:[u8]', + elems: [ + { + name: "[]", + fullPath: ["[]"], + pathWithoutLast: [], + pathLast: "[]", + generics: [ + { + name: "u8", + fullPath: ["u8"], + pathWithoutLast: [], + pathLast: "u8", + generics: [], + typeFilter: -1, + }, + ], + typeFilter: 15, + }, + ], + foundElems: 1, + original: "primitive:[u8]", + returned: [], + userQuery: "primitive:[u8]", + error: null, + }, + { + query: 'macro:[u8]', + elems: [], + foundElems: 0, + original: "macro:[u8]", + returned: [], + userQuery: "macro:[u8]", + error: "Invalid search type: primitive `[]` and `macro` both specified", + }, +]; diff --git a/tests/rustdoc-js/generics-match-ambiguity.js b/tests/rustdoc-js/generics-match-ambiguity.js new file mode 100644 index 0000000000000..a9932a16ca38b --- /dev/null +++ b/tests/rustdoc-js/generics-match-ambiguity.js @@ -0,0 +1,91 @@ +// ignore-order +// exact-check + +// Make sure that results are order-agnostic, even when there's search items that only differ +// by generics. + +const EXPECTED = [ + { + 'query': 'Wrap', + 'in_args': [ + { 'path': 'generics_match_ambiguity', 'name': 'bar' }, + { 'path': 'generics_match_ambiguity', 'name': 'foo' }, + ], + }, + { + 'query': 'Wrap', + 'in_args': [ + { 'path': 'generics_match_ambiguity', 'name': 'bar' }, + { 'path': 'generics_match_ambiguity', 'name': 'foo' }, + ], + }, + { + 'query': 'Wrap, Wrap', + 'others': [ + { 'path': 'generics_match_ambiguity', 'name': 'bar' }, + { 'path': 'generics_match_ambiguity', 'name': 'foo' }, + ], + }, + { + 'query': 'Wrap, Wrap', + 'others': [ + { 'path': 'generics_match_ambiguity', 'name': 'bar' }, + { 'path': 'generics_match_ambiguity', 'name': 'foo' }, + ], + }, + { + 'query': 'W3, W3', + 'others': [ + { 'path': 'generics_match_ambiguity', 'name': 'baaa' }, + { 'path': 'generics_match_ambiguity', 'name': 'baab' }, + { 'path': 'generics_match_ambiguity', 'name': 'baac' }, + { 'path': 'generics_match_ambiguity', 'name': 'baad' }, + { 'path': 'generics_match_ambiguity', 'name': 'baae' }, + { 'path': 'generics_match_ambiguity', 'name': 'baaf' }, + { 'path': 'generics_match_ambiguity', 'name': 'baag' }, + { 'path': 'generics_match_ambiguity', 'name': 'baah' }, + ], + }, + { + 'query': 'W3, W3', + 'others': [ + { 'path': 'generics_match_ambiguity', 'name': 'baaa' }, + { 'path': 'generics_match_ambiguity', 'name': 'baab' }, + { 'path': 'generics_match_ambiguity', 'name': 'baac' }, + { 'path': 'generics_match_ambiguity', 'name': 'baad' }, + { 'path': 'generics_match_ambiguity', 'name': 'baae' }, + { 'path': 'generics_match_ambiguity', 'name': 'baaf' }, + { 'path': 'generics_match_ambiguity', 'name': 'baag' }, + { 'path': 'generics_match_ambiguity', 'name': 'baah' }, + ], + }, + { + 'query': 'W2, W2', + 'others': [ + { 'path': 'generics_match_ambiguity', 'name': 'baag' }, + { 'path': 'generics_match_ambiguity', 'name': 'baah' }, + ], + }, + { + 'query': 'W2, W2', + 'others': [ + { 'path': 'generics_match_ambiguity', 'name': 'baag' }, + { 'path': 'generics_match_ambiguity', 'name': 'baah' }, + ], + }, + { + 'query': 'W2, W3', + 'others': [ + { 'path': 'generics_match_ambiguity', 'name': 'baac' }, + { 'path': 'generics_match_ambiguity', 'name': 'baaf' }, + { 'path': 'generics_match_ambiguity', 'name': 'baag' }, + ], + }, + { + 'query': 'W2, W2', + 'others': [ + { 'path': 'generics_match_ambiguity', 'name': 'baag' }, + { 'path': 'generics_match_ambiguity', 'name': 'baah' }, + ], + }, +]; diff --git a/tests/rustdoc-js/generics-match-ambiguity.rs b/tests/rustdoc-js/generics-match-ambiguity.rs new file mode 100644 index 0000000000000..79c493856ebc7 --- /dev/null +++ b/tests/rustdoc-js/generics-match-ambiguity.rs @@ -0,0 +1,17 @@ +pub struct Wrap(pub T, pub U); + +pub fn foo(a: Wrap, b: Wrap) {} +pub fn bar(a: Wrap, b: Wrap) {} + +pub struct W2(pub T); +pub struct W3(pub T, pub U); + +pub fn baaa(a: W3, b: W3) {} +pub fn baab(a: W3, b: W3) {} +pub fn baac(a: W2>, b: W3) {} +pub fn baad(a: W2>, b: W3) {} +pub fn baae(a: W3, b: W2>) {} +pub fn baaf(a: W3, b: W2>) {} +pub fn baag(a: W2>, b: W2>) {} +pub fn baah(a: W2>, b: W2>) {} +// diff --git a/tests/rustdoc-js/nested-unboxed.js b/tests/rustdoc-js/nested-unboxed.js new file mode 100644 index 0000000000000..44f784eb1f638 --- /dev/null +++ b/tests/rustdoc-js/nested-unboxed.js @@ -0,0 +1,68 @@ +// exact-check + +const EXPECTED = [ + { + 'query': '-> Result', + 'others': [ + { 'path': 'nested_unboxed', 'name': 'something' }, + ], + }, + { + 'query': '-> Result, bool>', + 'others': [ + { 'path': 'nested_unboxed', 'name': 'something' }, + ], + }, + { + 'query': '-> Object, bool', + 'others': [ + { 'path': 'nested_unboxed', 'name': 'something' }, + ], + }, + { + 'query': '-> Object, bool', + 'others': [ + { 'path': 'nested_unboxed', 'name': 'something' }, + ], + }, + { + 'query': '-> i32, u32, bool', + 'others': [ + { 'path': 'nested_unboxed', 'name': 'something' }, + ], + }, + { + 'query': '-> Result', + 'others': [ + { 'path': 'nested_unboxed', 'name': 'something' }, + ], + }, + { + 'query': '-> Result, bool>', + 'others': [ + { 'path': 'nested_unboxed', 'name': 'something' }, + ], + }, + { + 'query': '-> Result, bool>', + 'others': [ + { 'path': 'nested_unboxed', 'name': 'something' }, + ], + }, + { + 'query': '-> Result, u32, bool>', + 'others': [], + }, + { + 'query': '-> Result, bool>', + 'others': [], + }, + { + 'query': '-> Result>', + 'others': [], + }, + { + 'query': '-> Result, Object, bool>', + 'others': [], + }, +]; diff --git a/tests/rustdoc-js/nested-unboxed.rs b/tests/rustdoc-js/nested-unboxed.rs new file mode 100644 index 0000000000000..57f9592b79147 --- /dev/null +++ b/tests/rustdoc-js/nested-unboxed.rs @@ -0,0 +1,5 @@ +pub struct Object(T, U); + +pub fn something() -> Result, bool> { + loop {} +} diff --git a/tests/rustdoc-js/never-search.js b/tests/rustdoc-js/never-search.js new file mode 100644 index 0000000000000..ed24d693133ba --- /dev/null +++ b/tests/rustdoc-js/never-search.js @@ -0,0 +1,46 @@ +// exact-check + +const EXPECTED = [ + { + 'query': '-> !', + 'others': [ + { 'path': 'never_search', 'name': 'loops' }, + ], + }, + { + 'query': '-> never', + 'others': [ + { 'path': 'never_search', 'name': 'loops' }, + { 'path': 'never_search', 'name': 'returns' }, + ], + }, + { + 'query': '!', + 'in_args': [ + { 'path': 'never_search', 'name': 'impossible' }, + { 'path': 'never_search', 'name': 'box_impossible' }, + ], + }, + { + 'query': 'never', + 'in_args': [ + { 'path': 'never_search', 'name': 'impossible' }, + { 'path': 'never_search', 'name': 'uninteresting' }, + { 'path': 'never_search', 'name': 'box_impossible' }, + { 'path': 'never_search', 'name': 'box_uninteresting' }, + ], + }, + { + 'query': 'box', + 'in_args': [ + { 'path': 'never_search', 'name': 'box_impossible' }, + ], + }, + { + 'query': 'box', + 'in_args': [ + { 'path': 'never_search', 'name': 'box_impossible' }, + { 'path': 'never_search', 'name': 'box_uninteresting' }, + ], + }, +]; diff --git a/tests/rustdoc-js/never-search.rs b/tests/rustdoc-js/never-search.rs new file mode 100644 index 0000000000000..299b4660dae9e --- /dev/null +++ b/tests/rustdoc-js/never-search.rs @@ -0,0 +1,13 @@ +#![feature(never_type)] + +#[allow(nonstandard_style)] +pub struct never; + +pub fn loops() -> ! { loop {} } +pub fn returns() -> never { never } + +pub fn impossible(x: !) { match x {} } +pub fn uninteresting(x: never) { match x { never => {} } } + +pub fn box_impossible(x: Box) { match *x {} } +pub fn box_uninteresting(x: Box) { match *x { never => {} } } diff --git a/tests/rustdoc-js/slice-array.js b/tests/rustdoc-js/slice-array.js index 1c06566920c2b..d676d0577c583 100644 --- a/tests/rustdoc-js/slice-array.js +++ b/tests/rustdoc-js/slice-array.js @@ -51,4 +51,23 @@ const EXPECTED = [ { 'path': 'slice_array', 'name': 'gamma' }, ], }, + { + 'query': '[TraitCat]', + 'in_args': [ + { 'path': 'slice_array', 'name': 'gamma' }, + { 'path': 'slice_array', 'name': 'epsilon' }, + ], + }, + { + 'query': 'R<[Q]>', + 'returned': [ + { 'path': 'slice_array', 'name': 'bet' }, + ], + }, + { + 'query': 'R<[P]>', + 'in_args': [ + { 'path': 'slice_array', 'name': 'alpha' }, + ], + }, ]; diff --git a/tests/rustdoc-js/slice-array.rs b/tests/rustdoc-js/slice-array.rs index 2523b21cfaa50..15ac4294f3d79 100644 --- a/tests/rustdoc-js/slice-array.rs +++ b/tests/rustdoc-js/slice-array.rs @@ -14,3 +14,5 @@ pub trait TraitCat {} pub trait TraitDog {} pub fn gamma(t: [T; 32]) {} + +pub fn epsilon(t: &[T]) {} diff --git a/tests/rustdoc/issue-112515-impl-ty-alias.rs b/tests/rustdoc/issue-112515-impl-ty-alias.rs new file mode 100644 index 0000000000000..161188ee5762f --- /dev/null +++ b/tests/rustdoc/issue-112515-impl-ty-alias.rs @@ -0,0 +1,30 @@ +// Regression test for . +// It's to ensure that this code doesn't have infinite loop in rustdoc when +// trying to retrive type alias implementations. + +// ignore-tidy-linelength + +pub type Boom = S, ()>, ()>, ()>, u8>, ()>, u8>, ()>, u8>, u8>, ()>, ()>, ()>, u8>, u8>, u8>, ()>, ()>, u8>, ()>, ()>, ()>, u8>, u8>, ()>, ()>, ()>, ()>, ()>, u8>, ()>, ()>, u8>, ()>, ()>, ()>, u8>, ()>, ()>, u8>, u8>, u8>, u8>, ()>, u8>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>; +pub struct S(T, U); + +pub trait A {} + +pub trait B { + type P; +} + +impl A for u64 {} + +impl A for S {} + +impl B for S +where + T: B, + >::P: A, +{ + type P = (); +} + +impl B for S { + type P = (); +} diff --git a/tests/rustdoc/issue-32077-type-alias-impls.rs b/tests/rustdoc/issue-32077-type-alias-impls.rs deleted file mode 100644 index 555d0579bee79..0000000000000 --- a/tests/rustdoc/issue-32077-type-alias-impls.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Regression test for . - -#![crate_name = "foo"] - -pub struct GenericStruct(T); - -impl GenericStruct { - pub fn on_gen(arg: T) {} -} - -impl GenericStruct { - pub fn on_u32(arg: u32) {} -} - -pub trait Foo {} -pub trait Bar {} - -impl Foo for GenericStruct {} -impl Bar for GenericStruct {} - -// @has 'foo/type.TypedefStruct.html' -// We check that we have the implementation of the type alias itself. -// @has - '//*[@id="impl-TypedefStruct"]/h3' 'impl TypedefStruct' -// @has - '//*[@id="method.on_alias"]/h4' 'pub fn on_alias()' -// @has - '//*[@id="impl-GenericStruct%3CT%3E"]/h3' 'impl GenericStruct' -// @has - '//*[@id="method.on_gen"]/h4' 'pub fn on_gen(arg: T)' -// @has - '//*[@id="impl-Foo-for-GenericStruct%3CT%3E"]/h3' 'impl Foo for GenericStruct' -// This trait implementation doesn't match the type alias parameters so shouldn't appear in docs. -// @!has - '//h3' 'impl Bar for GenericStruct {}' -// Same goes for the `Deref` impl. -// @!has - '//h2' 'Methods from Deref' -pub type TypedefStruct = GenericStruct; - -impl TypedefStruct { - pub fn on_alias() {} -} - -impl std::ops::Deref for GenericStruct { - type Target = u32; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -pub struct Wrap(GenericStruct); - -// @has 'foo/type.Alias.html' -// @has - '//h2' 'Methods from Deref' -// @has - '//*[@id="impl-Deref-for-Wrap%3CT%3E"]/h3' 'impl Deref for Wrap' -pub type Alias = Wrap; - -impl std::ops::Deref for Wrap { - type Target = GenericStruct; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} diff --git a/tests/ui/assign-assign.rs b/tests/ui/assign-assign.rs index bcf506b398b9e..9db8fb008cf2e 100644 --- a/tests/ui/assign-assign.rs +++ b/tests/ui/assign-assign.rs @@ -6,7 +6,7 @@ fn test_assign() { let y: () = x = 10; assert_eq!(x, 10); assert_eq!(y, ()); - let mut z = x = 11; + let mut z: () = x = 11; assert_eq!(x, 11); assert_eq!(z, ()); z = x = 12; @@ -19,7 +19,7 @@ fn test_assign_op() { let y: () = x += 10; assert_eq!(x, 10); assert_eq!(y, ()); - let mut z = x += 11; + let mut z: () = x += 11; assert_eq!(x, 21); assert_eq!(z, ()); z = x += 12; diff --git a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs new file mode 100644 index 0000000000000..40896c32e1113 --- /dev/null +++ b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs @@ -0,0 +1,10 @@ +trait Trait { + const ASSOC: i32; +} + +impl Trait for () { + const ASSOC: &dyn Fn(_) = 1i32; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants +} + +fn main() {} diff --git a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr new file mode 100644 index 0000000000000..993a08faba990 --- /dev/null +++ b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr @@ -0,0 +1,9 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants + --> $DIR/infer-placeholder-in-non-suggestable-pos.rs:6:26 + | +LL | const ASSOC: &dyn Fn(_) = 1i32; + | ^ not allowed in type signatures + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/associated-inherent-types/issue-111404-0.rs b/tests/ui/associated-inherent-types/issue-111404-0.rs new file mode 100644 index 0000000000000..1180577bd5421 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-111404-0.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Foo(T); + +impl<'a> Foo { + type Assoc = &'a (); +} + +fn bar(_: for<'a> fn(Foo::Assoc)>::Assoc)) {} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-111404-1.rs b/tests/ui/associated-inherent-types/issue-111404-1.rs new file mode 100644 index 0000000000000..f4ad5d7ff6c03 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-111404-1.rs @@ -0,0 +1,13 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Foo(T); + +impl<'a> Foo { + type Assoc = &'a (); +} + +fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {} +//~^ ERROR higher-ranked subtype error + +fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-111404-1.stderr b/tests/ui/associated-inherent-types/issue-111404-1.stderr new file mode 100644 index 0000000000000..c55f1432389c7 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-111404-1.stderr @@ -0,0 +1,8 @@ +error: higher-ranked subtype error + --> $DIR/issue-111404-1.rs:10:1 + | +LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/associated-inherent-types/private-in-public.rs b/tests/ui/associated-inherent-types/private-in-public.rs index a4b372537c789..44a20a79ad625 100644 --- a/tests/ui/associated-inherent-types/private-in-public.rs +++ b/tests/ui/associated-inherent-types/private-in-public.rs @@ -3,6 +3,11 @@ #![crate_type = "lib"] #![deny(private_in_public)] +#![warn(private_interfaces)] + +// In this test both old and new private-in-public diagnostic were emitted. +// Old diagnostic will be deleted soon. +// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. pub type PubAlias0 = PubTy::PrivAssocTy; //~^ ERROR private associated type `PubTy::PrivAssocTy` in public interface (error E0446) diff --git a/tests/ui/associated-inherent-types/private-in-public.stderr b/tests/ui/associated-inherent-types/private-in-public.stderr index f0a64e96179ac..d40db83707bbb 100644 --- a/tests/ui/associated-inherent-types/private-in-public.stderr +++ b/tests/ui/associated-inherent-types/private-in-public.stderr @@ -1,5 +1,5 @@ error: private associated type `PubTy::PrivAssocTy` in public interface (error E0446) - --> $DIR/private-in-public.rs:7:1 + --> $DIR/private-in-public.rs:12:1 | LL | pub type PubAlias0 = PubTy::PrivAssocTy; | ^^^^^^^^^^^^^^^^^^ @@ -12,8 +12,26 @@ note: the lint level is defined here LL | #![deny(private_in_public)] | ^^^^^^^^^^^^^^^^^ +warning: associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0` + | +note: type alias `PubAlias0` is reachable at visibility `pub` + --> $DIR/private-in-public.rs:12:1 + | +LL | pub type PubAlias0 = PubTy::PrivAssocTy; + | ^^^^^^^^^^^^^^^^^^ +note: but associated type `PubTy::PrivAssocTy` is only usable at visibility `pub(crate)` + --> $DIR/private-in-public.rs:24:5 + | +LL | type PrivAssocTy = (); + | ^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/private-in-public.rs:6:9 + | +LL | #![warn(private_interfaces)] + | ^^^^^^^^^^^^^^^^^^ + error: private type `PrivTy` in public interface (error E0446) - --> $DIR/private-in-public.rs:10:1 + --> $DIR/private-in-public.rs:15:1 | LL | pub type PubAlias1 = PrivTy::PubAssocTy; | ^^^^^^^^^^^^^^^^^^ @@ -21,8 +39,21 @@ LL | pub type PubAlias1 = PrivTy::PubAssocTy; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 +warning: type `PrivTy` is more private than the item `PubAlias1` + | +note: type alias `PubAlias1` is reachable at visibility `pub` + --> $DIR/private-in-public.rs:15:1 + | +LL | pub type PubAlias1 = PrivTy::PubAssocTy; + | ^^^^^^^^^^^^^^^^^^ +note: but type `PrivTy` is only usable at visibility `pub(crate)` + --> $DIR/private-in-public.rs:28:1 + | +LL | struct PrivTy; + | ^^^^^^^^^^^^^ + error: private type `PrivTy` in public interface (error E0446) - --> $DIR/private-in-public.rs:13:1 + --> $DIR/private-in-public.rs:18:1 | LL | pub type PubAlias2 = PubTy::PubAssocTy; | ^^^^^^^^^^^^^^^^^^ @@ -30,5 +61,18 @@ LL | pub type PubAlias2 = PubTy::PubAssocTy; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 -error: aborting due to 3 previous errors +warning: type `PrivTy` is more private than the item `PubAlias2` + | +note: type alias `PubAlias2` is reachable at visibility `pub` + --> $DIR/private-in-public.rs:18:1 + | +LL | pub type PubAlias2 = PubTy::PubAssocTy; + | ^^^^^^^^^^^^^^^^^^ +note: but type `PrivTy` is only usable at visibility `pub(crate)` + --> $DIR/private-in-public.rs:28:1 + | +LL | struct PrivTy; + | ^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors; 3 warnings emitted diff --git a/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs b/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs index a8d00803a534a..a3f4717791abd 100644 --- a/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs +++ b/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs @@ -59,8 +59,8 @@ fn def_et4() -> Et4 { pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } fn main() { - let _ = use_et1(); - let _ = use_et2(); - let _ = use_et3(); - let _ = use_et4(); + use_et1(); + use_et2(); + use_et3(); + use_et4(); } diff --git a/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs b/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs index 08f965452ef48..52199124ea3b5 100644 --- a/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs +++ b/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs @@ -66,8 +66,8 @@ fn def_et4() -> Box Tr2<'a>>> { pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } fn main() { - let _ = use_et1(); - let _ = use_et2(); - let _ = use_et3(); - let _ = use_et4(); + use_et1(); + use_et2(); + use_et3(); + use_et4(); } diff --git a/tests/ui/associated-type-bounds/rpit.rs b/tests/ui/associated-type-bounds/rpit.rs index 47cadf3310bd8..59c7733fbe4ba 100644 --- a/tests/ui/associated-type-bounds/rpit.rs +++ b/tests/ui/associated-type-bounds/rpit.rs @@ -57,8 +57,8 @@ fn def_et4() -> impl Tr1 Tr2<'a>> { pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } fn main() { - let _ = use_et1(); - let _ = use_et2(); - let _ = use_et3(); - let _ = use_et4(); + use_et1(); + use_et2(); + use_et3(); + use_et4(); } diff --git a/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs b/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs index e223a89574170..93a44c01ce053 100644 --- a/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs +++ b/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs @@ -89,8 +89,8 @@ pub fn use_et4() { } fn main() { - let _ = use_et1(); - let _ = use_et2(); - let _ = use_et3(); - let _ = use_et4(); + use_et1(); + use_et2(); + use_et3(); + use_et4(); } diff --git a/tests/ui/associated-types/normalization-debruijn-3.rs b/tests/ui/associated-types/normalization-debruijn-3.rs index 2bea78cf7bd69..bd9a8fcf4925f 100644 --- a/tests/ui/associated-types/normalization-debruijn-3.rs +++ b/tests/ui/associated-types/normalization-debruijn-3.rs @@ -6,10 +6,10 @@ use std::future::{Future, Ready}; async fn read() { - let _ = connect(&()).await; + connect(&()).await; } async fn connect(addr: A) { - let _ = addr.to_socket_addr().await; + addr.to_socket_addr().await; } pub trait ToSocketAddr { type Future: Future; diff --git a/tests/ui/async-await/drop-track-field-assign.rs b/tests/ui/async-await/drop-track-field-assign.rs index dd0e3f11ccc01..b79d2af066a37 100644 --- a/tests/ui/async-await/drop-track-field-assign.rs +++ b/tests/ui/async-await/drop-track-field-assign.rs @@ -21,7 +21,7 @@ impl Agent { let mut info = self.info_result.clone(); info.node = Some("bar".into()); let element = parse_info(info); - let _ = send_element(element).await; + send_element(element).await; } } diff --git a/tests/ui/async-await/field-assign.rs b/tests/ui/async-await/field-assign.rs index dd0e3f11ccc01..b79d2af066a37 100644 --- a/tests/ui/async-await/field-assign.rs +++ b/tests/ui/async-await/field-assign.rs @@ -21,7 +21,7 @@ impl Agent { let mut info = self.info_result.clone(); info.node = Some("bar".into()); let element = parse_info(info); - let _ = send_element(element).await; + send_element(element).await; } } diff --git a/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr b/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr index 4b575a3d3b47a..60b7551ff8ad5 100644 --- a/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr +++ b/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr @@ -6,13 +6,13 @@ LL | pub fn foo() -> impl Future + Send { | = help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)` note: future is not `Send` as this value is used across an await - --> $DIR/issue-64130-4-async-move.rs:27:32 + --> $DIR/issue-64130-4-async-move.rs:27:23 | LL | match client.status() { | ------ has type `&Client` which is not `Send` LL | 200 => { -LL | let _x = get().await; - | ^^^^^ await occurs here, with `client` maybe used later +LL | get().await; + | ^^^^^ await occurs here, with `client` maybe used later ... LL | } | - `client` is later dropped here diff --git a/tests/ui/async-await/issue-64130-4-async-move.rs b/tests/ui/async-await/issue-64130-4-async-move.rs index bcb297aaa0258..5d68a808b1769 100644 --- a/tests/ui/async-await/issue-64130-4-async-move.rs +++ b/tests/ui/async-await/issue-64130-4-async-move.rs @@ -24,7 +24,7 @@ pub fn foo() -> impl Future + Send { async move { match client.status() { 200 => { - let _x = get().await; + get().await; } _ => (), } diff --git a/tests/ui/async-await/non-trivial-drop.rs b/tests/ui/async-await/non-trivial-drop.rs index d4df9d439c5f1..258da0756de31 100644 --- a/tests/ui/async-await/non-trivial-drop.rs +++ b/tests/ui/async-await/non-trivial-drop.rs @@ -7,7 +7,7 @@ #![feature(generators)] fn main() { - let _ = foo(); + foo(); } fn foo() { diff --git a/tests/ui/cfg/cfg_stmt_expr.rs b/tests/ui/cfg/cfg_stmt_expr.rs index 6381bb2d58877..f9f4c98102c99 100644 --- a/tests/ui/cfg/cfg_stmt_expr.rs +++ b/tests/ui/cfg/cfg_stmt_expr.rs @@ -81,7 +81,7 @@ fn main() { // check that lints work #[allow(non_snake_case)] - let FOOBAR = { + let FOOBAR: () = { fn SYLADEX() {} }; diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs b/tests/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs index 03400e0ee8d56..6d4cf6fa553b7 100644 --- a/tests/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs +++ b/tests/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs @@ -15,7 +15,7 @@ struct Struct { fn main() { let mut s = Struct { x: 10, y: 10, s: String::new() }; - let mut c = { + let mut c = || { s.x += 10; s.y += 42; s.s = String::from("new"); diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs b/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs index d2375aa69ec25..a386e9f40ccaf 100644 --- a/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs +++ b/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs @@ -2,7 +2,7 @@ //check-pass #![warn(unused)] #![feature(rustc_attrs)] -#![feature(btree_drain_filter)] +#![feature(btree_extract_if)] use std::collections::BTreeMap; use std::panic::{catch_unwind, AssertUnwindSafe}; @@ -14,14 +14,14 @@ fn main() { map.insert("c", ()); { - let mut it = map.drain_filter(|_, _| true); + let mut it = map.extract_if(|_, _| true); catch_unwind(AssertUnwindSafe(|| while it.next().is_some() {})).unwrap_err(); let result = catch_unwind(AssertUnwindSafe(|| it.next())); assert!(matches!(result, Ok(None))); } { - let mut it = map.drain_filter(|_, _| true); + let mut it = map.extract_if(|_, _| true); catch_unwind(AssertUnwindSafe(|| while let Some(_) = it.next() {})).unwrap_err(); let result = catch_unwind(AssertUnwindSafe(|| it.next())); assert!(matches!(result, Ok(None))); diff --git a/tests/ui/const-generics/generic_arg_infer/in-signature.rs b/tests/ui/const-generics/generic_arg_infer/in-signature.rs index 1f60b2242411d..cd852a269435e 100644 --- a/tests/ui/const-generics/generic_arg_infer/in-signature.rs +++ b/tests/ui/const-generics/generic_arg_infer/in-signature.rs @@ -33,15 +33,15 @@ static TY_STATIC_MIXED: Bar<_, _> = Bar::(0); //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables trait ArrAssocConst { const ARR: [u8; _]; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants } trait TyAssocConst { const ARR: Bar; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants } trait TyAssocConstMixed { const ARR: Bar<_, _>; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants } trait AssocTy { diff --git a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr index 52d1b29f93222..b32018a6a2d22 100644 --- a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr +++ b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr @@ -74,19 +74,19 @@ LL | static TY_STATIC_MIXED: Bar<_, _> = Bar::(0); | not allowed in type signatures | help: replace with the correct type: `Bar` -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/in-signature.rs:35:21 | LL | const ARR: [u8; _]; | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/in-signature.rs:39:25 | LL | const ARR: Bar; | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/in-signature.rs:43:20 | LL | const ARR: Bar<_, _>; diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs index 8023b998a4099..96b769699ccd4 100644 --- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs +++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs @@ -2,6 +2,12 @@ #![feature(generic_const_exprs)] #![allow(incomplete_features)] +#![warn(private_interfaces)] + +// In this test both old and new private-in-public diagnostic were emitted. +// Old diagnostic will be deleted soon. +// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. + pub struct Const; pub trait Trait { diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr index 2d9de8805bb55..465621619b4d4 100644 --- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr +++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr @@ -1,5 +1,5 @@ error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface - --> $DIR/eval-privacy.rs:16:5 + --> $DIR/eval-privacy.rs:22:5 | LL | type AssocTy = Const<{ my_const_fn(U) }>; | ^^^^^^^^^^^^ can't leak private type @@ -7,6 +7,24 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>; LL | const fn my_const_fn(val: u8) -> u8 { | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private -error: aborting due to previous error +warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item ` as Trait>::AssocTy` + | +note: associated type ` as Trait>::AssocTy` is reachable at visibility `pub` + --> $DIR/eval-privacy.rs:22:5 + | +LL | type AssocTy = Const<{ my_const_fn(U) }>; + | ^^^^^^^^^^^^ +note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)` + --> $DIR/eval-privacy.rs:29:1 + | +LL | const fn my_const_fn(val: u8) -> u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/eval-privacy.rs:5:9 + | +LL | #![warn(private_interfaces)] + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-86710.rs b/tests/ui/const-generics/generic_const_exprs/issue-86710.rs index bdd8a21b3b991..281b12458e3d9 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-86710.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-86710.rs @@ -7,7 +7,7 @@ use std::marker::PhantomData; fn main() { let x = FooImpl::> { phantom: PhantomData }; - let _ = x.foo::>(); + x.foo::>(); } trait Foo diff --git a/tests/ui/const-generics/issue-112505-overflow.rs b/tests/ui/const-generics/issue-112505-overflow.rs new file mode 100644 index 0000000000000..0dd7776d59544 --- /dev/null +++ b/tests/ui/const-generics/issue-112505-overflow.rs @@ -0,0 +1,7 @@ +#![feature(transmute_generic_consts)] + +fn overflow(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 777777777]; 239] { + unsafe { std::mem::transmute(v) } //~ ERROR cannot transmute between types of different sizes +} + +fn main() { } diff --git a/tests/ui/const-generics/issue-112505-overflow.stderr b/tests/ui/const-generics/issue-112505-overflow.stderr new file mode 100644 index 0000000000000..0432f2fa8be5d --- /dev/null +++ b/tests/ui/const-generics/issue-112505-overflow.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/issue-112505-overflow.rs:4:14 + | +LL | unsafe { std::mem::transmute(v) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type `[[[u32; 8888888]; 9999999]; 777777777]` are too big for the current architecture) + = note: target type: `[[[u32; 9999999]; 777777777]; 239]` (59484438436515561504 bits) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/const-generics/issues/issue-70273-assoc-fn.rs b/tests/ui/const-generics/issues/issue-70273-assoc-fn.rs index a76488249173a..f02ab355f9bb6 100644 --- a/tests/ui/const-generics/issues/issue-70273-assoc-fn.rs +++ b/tests/ui/const-generics/issues/issue-70273-assoc-fn.rs @@ -10,5 +10,5 @@ impl T<0usize> for S { } fn main() { - let _err = >::f(); + >::f(); } diff --git a/tests/ui/consts/assoc_const_generic_impl.rs b/tests/ui/consts/assoc_const_generic_impl.rs index 3475c862bfc2d..ba358628d15dc 100644 --- a/tests/ui/consts/assoc_const_generic_impl.rs +++ b/tests/ui/consts/assoc_const_generic_impl.rs @@ -8,7 +8,7 @@ trait ZeroSized: Sized { impl ZeroSized for T { const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::()]; //~ ERROR evaluation of `::I_AM_ZERO_SIZED` failed fn requires_zero_size(self) { - let () = Self::I_AM_ZERO_SIZED; + Self::I_AM_ZERO_SIZED; println!("requires_zero_size called"); } } diff --git a/tests/ui/consts/const-eval/erroneous-const.rs b/tests/ui/consts/const-eval/erroneous-const.rs index e0fd057a241a5..74d44c5259a3e 100644 --- a/tests/ui/consts/const-eval/erroneous-const.rs +++ b/tests/ui/consts/const-eval/erroneous-const.rs @@ -10,7 +10,7 @@ const fn no_codegen() { if false { // This bad constant is only used in dead code in a no-codegen function... and yet we still // must make sure that the build fails. - let _ = PrintName::::VOID; //~ constant + PrintName::::VOID; //~ constant } } diff --git a/tests/ui/consts/const-eval/erroneous-const.stderr b/tests/ui/consts/const-eval/erroneous-const.stderr index 03030392a5132..770f95062ab30 100644 --- a/tests/ui/consts/const-eval/erroneous-const.stderr +++ b/tests/ui/consts/const-eval/erroneous-const.stderr @@ -5,10 +5,10 @@ LL | const VOID: () = [()][2]; | ^^^^^^^ index out of bounds: the length is 1 but the index is 2 note: erroneous constant used - --> $DIR/erroneous-const.rs:13:17 + --> $DIR/erroneous-const.rs:13:13 | -LL | let _ = PrintName::::VOID; - | ^^^^^^^^^^^^^^^^^^^^ +LL | PrintName::::VOID; + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/consts/const-eval/erroneous-const2.rs b/tests/ui/consts/const-eval/erroneous-const2.rs index 15c0f910728a9..61f2955f2d822 100644 --- a/tests/ui/consts/const-eval/erroneous-const2.rs +++ b/tests/ui/consts/const-eval/erroneous-const2.rs @@ -10,7 +10,7 @@ pub static FOO: () = { if false { // This bad constant is only used in dead code in a static initializer... and yet we still // must make sure that the build fails. - let _ = PrintName::::VOID; //~ constant + PrintName::::VOID; //~ constant } }; diff --git a/tests/ui/consts/const-eval/erroneous-const2.stderr b/tests/ui/consts/const-eval/erroneous-const2.stderr index 8626f4d783397..082c2876575a6 100644 --- a/tests/ui/consts/const-eval/erroneous-const2.stderr +++ b/tests/ui/consts/const-eval/erroneous-const2.stderr @@ -5,10 +5,10 @@ LL | const VOID: () = [()][2]; | ^^^^^^^ index out of bounds: the length is 1 but the index is 2 note: erroneous constant used - --> $DIR/erroneous-const2.rs:13:17 + --> $DIR/erroneous-const2.rs:13:9 | -LL | let _ = PrintName::::VOID; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | PrintName::::VOID; + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/consts/const-eval/promoted_errors.rs b/tests/ui/consts/const-eval/promoted_errors.rs index 2c42d035629a0..5e67dc6f6c32e 100644 --- a/tests/ui/consts/const-eval/promoted_errors.rs +++ b/tests/ui/consts/const-eval/promoted_errors.rs @@ -48,5 +48,5 @@ const Y: () = { }; fn main() { - let _y = Y; + Y; } diff --git a/tests/ui/consts/const-eval/unwind-abort.rs b/tests/ui/consts/const-eval/unwind-abort.rs index 2b0e58166c254..57959e7db6ad9 100644 --- a/tests/ui/consts/const-eval/unwind-abort.rs +++ b/tests/ui/consts/const-eval/unwind-abort.rs @@ -8,5 +8,5 @@ const _: () = foo(); // Ensure that the CTFE engine handles calls to `extern "C"` aborting gracefully fn main() { - let _ = foo(); + foo(); } diff --git a/tests/ui/consts/large_const_alloc.rs b/tests/ui/consts/large_const_alloc.rs index 54abaab224730..298ed38d180e6 100644 --- a/tests/ui/consts/large_const_alloc.rs +++ b/tests/ui/consts/large_const_alloc.rs @@ -13,6 +13,6 @@ static FOO2: () = { }; fn main() { - let _ = FOO; - let _ = FOO2; + FOO; + FOO2; } diff --git a/tests/ui/empty-allocation-rvalue-non-null.rs b/tests/ui/empty-allocation-rvalue-non-null.rs index 2f5a5c4bbc6db..ad0f22031067e 100644 --- a/tests/ui/empty-allocation-rvalue-non-null.rs +++ b/tests/ui/empty-allocation-rvalue-non-null.rs @@ -4,5 +4,5 @@ // pretty-expanded FIXME #23616 pub fn main() { - let x = *Box::new(()); + let x: () = *Box::new(()); } diff --git a/tests/ui/error-codes/E0445.rs b/tests/ui/error-codes/E0445.rs index a9a3aee2500fb..f5f35fb8a4d2d 100644 --- a/tests/ui/error-codes/E0445.rs +++ b/tests/ui/error-codes/E0445.rs @@ -1,3 +1,10 @@ +#[warn(private_bounds)] +#[warn(private_interfaces)] + +// In this test both old and new private-in-public diagnostic were emitted. +// Old diagnostic will be deleted soon. +// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. + trait Foo { fn dummy(&self) { } } diff --git a/tests/ui/error-codes/E0445.stderr b/tests/ui/error-codes/E0445.stderr index 23b7a33504767..ac3637a821858 100644 --- a/tests/ui/error-codes/E0445.stderr +++ b/tests/ui/error-codes/E0445.stderr @@ -1,5 +1,5 @@ error[E0445]: private trait `Foo` in public interface - --> $DIR/E0445.rs:5:1 + --> $DIR/E0445.rs:12:1 | LL | trait Foo { | --------- `Foo` declared as private @@ -7,8 +7,26 @@ LL | trait Foo { LL | pub trait Bar : Foo {} | ^^^^^^^^^^^^^^^^^^^ can't leak private trait +warning: trait `Foo` is more private than the item `Bar` + | +note: trait `Bar` is reachable at visibility `pub` + --> $DIR/E0445.rs:12:1 + | +LL | pub trait Bar : Foo {} + | ^^^^^^^^^^^^^^^^^^^ +note: but trait `Foo` is only usable at visibility `pub(crate)` + --> $DIR/E0445.rs:8:1 + | +LL | trait Foo { + | ^^^^^^^^^ +note: the lint level is defined here + --> $DIR/E0445.rs:1:8 + | +LL | #[warn(private_bounds)] + | ^^^^^^^^^^^^^^ + error[E0445]: private trait `Foo` in public interface - --> $DIR/E0445.rs:7:1 + --> $DIR/E0445.rs:14:1 | LL | trait Foo { | --------- `Foo` declared as private @@ -16,8 +34,21 @@ LL | trait Foo { LL | pub struct Bar2(pub T); | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait +warning: trait `Foo` is more private than the item `Bar2` + | +note: struct `Bar2` is reachable at visibility `pub` + --> $DIR/E0445.rs:14:1 + | +LL | pub struct Bar2(pub T); + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: but trait `Foo` is only usable at visibility `pub(crate)` + --> $DIR/E0445.rs:8:1 + | +LL | trait Foo { + | ^^^^^^^^^ + error[E0445]: private trait `Foo` in public interface - --> $DIR/E0445.rs:9:1 + --> $DIR/E0445.rs:16:1 | LL | trait Foo { | --------- `Foo` declared as private @@ -25,6 +56,19 @@ LL | trait Foo { LL | pub fn foo (t: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait -error: aborting due to 3 previous errors +warning: trait `Foo` is more private than the item `foo` + | +note: function `foo` is reachable at visibility `pub` + --> $DIR/E0445.rs:16:1 + | +LL | pub fn foo (t: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: but trait `Foo` is only usable at visibility `pub(crate)` + --> $DIR/E0445.rs:8:1 + | +LL | trait Foo { + | ^^^^^^^^^ + +error: aborting due to 3 previous errors; 3 warnings emitted For more information about this error, try `rustc --explain E0445`. diff --git a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs new file mode 100644 index 0000000000000..17e08f511d71f --- /dev/null +++ b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs @@ -0,0 +1,10 @@ +extern "C" { + type Item = [T] where [T]: Sized; + //~^ incorrect `type` inside `extern` block + //~| `type`s inside `extern` blocks cannot have `where` clauses + //~| cannot find type `T` in this scope + //~| cannot find type `T` in this scope + //~| extern types are experimental +} + +fn main() {} diff --git a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr new file mode 100644 index 0000000000000..bdc6755038aa4 --- /dev/null +++ b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr @@ -0,0 +1,47 @@ +error: incorrect `type` inside `extern` block + --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:10 + | +LL | extern "C" { + | ---------- `extern` blocks define existing foreign types and types inside of them cannot have a body +LL | type Item = [T] where [T]: Sized; + | ^^^^ --- the invalid body + | | + | cannot have a body + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: `type`s inside `extern` blocks cannot have `where` clauses + --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:21 + | +LL | extern "C" { + | ---------- `extern` block begins here +LL | type Item = [T] where [T]: Sized; + | ^^^^^^^^^^^^^^^^ help: remove the `where` clause + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error[E0412]: cannot find type `T` in this scope + --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:28 + | +LL | type Item = [T] where [T]: Sized; + | ^ not found in this scope + +error[E0412]: cannot find type `T` in this scope + --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:18 + | +LL | type Item = [T] where [T]: Sized; + | ^ not found in this scope + +error[E0658]: extern types are experimental + --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:5 + | +LL | type Item = [T] where [T]: Sized; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #43467 for more information + = help: add `#![feature(extern_types)]` to the crate attributes to enable + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0412, E0658. +For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs b/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs index afd14b7843e20..be66560fd921c 100644 --- a/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs +++ b/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs @@ -19,5 +19,5 @@ fn bar() { fn main() { let _x = foo::<_>([1,2]); //[normal]~^ ERROR: type provided when a constant was expected - let _y = bar(); + bar(); } diff --git a/tests/ui/for-loop-while/loop-break-value.rs b/tests/ui/for-loop-while/loop-break-value.rs index d7209fc4de867..65207fb7fb54e 100644 --- a/tests/ui/for-loop-while/loop-break-value.rs +++ b/tests/ui/for-loop-while/loop-break-value.rs @@ -64,7 +64,7 @@ pub fn main() { }; assert_eq!(trait_unified_3, ["Yes"]); - let regular_break = loop { + let regular_break: () = loop { if true { break; } else { @@ -73,7 +73,7 @@ pub fn main() { }; assert_eq!(regular_break, ()); - let regular_break_2 = loop { + let regular_break_2: () = loop { if true { break Default::default(); } else { @@ -82,7 +82,7 @@ pub fn main() { }; assert_eq!(regular_break_2, ()); - let regular_break_3 = loop { + let regular_break_3: () = loop { break if true { Default::default() } else { @@ -91,13 +91,13 @@ pub fn main() { }; assert_eq!(regular_break_3, ()); - let regular_break_4 = loop { + let regular_break_4: () = loop { break (); break; }; assert_eq!(regular_break_4, ()); - let regular_break_5 = loop { + let regular_break_5: () = loop { break; break (); }; diff --git a/tests/ui/issues/issue-20605.stderr b/tests/ui/for/issue-20605.current.stderr similarity index 95% rename from tests/ui/issues/issue-20605.stderr rename to tests/ui/for/issue-20605.current.stderr index e1858b6398932..b9a53cbd4fcb2 100644 --- a/tests/ui/issues/issue-20605.stderr +++ b/tests/ui/for/issue-20605.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `dyn Iterator` cannot be known at compilation time - --> $DIR/issue-20605.rs:2:17 + --> $DIR/issue-20605.rs:5:17 | LL | for item in *things { *item = 0 } | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr new file mode 100644 index 0000000000000..5362a68c834a3 --- /dev/null +++ b/tests/ui/for/issue-20605.next.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `dyn Iterator: IntoIterator` is not satisfied + --> $DIR/issue-20605.rs:5:17 + | +LL | for item in *things { *item = 0 } + | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` + +error[E0277]: the size for values of type ` as IntoIterator>::IntoIter` cannot be known at compilation time + --> $DIR/issue-20605.rs:5:17 + | +LL | for item in *things { *item = 0 } + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for ` as IntoIterator>::IntoIter` + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature + +error: the type `<_ as IntoIterator>::IntoIter` is not well-formed + --> $DIR/issue-20605.rs:5:17 + | +LL | for item in *things { *item = 0 } + | ^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs new file mode 100644 index 0000000000000..499271fa92fa9 --- /dev/null +++ b/tests/ui/for/issue-20605.rs @@ -0,0 +1,11 @@ +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next + +fn changer<'a>(mut things: Box>) { + for item in *things { *item = 0 } + //~^ ERROR the size for values of type + //[next]~^^ ERROR the type `<_ as IntoIterator>::IntoIter` is not well-formed + //[next]~| ERROR the trait bound `dyn Iterator: IntoIterator` is not satisfied +} + +fn main() {} diff --git a/tests/ui/generics/post_monomorphization_error_backtrace.rs b/tests/ui/generics/post_monomorphization_error_backtrace.rs index 1fd9b6b3b9dba..a1316688075d1 100644 --- a/tests/ui/generics/post_monomorphization_error_backtrace.rs +++ b/tests/ui/generics/post_monomorphization_error_backtrace.rs @@ -11,7 +11,7 @@ fn assert_zst() { //~| NOTE: in this expansion of assert! //~| NOTE: the evaluated program panicked } - let _ = F::::V; + F::::V; } fn foo() { diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs index 74a4785e478b8..0ea736deeaa84 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs @@ -71,7 +71,7 @@ impl<'a, 'b, U: Unpack<'b>> Backed<'a, U> { where F: for<'f> FnOnce(>::Unpacked) -> (), { - let result = f(self.1.unpack()); + let result: () = f(self.1.unpack()); Backed(self.0, result) } } diff --git a/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.rs b/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.rs new file mode 100644 index 0000000000000..befd768b1818a --- /dev/null +++ b/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.rs @@ -0,0 +1,9 @@ +fn test() -> impl std::fmt::Debug { + if true { + "boo2" + } else { + //~^ ERROR `if` and `else` have incompatible types + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.stderr b/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.stderr new file mode 100644 index 0000000000000..9b63911da7aa3 --- /dev/null +++ b/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.stderr @@ -0,0 +1,16 @@ +error[E0308]: `if` and `else` have incompatible types + --> $DIR/dont-suggest-box-on-empty-else-arm.rs:4:12 + | +LL | if true { + | ------- `if` and `else` have incompatible types +LL | "boo2" + | ------ expected because of this +LL | } else { + | ____________^ +LL | | +LL | | } + | |_____^ expected `&str`, found `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr new file mode 100644 index 0000000000000..f604ada6ac760 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr @@ -0,0 +1,21 @@ +error[E0053]: method `early` has an incompatible type for trait + --> $DIR/method-signature-matches.rs:58:27 + | +LL | fn early<'late, T>(_: &'late ()) {} + | - ^^^^^^^^^ + | | | + | | expected type parameter `T`, found `()` + | | help: change the parameter type to match the trait: `&'early T` + | this type parameter + | +note: type in trait + --> $DIR/method-signature-matches.rs:53:28 + | +LL | fn early<'early, T>(x: &'early T) -> impl Sized; + | ^^^^^^^^^ + = note: expected signature `fn(&'early T)` + found signature `fn(&())` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr new file mode 100644 index 0000000000000..d3183b92e8400 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr @@ -0,0 +1,20 @@ +error[E0053]: method `owo` has an incompatible type for trait + --> $DIR/method-signature-matches.rs:14:15 + | +LL | fn owo(_: u8) {} + | ^^ + | | + | expected `()`, found `u8` + | help: change the parameter type to match the trait: `()` + | +note: type in trait + --> $DIR/method-signature-matches.rs:9:15 + | +LL | fn owo(x: ()) -> impl Sized; + | ^^ + = note: expected signature `fn(())` + found signature `fn(u8)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr new file mode 100644 index 0000000000000..80fda1c9fe14e --- /dev/null +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr @@ -0,0 +1,20 @@ +error[E0053]: method `owo` has an incompatible type for trait + --> $DIR/method-signature-matches.rs:25:21 + | +LL | async fn owo(_: u8) {} + | ^^ + | | + | expected `()`, found `u8` + | help: change the parameter type to match the trait: `()` + | +note: type in trait + --> $DIR/method-signature-matches.rs:20:21 + | +LL | async fn owo(x: ()) {} + | ^^ + = note: expected signature `fn(()) -> _` + found signature `fn(u8) -> _` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.rs b/tests/ui/impl-trait/in-trait/method-signature-matches.rs index c848ee3f643de..294f93b30d0ee 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.rs +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.rs @@ -1,51 +1,62 @@ // edition: 2021 +// revisions: mismatch mismatch_async too_many too_few lt #![feature(return_position_impl_trait_in_trait, async_fn_in_trait)] #![allow(incomplete_features)] +#[cfg(mismatch)] trait Uwu { fn owo(x: ()) -> impl Sized; } +#[cfg(mismatch)] impl Uwu for () { fn owo(_: u8) {} - //~^ ERROR method `owo` has an incompatible type for trait + //[mismatch]~^ ERROR method `owo` has an incompatible type for trait } +#[cfg(mismatch_async)] trait AsyncUwu { async fn owo(x: ()) {} } +#[cfg(mismatch_async)] impl AsyncUwu for () { async fn owo(_: u8) {} - //~^ ERROR method `owo` has an incompatible type for trait + //[mismatch_async]~^ ERROR method `owo` has an incompatible type for trait } +#[cfg(too_many)] trait TooMuch { fn calm_down_please() -> impl Sized; } +#[cfg(too_many)] impl TooMuch for () { fn calm_down_please(_: (), _: (), _: ()) {} - //~^ ERROR method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0 + //[too_many]~^ ERROR method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0 } +#[cfg(too_few)] trait TooLittle { fn come_on_a_little_more_effort(_: (), _: (), _: ()) -> impl Sized; } +#[cfg(too_few)] impl TooLittle for () { fn come_on_a_little_more_effort() {} - //~^ ERROR method `come_on_a_little_more_effort` has 0 parameters but the declaration in trait `TooLittle::come_on_a_little_more_effort` has 3 + //[too_few]~^ ERROR method `come_on_a_little_more_effort` has 0 parameters but the declaration in trait `TooLittle::come_on_a_little_more_effort` has 3 } +#[cfg(lt)] trait Lifetimes { fn early<'early, T>(x: &'early T) -> impl Sized; } +#[cfg(lt)] impl Lifetimes for () { fn early<'late, T>(_: &'late ()) {} - //~^ ERROR method `early` has an incompatible type for trait + //[lt]~^ ERROR method `early` has an incompatible type for trait } fn main() {} diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.stderr deleted file mode 100644 index 3ec62020e6c89..0000000000000 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.stderr +++ /dev/null @@ -1,74 +0,0 @@ -error[E0053]: method `owo` has an incompatible type for trait - --> $DIR/method-signature-matches.rs:11:15 - | -LL | fn owo(_: u8) {} - | ^^ - | | - | expected `()`, found `u8` - | help: change the parameter type to match the trait: `()` - | -note: type in trait - --> $DIR/method-signature-matches.rs:7:15 - | -LL | fn owo(x: ()) -> impl Sized; - | ^^ - = note: expected signature `fn(())` - found signature `fn(u8)` - -error[E0053]: method `owo` has an incompatible type for trait - --> $DIR/method-signature-matches.rs:20:21 - | -LL | async fn owo(_: u8) {} - | ^^ - | | - | expected `()`, found `u8` - | help: change the parameter type to match the trait: `()` - | -note: type in trait - --> $DIR/method-signature-matches.rs:16:21 - | -LL | async fn owo(x: ()) {} - | ^^ - = note: expected signature `fn(()) -> _` - found signature `fn(u8) -> _` - -error[E0050]: method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0 - --> $DIR/method-signature-matches.rs:29:28 - | -LL | fn calm_down_please() -> impl Sized; - | ------------------------------------ trait requires 0 parameters -... -LL | fn calm_down_please(_: (), _: (), _: ()) {} - | ^^^^^^^^^^^^^^^^ expected 0 parameters, found 3 - -error[E0050]: method `come_on_a_little_more_effort` has 0 parameters but the declaration in trait `TooLittle::come_on_a_little_more_effort` has 3 - --> $DIR/method-signature-matches.rs:38:5 - | -LL | fn come_on_a_little_more_effort(_: (), _: (), _: ()) -> impl Sized; - | ---------------- trait requires 3 parameters -... -LL | fn come_on_a_little_more_effort() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 3 parameters, found 0 - -error[E0053]: method `early` has an incompatible type for trait - --> $DIR/method-signature-matches.rs:47:27 - | -LL | fn early<'late, T>(_: &'late ()) {} - | - ^^^^^^^^^ - | | | - | | expected type parameter `T`, found `()` - | | help: change the parameter type to match the trait: `&'early T` - | this type parameter - | -note: type in trait - --> $DIR/method-signature-matches.rs:43:28 - | -LL | fn early<'early, T>(x: &'early T) -> impl Sized; - | ^^^^^^^^^ - = note: expected signature `fn(&'early T)` - found signature `fn(&())` - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0050, E0053. -For more information about an error, try `rustc --explain E0050`. diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.too_few.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.too_few.stderr new file mode 100644 index 0000000000000..24bcfeb748fd0 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.too_few.stderr @@ -0,0 +1,12 @@ +error[E0050]: method `come_on_a_little_more_effort` has 0 parameters but the declaration in trait `TooLittle::come_on_a_little_more_effort` has 3 + --> $DIR/method-signature-matches.rs:47:5 + | +LL | fn come_on_a_little_more_effort(_: (), _: (), _: ()) -> impl Sized; + | ---------------- trait requires 3 parameters +... +LL | fn come_on_a_little_more_effort() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 3 parameters, found 0 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0050`. diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.too_many.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.too_many.stderr new file mode 100644 index 0000000000000..616cbd2905c79 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.too_many.stderr @@ -0,0 +1,12 @@ +error[E0050]: method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0 + --> $DIR/method-signature-matches.rs:36:28 + | +LL | fn calm_down_please() -> impl Sized; + | ------------------------------------ trait requires 0 parameters +... +LL | fn calm_down_please(_: (), _: (), _: ()) {} + | ^^^^^^^^^^^^^^^^ expected 0 parameters, found 3 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0050`. diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr b/tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr new file mode 100644 index 0000000000000..bf088ae8b25cc --- /dev/null +++ b/tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr @@ -0,0 +1,9 @@ +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-lt.rs:10:6 + | +LL | impl<'a, T> Foo for T { + | ^^ unconstrained lifetime parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr b/tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr new file mode 100644 index 0000000000000..bf088ae8b25cc --- /dev/null +++ b/tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr @@ -0,0 +1,9 @@ +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-lt.rs:10:6 + | +LL | impl<'a, T> Foo for T { + | ^^ unconstrained lifetime parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.rs b/tests/ui/impl-trait/in-trait/unconstrained-lt.rs new file mode 100644 index 0000000000000..f966be43a6ef8 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/unconstrained-lt.rs @@ -0,0 +1,16 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + +#![feature(return_position_impl_trait_in_trait)] + +trait Foo { + fn test() -> impl Sized; +} + +impl<'a, T> Foo for T { + //~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + + fn test() -> &'a () { &() } +} + +fn main() {} diff --git a/tests/ui/intrinsics/panic-uninitialized-zeroed.rs b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs index 1a0104b859e53..6db2ebb9754bc 100644 --- a/tests/ui/intrinsics/panic-uninitialized-zeroed.rs +++ b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -391,7 +391,7 @@ fn main() { let _val = mem::zeroed::(); let _val = mem::uninitialized::>(); let _val = mem::uninitialized::<[!; 0]>(); - let _val = mem::uninitialized::<()>(); + let _val: () = mem::uninitialized::<()>(); let _val = mem::uninitialized::(); } } diff --git a/tests/ui/issues/issue-11047.rs b/tests/ui/issues/issue-11047.rs index 1fb2b5bb3a1d5..7a4acea453757 100644 --- a/tests/ui/issues/issue-11047.rs +++ b/tests/ui/issues/issue-11047.rs @@ -18,8 +18,8 @@ pub mod foo { fn main() { type Ham = foo::bar::baz::Qux; - let foo = foo::bar::baz::Qux::new(); // invoke directly - let bar = Ham::new(); // invoke via type alias + let foo: () = foo::bar::baz::Qux::new(); // invoke directly + let bar: () = Ham::new(); // invoke via type alias type StringVec = Vec; let sv = StringVec::new(); diff --git a/tests/ui/issues/issue-11709.rs b/tests/ui/issues/issue-11709.rs index 58424f9e4c583..2d6956649a283 100644 --- a/tests/ui/issues/issue-11709.rs +++ b/tests/ui/issues/issue-11709.rs @@ -10,7 +10,7 @@ struct S {x:()} fn test(slot: &mut Option Box>>) -> () { let a = slot.take(); - let _a = match a { + let _a: () = match a { // `{let .. a(); }` would break Some(mut a) => { let _a = a(); }, None => (), @@ -28,7 +28,7 @@ fn not(b: bool) -> bool { pub fn main() { // {} would break - let _r = {}; + let _r: () = {}; let mut slot = None; // `{ test(...); }` would break let _s : S = S{ x: { test(&mut slot); } }; diff --git a/tests/ui/issues/issue-11740.rs b/tests/ui/issues/issue-11740.rs index 9faeb7770a75a..fa80f509b3229 100644 --- a/tests/ui/issues/issue-11740.rs +++ b/tests/ui/issues/issue-11740.rs @@ -24,5 +24,5 @@ impl Element { fn main() { let element = Element { attrs: Vec::new() }; - let _ = unsafe { element.get_attr("foo") }; + unsafe { let () = element.get_attr("foo"); }; } diff --git a/tests/ui/issues/issue-18389.rs b/tests/ui/issues/issue-18389.rs index 654dfb63b88be..3686afc48af8d 100644 --- a/tests/ui/issues/issue-18389.rs +++ b/tests/ui/issues/issue-18389.rs @@ -1,3 +1,9 @@ +#![warn(private_bounds)] + +// In this test both old and new private-in-public diagnostic were emitted. +// Old diagnostic will be deleted soon. +// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. + use std::any::Any; use std::any::TypeId; diff --git a/tests/ui/issues/issue-18389.stderr b/tests/ui/issues/issue-18389.stderr index 6ce78c45d6e5a..f9ebde48a4522 100644 --- a/tests/ui/issues/issue-18389.stderr +++ b/tests/ui/issues/issue-18389.stderr @@ -1,5 +1,5 @@ error[E0445]: private trait `Private<::P, ::R>` in public interface - --> $DIR/issue-18389.rs:7:1 + --> $DIR/issue-18389.rs:13:1 | LL | trait Private { | ------------------- `Private<::P, ::R>` declared as private @@ -11,6 +11,28 @@ LL | | ::R LL | | > { | |_^ can't leak private trait -error: aborting due to previous error +warning: trait `Private<::P, ::R>` is more private than the item `Public` + | +note: trait `Public` is reachable at visibility `pub` + --> $DIR/issue-18389.rs:13:1 + | +LL | / pub trait Public: Private< +LL | | +LL | | ::P, +LL | | ::R +LL | | > { + | |_^ +note: but trait `Private<::P, ::R>` is only usable at visibility `pub(crate)` + --> $DIR/issue-18389.rs:10:1 + | +LL | trait Private { + | ^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/issue-18389.rs:1:9 + | +LL | #![warn(private_bounds)] + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0445`. diff --git a/tests/ui/issues/issue-20605.rs b/tests/ui/issues/issue-20605.rs deleted file mode 100644 index 17b7d32ebf59b..0000000000000 --- a/tests/ui/issues/issue-20605.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn changer<'a>(mut things: Box>) { - for item in *things { *item = 0 } -//~^ ERROR the size for values of type -} - -fn main() {} diff --git a/tests/ui/issues/issue-20644.rs b/tests/ui/issues/issue-20644.rs index 1b90727fbc0a6..a3a9ea7405f29 100644 --- a/tests/ui/issues/issue-20644.rs +++ b/tests/ui/issues/issue-20644.rs @@ -26,7 +26,7 @@ fn foo() { let cwd = env::current_dir().unwrap(); let src = cwd.clone(); let summary = File::open(&src.join("SUMMARY.md")).unwrap(); - let _ = parse_summary(summary, &src); + parse_summary(summary, &src); } fn main() {} diff --git a/tests/ui/issues/issue-23808.rs b/tests/ui/issues/issue-23808.rs index 0988b09fce99a..b10682521a4b0 100644 --- a/tests/ui/issues/issue-23808.rs +++ b/tests/ui/issues/issue-23808.rs @@ -45,14 +45,14 @@ impl_Const!(ConstStruct, ConstEnum, AliasedConstStruct, AliasedConstEnum); impl_StaticFn!(StaticFnStruct, StaticFnEnum, AliasedStaticFnStruct, AliasedStaticFnEnum); fn main() { - let _ = ConstStruct::C; - let _ = ConstEnum::C; + let () = ConstStruct::C; + let () = ConstEnum::C; StaticFnStruct::sfn(); StaticFnEnum::sfn(); - let _ = AliasConstStruct::C; - let _ = AliasConstEnum::C; + let () = AliasConstStruct::C; + let () = AliasConstEnum::C; AliasStaticFnStruct::sfn(); AliasStaticFnEnum::sfn(); diff --git a/tests/ui/layout/issue-112048-unsizing-field-order.rs b/tests/ui/layout/issue-112048-unsizing-field-order.rs new file mode 100644 index 0000000000000..ebc4b9e98b7ab --- /dev/null +++ b/tests/ui/layout/issue-112048-unsizing-field-order.rs @@ -0,0 +1,25 @@ +// run-pass + +// Check that unsizing doesn't reorder fields. + +#![allow(dead_code)] + +use std::fmt::Debug; + +#[derive(Debug)] +struct GcNode { + gets_swapped_with_next: usize, + next: Option<&'static GcNode>, + tail: T, +} + +fn main() { + let node: Box> = Box::new(GcNode { + gets_swapped_with_next: 42, + next: None, + tail: Box::new(1), + }); + + assert_eq!(node.gets_swapped_with_next, 42); + assert!(node.next.is_none()); +} diff --git a/tests/ui/layout/issue-112048-unsizing-niche.rs b/tests/ui/layout/issue-112048-unsizing-niche.rs new file mode 100644 index 0000000000000..23588ba36ee59 --- /dev/null +++ b/tests/ui/layout/issue-112048-unsizing-niche.rs @@ -0,0 +1,30 @@ +// run-pass + +// Check that unsizing does not change which field is considered for niche layout. + +#![feature(offset_of)] +#![allow(dead_code)] + +#[derive(Clone)] +struct WideptrField { + first: usize, + second: usize, + niche: NicheAtEnd, + tail: T, +} + +#[derive(Clone)] +#[repr(C)] +struct NicheAtEnd { + arr: [u8; 7], + b: bool, +} + +type Tail = [bool; 8]; + +fn main() { + assert_eq!( + core::mem::offset_of!(WideptrField, niche), + core::mem::offset_of!(WideptrField, niche) + ); +} diff --git a/tests/ui/lexer/lex-bad-char-literals-1.stderr b/tests/ui/lexer/lex-bad-char-literals-1.stderr index e6ff1f662bde9..9dc0a3380631e 100644 --- a/tests/ui/lexer/lex-bad-char-literals-1.stderr +++ b/tests/ui/lexer/lex-bad-char-literals-1.stderr @@ -16,7 +16,7 @@ error: unknown character escape: `\u{25cf}` LL | '\●' | ^ unknown character escape | - = help: for more information, visit + = help: for more information, visit help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal | LL | r"\●" @@ -28,7 +28,7 @@ error: unknown character escape: `\u{25cf}` LL | "\●" | ^ unknown character escape | - = help: for more information, visit + = help: for more information, visit help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal | LL | r"\●" diff --git a/tests/ui/lint/lint-attr-everywhere-early.rs b/tests/ui/lint/lint-attr-everywhere-early.rs index 0c820ef9a29a9..ae32ec426f232 100644 --- a/tests/ui/lint/lint-attr-everywhere-early.rs +++ b/tests/ui/lint/lint-attr-everywhere-early.rs @@ -147,7 +147,7 @@ fn expressions() { #![deny(unsafe_code)] unsafe {} //~ ERROR usage of an `unsafe` block } - let block_tail = { + let block_tail: () = { #[deny(unsafe_code)] unsafe {} //~ ERROR usage of an `unsafe` block }; diff --git a/tests/ui/lint/lint-attr-everywhere-late.rs b/tests/ui/lint/lint-attr-everywhere-late.rs index a24355babb63e..c3acdeda43a9b 100644 --- a/tests/ui/lint/lint-attr-everywhere-late.rs +++ b/tests/ui/lint/lint-attr-everywhere-late.rs @@ -172,7 +172,7 @@ fn expressions() { #![deny(enum_intrinsics_non_enums)] discriminant::(&123); //~ ERROR the return value of } - let block_tail = { + let block_tail: () = { #[deny(enum_intrinsics_non_enums)] discriminant::(&123); //~ ERROR the return value of }; diff --git a/tests/ui/lint/unused/lint-unused-extern-crate.rs b/tests/ui/lint/unused/lint-unused-extern-crate.rs index d5e4da526a1d5..79df58b704247 100644 --- a/tests/ui/lint/unused/lint-unused-extern-crate.rs +++ b/tests/ui/lint/unused/lint-unused-extern-crate.rs @@ -31,5 +31,5 @@ mod foo { fn main() { lint_unused_extern_crate3::foo(); - let y = foo(); + foo(); } diff --git a/tests/ui/lint/unused/lint-unused-imports.rs b/tests/ui/lint/unused/lint-unused-imports.rs index 4754d8880763a..953992ecf7147 100644 --- a/tests/ui/lint/unused/lint-unused-imports.rs +++ b/tests/ui/lint/unused/lint-unused-imports.rs @@ -86,5 +86,5 @@ fn main() { let mut b = 4; swap(&mut a, &mut b); test::C.b(); - let _a = foo(); + foo(); } diff --git a/tests/ui/lint/unused/lint-unused-variables.rs b/tests/ui/lint/unused/lint-unused-variables.rs index 6850e999242ea..621c6ef84140f 100644 --- a/tests/ui/lint/unused/lint-unused-variables.rs +++ b/tests/ui/lint/unused/lint-unused-variables.rs @@ -74,6 +74,6 @@ fn main() { b: i32, //~^ ERROR unused variable: `b` | {}; - let _ = a(1, 2); - let _ = b(1, 2); + a(1, 2); + b(1, 2); } diff --git a/tests/ui/lint/unused_import_warning_issue_45268.rs b/tests/ui/lint/unused_import_warning_issue_45268.rs index 5ae4828634091..7aa4d4959e7a6 100644 --- a/tests/ui/lint/unused_import_warning_issue_45268.rs +++ b/tests/ui/lint/unused_import_warning_issue_45268.rs @@ -31,15 +31,15 @@ use test::B; // This is used by the test2::func() through import of super mod test2 { use super::*; pub fn func() { - let _ = <()>::a(); - let _ = ().b(); + <()>::a(); + ().b(); test3::inner_func(); } mod test3 { use super::*; pub fn inner_func() { - let _ = <()>::a(); - let _ = ().b(); + <()>::a(); + ().b(); } } } diff --git a/tests/ui/macros/format-args-temporaries.rs b/tests/ui/macros/format-args-temporaries.rs index 59323828bc37f..1ff6e3f80d6d5 100644 --- a/tests/ui/macros/format-args-temporaries.rs +++ b/tests/ui/macros/format-args-temporaries.rs @@ -27,27 +27,27 @@ impl<'a> Display for MutexGuard<'a> { } fn main() { - let _print = { + let _print: () = { let mutex = Mutex; print!("{}", mutex.lock()) /* no semicolon */ }; - let _println = { + let _println: () = { let mutex = Mutex; println!("{}", mutex.lock()) /* no semicolon */ }; - let _eprint = { + let _eprint: () = { let mutex = Mutex; eprint!("{}", mutex.lock()) /* no semicolon */ }; - let _eprintln = { + let _eprintln: () = { let mutex = Mutex; eprintln!("{}", mutex.lock()) /* no semicolon */ }; - let _panic = { + let _panic: () = { let mutex = Mutex; panic!("{}", mutex.lock()) /* no semicolon */ }; diff --git a/tests/ui/macros/macro-comma-support-rpass.rs b/tests/ui/macros/macro-comma-support-rpass.rs index cb019792e656f..2f08ad3c343ab 100644 --- a/tests/ui/macros/macro-comma-support-rpass.rs +++ b/tests/ui/macros/macro-comma-support-rpass.rs @@ -170,8 +170,8 @@ fn format_args() { #[test] fn include() { - let _ = include!("auxiliary/macro-comma-support.rs"); - let _ = include!("auxiliary/macro-comma-support.rs",); + include!("auxiliary/macro-comma-support.rs"); + include!("auxiliary/macro-comma-support.rs",); } #[test] diff --git a/tests/ui/mir/issue-101844.rs b/tests/ui/mir/issue-101844.rs index da8a25f5f822f..72ceefa4f4a40 100644 --- a/tests/ui/mir/issue-101844.rs +++ b/tests/ui/mir/issue-101844.rs @@ -67,7 +67,7 @@ where MS::Item: Into<()>, { // Error: Apparently Balance::new doesn't exist during MIR validation - let _ = ImplShoulExist::::access_fn(ms); + ImplShoulExist::::access_fn(ms); } fn main() {} diff --git a/tests/ui/mir/issue-80949.rs b/tests/ui/mir/issue-80949.rs index 7e34a4f5c2737..96b63e93a9ab8 100644 --- a/tests/ui/mir/issue-80949.rs +++ b/tests/ui/mir/issue-80949.rs @@ -28,7 +28,7 @@ fn may_panic(_: X) { } fn main() { let dyn_trait = make_dyn_trait(&()); let storage = vec![()]; - let _x = may_panic(()); + may_panic(()); let storage_ref = &storage; diff(dyn_trait, storage_ref); } diff --git a/tests/ui/mir/issue66339.rs b/tests/ui/mir/issue66339.rs index 2507af38cdf73..f25afd5602d34 100644 --- a/tests/ui/mir/issue66339.rs +++ b/tests/ui/mir/issue66339.rs @@ -5,7 +5,7 @@ fn foo() { let bar = |_| { }; - let _ = bar("a"); + bar("a"); } fn main() { diff --git a/tests/ui/never_type/diverging-fallback-control-flow.rs b/tests/ui/never_type/diverging-fallback-control-flow.rs index 45a3362fa6d8e..9f6cfc7999a6a 100644 --- a/tests/ui/never_type/diverging-fallback-control-flow.rs +++ b/tests/ui/never_type/diverging-fallback-control-flow.rs @@ -48,7 +48,7 @@ fn assignment_rev() { } fn if_then_else() { - let _x = if true { + let _x: () = if true { UnitDefault::default() } else { return; @@ -56,7 +56,7 @@ fn if_then_else() { } fn if_then_else_rev() { - let _x = if true { + let _x: () = if true { return; } else { UnitDefault::default() @@ -64,21 +64,21 @@ fn if_then_else_rev() { } fn match_arm() { - let _x = match Ok(UnitDefault::default()) { + let _x: () = match Ok(UnitDefault::default()) { Ok(v) => v, Err(()) => return, }; } fn match_arm_rev() { - let _x = match Ok(UnitDefault::default()) { + let _x: () = match Ok(UnitDefault::default()) { Err(()) => return, Ok(v) => v, }; } fn loop_break() { - let _x = loop { + let _x: () = loop { if false { break return; } else { @@ -88,7 +88,7 @@ fn loop_break() { } fn loop_break_rev() { - let _x = loop { + let _x: () = loop { if false { break return; } else { diff --git a/tests/ui/nll/assign-while-to-immutable.rs b/tests/ui/nll/assign-while-to-immutable.rs index c803321b5087a..24eaa8a23883d 100644 --- a/tests/ui/nll/assign-while-to-immutable.rs +++ b/tests/ui/nll/assign-while-to-immutable.rs @@ -4,8 +4,8 @@ // check-pass fn main() { - let x = while false { + let x: () = while false { break; }; - let y = 'l: while break 'l {}; + let y: () = 'l: while break 'l {}; } diff --git a/tests/ui/nll/issue-54943-3.rs b/tests/ui/nll/issue-54943-3.rs index 077eb156316f5..348b48dbabb5b 100644 --- a/tests/ui/nll/issue-54943-3.rs +++ b/tests/ui/nll/issue-54943-3.rs @@ -13,7 +13,7 @@ fn foo(_: T) { } fn bar<'a>() { return; - let _x = foo::>(Vec::<&'a u32>::new()); + foo::>(Vec::<&'a u32>::new()); } fn main() {} diff --git a/tests/ui/parser/bad-escape-suggest-raw-string.rs b/tests/ui/parser/bad-escape-suggest-raw-string.rs index 978b92cbcd211..06df82d288b59 100644 --- a/tests/ui/parser/bad-escape-suggest-raw-string.rs +++ b/tests/ui/parser/bad-escape-suggest-raw-string.rs @@ -2,6 +2,6 @@ fn main() { let ok = r"ab\[c"; let bad = "ab\[c"; //~^ ERROR unknown character escape: `[` - //~| HELP for more information, visit + //~| HELP for more information, visit //~| HELP if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal } diff --git a/tests/ui/parser/bad-escape-suggest-raw-string.stderr b/tests/ui/parser/bad-escape-suggest-raw-string.stderr index fc34bd3281af5..45d24bc0fb362 100644 --- a/tests/ui/parser/bad-escape-suggest-raw-string.stderr +++ b/tests/ui/parser/bad-escape-suggest-raw-string.stderr @@ -4,7 +4,7 @@ error: unknown character escape: `[` LL | let bad = "ab\[c"; | ^ unknown character escape | - = help: for more information, visit + = help: for more information, visit help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal | LL | let bad = r"ab\[c"; diff --git a/tests/ui/parser/byte-literals.stderr b/tests/ui/parser/byte-literals.stderr index efa55ae05bd37..5b414c8927e2c 100644 --- a/tests/ui/parser/byte-literals.stderr +++ b/tests/ui/parser/byte-literals.stderr @@ -4,7 +4,7 @@ error: unknown byte escape: `f` LL | static FOO: u8 = b'\f'; | ^ unknown byte escape | - = help: for more information, visit + = help: for more information, visit error: unknown byte escape: `f` --> $DIR/byte-literals.rs:6:8 @@ -12,7 +12,7 @@ error: unknown byte escape: `f` LL | b'\f'; | ^ unknown byte escape | - = help: for more information, visit + = help: for more information, visit error: invalid character in numeric character escape: `Z` --> $DIR/byte-literals.rs:7:10 diff --git a/tests/ui/parser/byte-string-literals.stderr b/tests/ui/parser/byte-string-literals.stderr index 5b96cc3d18abc..655b6998e85ff 100644 --- a/tests/ui/parser/byte-string-literals.stderr +++ b/tests/ui/parser/byte-string-literals.stderr @@ -4,7 +4,7 @@ error: unknown byte escape: `f` LL | static FOO: &'static [u8] = b"\f"; | ^ unknown byte escape | - = help: for more information, visit + = help: for more information, visit error: unknown byte escape: `f` --> $DIR/byte-string-literals.rs:4:8 @@ -12,7 +12,7 @@ error: unknown byte escape: `f` LL | b"\f"; | ^ unknown byte escape | - = help: for more information, visit + = help: for more information, visit error: invalid character in numeric character escape: `Z` --> $DIR/byte-string-literals.rs:5:10 diff --git a/tests/ui/parser/foreign-ty-semantic-fail.rs b/tests/ui/parser/foreign-ty-semantic-fail.rs index 96b15232b10d0..4d30086e76536 100644 --- a/tests/ui/parser/foreign-ty-semantic-fail.rs +++ b/tests/ui/parser/foreign-ty-semantic-fail.rs @@ -15,4 +15,5 @@ extern "C" { //~^ ERROR incorrect `type` inside `extern` block type E: where; + //~^ ERROR `type`s inside `extern` blocks cannot have `where` clauses } diff --git a/tests/ui/parser/foreign-ty-semantic-fail.stderr b/tests/ui/parser/foreign-ty-semantic-fail.stderr index 588e4966aaeb5..2b400dfea3bfa 100644 --- a/tests/ui/parser/foreign-ty-semantic-fail.stderr +++ b/tests/ui/parser/foreign-ty-semantic-fail.stderr @@ -61,5 +61,16 @@ LL | type D = u8; | = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html -error: aborting due to 6 previous errors +error: `type`s inside `extern` blocks cannot have `where` clauses + --> $DIR/foreign-ty-semantic-fail.rs:17:13 + | +LL | extern "C" { + | ---------- `extern` block begins here +... +LL | type E: where; + | ^^^^^ help: remove the `where` clause + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 7 previous errors diff --git a/tests/ui/parser/issues/issue-111692.rs b/tests/ui/parser/issues/issue-111692.rs new file mode 100644 index 0000000000000..56096f706a8a7 --- /dev/null +++ b/tests/ui/parser/issues/issue-111692.rs @@ -0,0 +1,32 @@ +mod module { + #[derive(Eq, PartialEq)] + pub struct Type { + pub x: u8, + pub y: u8, + } + + pub const C: u8 = 32u8; +} + +fn test(x: module::Type) { + if x == module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + } +} + +fn test2(x: module::Type) { + if x ==module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + } +} + + +fn test3(x: module::Type) { + if x == Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + } +} + +fn test4(x: module::Type) { + if x == demo_module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + } +} + +fn main() { } diff --git a/tests/ui/parser/issues/issue-111692.stderr b/tests/ui/parser/issues/issue-111692.stderr new file mode 100644 index 0000000000000..068b0483b0fd3 --- /dev/null +++ b/tests/ui/parser/issues/issue-111692.stderr @@ -0,0 +1,46 @@ +error: invalid struct literal + --> $DIR/issue-111692.rs:12:21 + | +LL | if x == module::Type { x: module::C, y: 1 } { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you might need to surround the struct literal with parentheses + | +LL | if x == (module::Type { x: module::C, y: 1 }) { + | + + + +error: invalid struct literal + --> $DIR/issue-111692.rs:17:20 + | +LL | if x ==module::Type { x: module::C, y: 1 } { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you might need to surround the struct literal with parentheses + | +LL | if x ==(module::Type { x: module::C, y: 1 }) { + | + + + +error: invalid struct literal + --> $DIR/issue-111692.rs:23:13 + | +LL | if x == Type { x: module::C, y: 1 } { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you might need to surround the struct literal with parentheses + | +LL | if x == (Type { x: module::C, y: 1 }) { + | + + + +error: invalid struct literal + --> $DIR/issue-111692.rs:28:26 + | +LL | if x == demo_module::Type { x: module::C, y: 1 } { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you might need to surround the struct literal with parentheses + | +LL | if x == (demo_module::Type { x: module::C, y: 1 }) { + | + + + +error: aborting due to 4 previous errors + diff --git a/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr b/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr index 7fd7ffc94a513..dedbad9094594 100644 --- a/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr +++ b/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr @@ -4,7 +4,7 @@ error: invalid struct literal LL | if Example { a: one(), }.is_pos() { | ^^^^^^^^^^^^^^^^^^^^^ | -help: you might need to surround the struct literal in parentheses +help: you might need to surround the struct literal with parentheses | LL | if (Example { a: one(), }).is_pos() { | + + diff --git a/tests/ui/polymorphization/drop_shims/simple.rs b/tests/ui/polymorphization/drop_shims/simple.rs index 2695dc6d4f177..5f10d5e831cd3 100644 --- a/tests/ui/polymorphization/drop_shims/simple.rs +++ b/tests/ui/polymorphization/drop_shims/simple.rs @@ -14,7 +14,7 @@ fn foo( let bar = || { let _ = OnDrop(|| ()); }; - let _ = bar(); + bar(); } fn main() { diff --git a/tests/ui/polymorphization/drop_shims/transitive.rs b/tests/ui/polymorphization/drop_shims/transitive.rs index c22891171091a..283b8da132947 100644 --- a/tests/ui/polymorphization/drop_shims/transitive.rs +++ b/tests/ui/polymorphization/drop_shims/transitive.rs @@ -19,7 +19,7 @@ fn foo( let bar = || { bar(|| {}) }; - let _ = bar(); + bar(); } fn main() { diff --git a/tests/ui/privacy/private-in-public-non-principal.rs b/tests/ui/privacy/private-in-public-non-principal.rs index ac1d5a9e6a202..a80c154146378 100644 --- a/tests/ui/privacy/private-in-public-non-principal.rs +++ b/tests/ui/privacy/private-in-public-non-principal.rs @@ -1,6 +1,12 @@ #![feature(auto_traits)] #![feature(negative_impls)] +#![deny(private_interfaces)] + +// In this test both old and new private-in-public diagnostic were emitted. +// Old diagnostic will be deleted soon. +// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. + pub trait PubPrincipal {} auto trait PrivNonPrincipal {} diff --git a/tests/ui/privacy/private-in-public-non-principal.stderr b/tests/ui/privacy/private-in-public-non-principal.stderr index de20cada42e86..9fc12affe4bfb 100644 --- a/tests/ui/privacy/private-in-public-non-principal.stderr +++ b/tests/ui/privacy/private-in-public-non-principal.stderr @@ -1,5 +1,5 @@ warning: private trait `PrivNonPrincipal` in public interface (error E0445) - --> $DIR/private-in-public-non-principal.rs:7:1 + --> $DIR/private-in-public-non-principal.rs:13:1 | LL | pub fn leak_dyn_nonprincipal() -> Box { loop {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,17 +8,35 @@ LL | pub fn leak_dyn_nonprincipal() -> Box = note: for more information, see issue #34537 = note: `#[warn(private_in_public)]` on by default +error: trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal` + | +note: function `leak_dyn_nonprincipal` is reachable at visibility `pub` + --> $DIR/private-in-public-non-principal.rs:13:1 + | +LL | pub fn leak_dyn_nonprincipal() -> Box { loop {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: but trait `PrivNonPrincipal` is only usable at visibility `pub(crate)` + --> $DIR/private-in-public-non-principal.rs:11:1 + | +LL | auto trait PrivNonPrincipal {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/private-in-public-non-principal.rs:4:9 + | +LL | #![deny(private_interfaces)] + | ^^^^^^^^^^^^^^^^^^ + error: missing documentation for an associated function - --> $DIR/private-in-public-non-principal.rs:14:9 + --> $DIR/private-in-public-non-principal.rs:20:9 | LL | pub fn check_doc_lint() {} | ^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/private-in-public-non-principal.rs:11:8 + --> $DIR/private-in-public-non-principal.rs:17:8 | LL | #[deny(missing_docs)] | ^^^^^^^^^^^^ -error: aborting due to previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/privacy/private-inferred-type-1.rs b/tests/ui/privacy/private-inferred-type-1.rs index d633189e3fbe4..b3eba53dd13d5 100644 --- a/tests/ui/privacy/private-inferred-type-1.rs +++ b/tests/ui/privacy/private-inferred-type-1.rs @@ -5,14 +5,24 @@ trait TyParam { fn ty_param_secret(&self); } +trait Ref { + fn ref_secret(self); +} + mod m { struct Priv; impl ::Arr0 for [Priv; 0] { fn arr0_secret(&self) {} } impl ::TyParam for Option { fn ty_param_secret(&self) {} } + impl<'a> ::Ref for &'a Priv { fn ref_secret(self) {} } } +fn anyref<'a, T>() -> &'a T { panic!() } + fn main() { [].arr0_secret(); //~ ERROR type `Priv` is private None.ty_param_secret(); //~ ERROR type `Priv` is private + Ref::ref_secret(anyref()); + //~^ ERROR type `Priv` is private + //~| ERROR type `Priv` is private } diff --git a/tests/ui/privacy/private-inferred-type-1.stderr b/tests/ui/privacy/private-inferred-type-1.stderr index 245789f435374..47c11d6ec7607 100644 --- a/tests/ui/privacy/private-inferred-type-1.stderr +++ b/tests/ui/privacy/private-inferred-type-1.stderr @@ -1,14 +1,26 @@ error: type `Priv` is private - --> $DIR/private-inferred-type-1.rs:16:5 + --> $DIR/private-inferred-type-1.rs:23:5 | LL | [].arr0_secret(); | ^^^^^^^^^^^^^^^^ private type error: type `Priv` is private - --> $DIR/private-inferred-type-1.rs:17:5 + --> $DIR/private-inferred-type-1.rs:24:5 | LL | None.ty_param_secret(); | ^^^^^^^^^^^^^^^^^^^^^^ private type -error: aborting due to 2 previous errors +error: type `Priv` is private + --> $DIR/private-inferred-type-1.rs:25:5 + | +LL | Ref::ref_secret(anyref()); + | ^^^^^^^^^^^^^^^ private type + +error: type `Priv` is private + --> $DIR/private-inferred-type-1.rs:25:21 + | +LL | Ref::ref_secret(anyref()); + | ^^^^^^^^ private type + +error: aborting due to 4 previous errors diff --git a/tests/ui/privacy/unnameable_types.rs b/tests/ui/privacy/unnameable_types.rs new file mode 100644 index 0000000000000..8b53f372fc937 --- /dev/null +++ b/tests/ui/privacy/unnameable_types.rs @@ -0,0 +1,30 @@ +#![allow(unused)] +#![allow(private_in_public)] +#![deny(unnameable_types)] + +mod m { + pub struct PubStruct(pub i32); //~ ERROR struct `PubStruct` is reachable but cannot be named + + pub enum PubE { //~ ERROR enum `PubE` is reachable but cannot be named + V(i32), + } + + pub trait PubTr { //~ ERROR trait `PubTr` is reachable but cannot be named + const C : i32 = 0; + type Alias; //~ ERROR associated type `PubTr::Alias` is reachable but cannot be named + fn f() {} + } + + impl PubTr for PubStruct { + type Alias = i32; //~ ERROR associated type `::Alias` is reachable but cannot be named + fn f() {} + } +} + +pub trait Voldemort {} + +impl Voldemort for i32 {} +impl Voldemort for i32 {} +impl Voldemort for u32 where T: m::PubTr {} + +fn main() {} diff --git a/tests/ui/privacy/unnameable_types.stderr b/tests/ui/privacy/unnameable_types.stderr new file mode 100644 index 0000000000000..25eb5c9434a8f --- /dev/null +++ b/tests/ui/privacy/unnameable_types.stderr @@ -0,0 +1,38 @@ +error: struct `PubStruct` is reachable but cannot be named + --> $DIR/unnameable_types.rs:6:5 + | +LL | pub struct PubStruct(pub i32); + | ^^^^^^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` + | +note: the lint level is defined here + --> $DIR/unnameable_types.rs:3:9 + | +LL | #![deny(unnameable_types)] + | ^^^^^^^^^^^^^^^^ + +error: enum `PubE` is reachable but cannot be named + --> $DIR/unnameable_types.rs:8:5 + | +LL | pub enum PubE { + | ^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` + +error: trait `PubTr` is reachable but cannot be named + --> $DIR/unnameable_types.rs:12:5 + | +LL | pub trait PubTr { + | ^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` + +error: associated type `PubTr::Alias` is reachable but cannot be named + --> $DIR/unnameable_types.rs:14:9 + | +LL | type Alias; + | ^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` + +error: associated type `::Alias` is reachable but cannot be named + --> $DIR/unnameable_types.rs:19:9 + | +LL | type Alias = i32; + | ^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` + +error: aborting due to 5 previous errors + diff --git a/tests/ui/privacy/where-priv-type.rs b/tests/ui/privacy/where-priv-type.rs index 66ee9c4bbd883..9899902dd884f 100644 --- a/tests/ui/privacy/where-priv-type.rs +++ b/tests/ui/privacy/where-priv-type.rs @@ -5,6 +5,12 @@ #![feature(generic_const_exprs)] #![allow(incomplete_features)] +#![warn(private_bounds)] +#![warn(private_interfaces)] + +// In this test both old and new private-in-public diagnostic were emitted. +// Old diagnostic will be deleted soon. +// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. struct PrivTy; trait PrivTr {} diff --git a/tests/ui/privacy/where-priv-type.stderr b/tests/ui/privacy/where-priv-type.stderr index c5fb2cdb0cf61..2830fa6cd442c 100644 --- a/tests/ui/privacy/where-priv-type.stderr +++ b/tests/ui/privacy/where-priv-type.stderr @@ -1,5 +1,5 @@ warning: private type `PrivTy` in public interface (error E0446) - --> $DIR/where-priv-type.rs:19:1 + --> $DIR/where-priv-type.rs:25:1 | LL | pub struct S | ^^^^^^^^^^^^ @@ -8,8 +8,26 @@ LL | pub struct S = note: for more information, see issue #34537 = note: `#[warn(private_in_public)]` on by default +warning: type `PrivTy` is more private than the item `S` + | +note: struct `S` is reachable at visibility `pub` + --> $DIR/where-priv-type.rs:25:1 + | +LL | pub struct S + | ^^^^^^^^^^^^ +note: but type `PrivTy` is only usable at visibility `pub(crate)` + --> $DIR/where-priv-type.rs:15:1 + | +LL | struct PrivTy; + | ^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/where-priv-type.rs:8:9 + | +LL | #![warn(private_bounds)] + | ^^^^^^^^^^^^^^ + warning: private type `PrivTy` in public interface (error E0446) - --> $DIR/where-priv-type.rs:27:1 + --> $DIR/where-priv-type.rs:33:1 | LL | pub enum E | ^^^^^^^^^^ @@ -17,8 +35,21 @@ LL | pub enum E = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 +warning: type `PrivTy` is more private than the item `E` + | +note: enum `E` is reachable at visibility `pub` + --> $DIR/where-priv-type.rs:33:1 + | +LL | pub enum E + | ^^^^^^^^^^ +note: but type `PrivTy` is only usable at visibility `pub(crate)` + --> $DIR/where-priv-type.rs:15:1 + | +LL | struct PrivTy; + | ^^^^^^^^^^^^^ + warning: private type `PrivTy` in public interface (error E0446) - --> $DIR/where-priv-type.rs:35:1 + --> $DIR/where-priv-type.rs:41:1 | LL | / pub fn f() LL | | @@ -30,8 +61,25 @@ LL | | PrivTy: = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 +warning: type `PrivTy` is more private than the item `f` + | +note: function `f` is reachable at visibility `pub` + --> $DIR/where-priv-type.rs:41:1 + | +LL | / pub fn f() +LL | | +LL | | +LL | | where +LL | | PrivTy: + | |___________^ +note: but type `PrivTy` is only usable at visibility `pub(crate)` + --> $DIR/where-priv-type.rs:15:1 + | +LL | struct PrivTy; + | ^^^^^^^^^^^^^ + error[E0446]: private type `PrivTy` in public interface - --> $DIR/where-priv-type.rs:43:1 + --> $DIR/where-priv-type.rs:49:1 | LL | struct PrivTy; | ------------- `PrivTy` declared as private @@ -39,8 +87,21 @@ LL | struct PrivTy; LL | impl S | ^^^^^^ can't leak private type +warning: type `PrivTy` is more private than the item `S` + | +note: implementation `S` is reachable at visibility `pub` + --> $DIR/where-priv-type.rs:49:1 + | +LL | impl S + | ^^^^^^ +note: but type `PrivTy` is only usable at visibility `pub(crate)` + --> $DIR/where-priv-type.rs:15:1 + | +LL | struct PrivTy; + | ^^^^^^^^^^^^^ + warning: private type `PrivTy` in public interface (error E0446) - --> $DIR/where-priv-type.rs:48:5 + --> $DIR/where-priv-type.rs:54:5 | LL | / pub fn f() LL | | @@ -52,8 +113,25 @@ LL | | PrivTy: = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 +warning: type `PrivTy` is more private than the item `S::f` + | +note: associated function `S::f` is reachable at visibility `pub` + --> $DIR/where-priv-type.rs:54:5 + | +LL | / pub fn f() +LL | | +LL | | +LL | | where +LL | | PrivTy: + | |_______________^ +note: but type `PrivTy` is only usable at visibility `pub(crate)` + --> $DIR/where-priv-type.rs:15:1 + | +LL | struct PrivTy; + | ^^^^^^^^^^^^^ + error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface - --> $DIR/where-priv-type.rs:80:5 + --> $DIR/where-priv-type.rs:86:5 | LL | type AssocTy = Const<{ my_const_fn(U) }>; | ^^^^^^^^^^^^ can't leak private type @@ -61,6 +139,24 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>; LL | const fn my_const_fn(val: u8) -> u8 { | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private -error: aborting due to 2 previous errors; 4 warnings emitted +warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item ` as Trait>::AssocTy` + | +note: associated type ` as Trait>::AssocTy` is reachable at visibility `pub` + --> $DIR/where-priv-type.rs:86:5 + | +LL | type AssocTy = Const<{ my_const_fn(U) }>; + | ^^^^^^^^^^^^ +note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)` + --> $DIR/where-priv-type.rs:93:1 + | +LL | const fn my_const_fn(val: u8) -> u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/where-priv-type.rs:9:9 + | +LL | #![warn(private_interfaces)] + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors; 10 warnings emitted For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/privacy/where-pub-type-impls-priv-trait.rs b/tests/ui/privacy/where-pub-type-impls-priv-trait.rs index 87c211df16937..3aad893eae2bf 100644 --- a/tests/ui/privacy/where-pub-type-impls-priv-trait.rs +++ b/tests/ui/privacy/where-pub-type-impls-priv-trait.rs @@ -4,6 +4,11 @@ #![feature(generic_const_exprs)] #![allow(incomplete_features)] +#![warn(private_bounds)] + +// In this test both old and new private-in-public diagnostic were emitted. +// Old diagnostic will be deleted soon. +// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. struct PrivTy; trait PrivTr {} diff --git a/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr b/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr index a433cebbbc090..413f7f781cd85 100644 --- a/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr +++ b/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr @@ -1,5 +1,5 @@ error[E0445]: private trait `PrivTr` in public interface - --> $DIR/where-pub-type-impls-priv-trait.rs:19:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:24:1 | LL | trait PrivTr {} | ------------ `PrivTr` declared as private @@ -7,8 +7,26 @@ LL | trait PrivTr {} LL | pub struct S | ^^^^^^^^^^^^ can't leak private trait +warning: trait `PrivTr` is more private than the item `S` + | +note: struct `S` is reachable at visibility `pub` + --> $DIR/where-pub-type-impls-priv-trait.rs:24:1 + | +LL | pub struct S + | ^^^^^^^^^^^^ +note: but trait `PrivTr` is only usable at visibility `pub(crate)` + --> $DIR/where-pub-type-impls-priv-trait.rs:14:1 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/where-pub-type-impls-priv-trait.rs:7:9 + | +LL | #![warn(private_bounds)] + | ^^^^^^^^^^^^^^ + error[E0445]: private trait `PrivTr` in public interface - --> $DIR/where-pub-type-impls-priv-trait.rs:26:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:31:1 | LL | trait PrivTr {} | ------------ `PrivTr` declared as private @@ -16,8 +34,21 @@ LL | trait PrivTr {} LL | pub enum E | ^^^^^^^^^^ can't leak private trait +warning: trait `PrivTr` is more private than the item `E` + | +note: enum `E` is reachable at visibility `pub` + --> $DIR/where-pub-type-impls-priv-trait.rs:31:1 + | +LL | pub enum E + | ^^^^^^^^^^ +note: but trait `PrivTr` is only usable at visibility `pub(crate)` + --> $DIR/where-pub-type-impls-priv-trait.rs:14:1 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ + error[E0445]: private trait `PrivTr` in public interface - --> $DIR/where-pub-type-impls-priv-trait.rs:33:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:38:1 | LL | trait PrivTr {} | ------------ `PrivTr` declared as private @@ -28,8 +59,24 @@ LL | | where LL | | PubTy: PrivTr | |_________________^ can't leak private trait +warning: trait `PrivTr` is more private than the item `f` + | +note: function `f` is reachable at visibility `pub` + --> $DIR/where-pub-type-impls-priv-trait.rs:38:1 + | +LL | / pub fn f() +LL | | +LL | | where +LL | | PubTy: PrivTr + | |_________________^ +note: but trait `PrivTr` is only usable at visibility `pub(crate)` + --> $DIR/where-pub-type-impls-priv-trait.rs:14:1 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ + error[E0445]: private trait `PrivTr` in public interface - --> $DIR/where-pub-type-impls-priv-trait.rs:40:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:45:1 | LL | trait PrivTr {} | ------------ `PrivTr` declared as private @@ -37,8 +84,21 @@ LL | trait PrivTr {} LL | impl S | ^^^^^^ can't leak private trait +warning: trait `PrivTr` is more private than the item `S` + | +note: implementation `S` is reachable at visibility `pub` + --> $DIR/where-pub-type-impls-priv-trait.rs:45:1 + | +LL | impl S + | ^^^^^^ +note: but trait `PrivTr` is only usable at visibility `pub(crate)` + --> $DIR/where-pub-type-impls-priv-trait.rs:14:1 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ + error[E0445]: private trait `PrivTr` in public interface - --> $DIR/where-pub-type-impls-priv-trait.rs:45:5 + --> $DIR/where-pub-type-impls-priv-trait.rs:50:5 | LL | trait PrivTr {} | ------------ `PrivTr` declared as private @@ -49,6 +109,22 @@ LL | | where LL | | PubTy: PrivTr | |_____________________^ can't leak private trait -error: aborting due to 5 previous errors +warning: trait `PrivTr` is more private than the item `S::f` + | +note: associated function `S::f` is reachable at visibility `pub` + --> $DIR/where-pub-type-impls-priv-trait.rs:50:5 + | +LL | / pub fn f() +LL | | +LL | | where +LL | | PubTy: PrivTr + | |_____________________^ +note: but trait `PrivTr` is only usable at visibility `pub(crate)` + --> $DIR/where-pub-type-impls-priv-trait.rs:14:1 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ + +error: aborting due to 5 previous errors; 5 warnings emitted For more information about this error, try `rustc --explain E0445`. diff --git a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs index 67f888c5e9402..9e4ba80a784a5 100644 --- a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs +++ b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs @@ -1,15 +1,24 @@ #![allow(non_camel_case_types)] // genus is always capitalized +#![warn(private_interfaces)] +//~^ NOTE the lint level is defined here + +// In this test both old and new private-in-public diagnostic were emitted. +// Old diagnostic will be deleted soon. +// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. pub(crate) struct Snail; //~^ NOTE `Snail` declared as private +//~| NOTE but type `Snail` is only usable at visibility `pub(crate)` mod sea { pub(super) struct Turtle; //~^ NOTE `Turtle` declared as crate-private + //~| NOTE but type `Turtle` is only usable at visibility `pub(crate)` } struct Tortoise; //~^ NOTE `Tortoise` declared as private +//~| NOTE but type `Tortoise` is only usable at visibility `pub(crate)` pub struct Shell { pub(crate) creature: T, @@ -18,11 +27,14 @@ pub struct Shell { pub type Helix_pomatia = Shell; //~^ ERROR private type `Snail` in public interface //~| NOTE can't leak private type +//~| NOTE type alias `Helix_pomatia` is reachable at visibility `pub` pub type Dermochelys_coriacea = Shell; //~^ ERROR crate-private type `Turtle` in public interface //~| NOTE can't leak crate-private type +//~| NOTE type alias `Dermochelys_coriacea` is reachable at visibility `pub` pub type Testudo_graeca = Shell; //~^ ERROR private type `Tortoise` in public interface //~| NOTE can't leak private type +//~| NOTE type alias `Testudo_graeca` is reachable at visibility `pub` fn main() {} diff --git a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr index 39d4f5ac8d3cf..52f67d4cdd504 100644 --- a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr +++ b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr @@ -1,5 +1,5 @@ error[E0446]: private type `Snail` in public interface - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:18:1 + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:27:1 | LL | pub(crate) struct Snail; | ----------------------- `Snail` declared as private @@ -7,8 +7,26 @@ LL | pub(crate) struct Snail; LL | pub type Helix_pomatia = Shell; | ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type +warning: type `Snail` is more private than the item `Helix_pomatia` + | +note: type alias `Helix_pomatia` is reachable at visibility `pub` + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:27:1 + | +LL | pub type Helix_pomatia = Shell; + | ^^^^^^^^^^^^^^^^^^^^^^ +note: but type `Snail` is only usable at visibility `pub(crate)` + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:9:1 + | +LL | pub(crate) struct Snail; + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:2:9 + | +LL | #![warn(private_interfaces)] + | ^^^^^^^^^^^^^^^^^^ + error[E0446]: crate-private type `Turtle` in public interface - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:21:1 + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:31:1 | LL | pub(super) struct Turtle; | ------------------------ `Turtle` declared as crate-private @@ -16,8 +34,21 @@ LL | pub(super) struct Turtle; LL | pub type Dermochelys_coriacea = Shell; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak crate-private type +warning: type `Turtle` is more private than the item `Dermochelys_coriacea` + | +note: type alias `Dermochelys_coriacea` is reachable at visibility `pub` + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:31:1 + | +LL | pub type Dermochelys_coriacea = Shell; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: but type `Turtle` is only usable at visibility `pub(crate)` + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:14:5 + | +LL | pub(super) struct Turtle; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0446]: private type `Tortoise` in public interface - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:24:1 + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:35:1 | LL | struct Tortoise; | --------------- `Tortoise` declared as private @@ -25,6 +56,19 @@ LL | struct Tortoise; LL | pub type Testudo_graeca = Shell; | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type -error: aborting due to 3 previous errors +warning: type `Tortoise` is more private than the item `Testudo_graeca` + | +note: type alias `Testudo_graeca` is reachable at visibility `pub` + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:35:1 + | +LL | pub type Testudo_graeca = Shell; + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: but type `Tortoise` is only usable at visibility `pub(crate)` + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:19:1 + | +LL | struct Tortoise; + | ^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors; 3 warnings emitted For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/reachable/expr_return.rs b/tests/ui/reachable/expr_return.rs index 0fc43f45075da..0dbeb660eedea 100644 --- a/tests/ui/reachable/expr_return.rs +++ b/tests/ui/reachable/expr_return.rs @@ -7,7 +7,7 @@ fn a() { // Here we issue that the "2nd-innermost" return is unreachable, // but we stop there. - let x = {return {return {return;}}}; //~ ERROR unreachable + let x: () = {return {return {return;}}}; //~ ERROR unreachable } fn main() { } diff --git a/tests/ui/reachable/expr_return.stderr b/tests/ui/reachable/expr_return.stderr index e1bef80aeb00e..3791559f44000 100644 --- a/tests/ui/reachable/expr_return.stderr +++ b/tests/ui/reachable/expr_return.stderr @@ -1,11 +1,11 @@ error: unreachable expression - --> $DIR/expr_return.rs:10:22 + --> $DIR/expr_return.rs:10:26 | -LL | let x = {return {return {return;}}}; - | ^^^^^^^^------^^ - | | | - | | any code following this expression is unreachable - | unreachable expression +LL | let x: () = {return {return {return;}}}; + | ^^^^^^^^------^^ + | | | + | | any code following this expression is unreachable + | unreachable expression | note: the lint level is defined here --> $DIR/expr_return.rs:4:9 diff --git a/tests/ui/resolve/extern-prelude.rs b/tests/ui/resolve/extern-prelude.rs index 50fed6034aa02..b5f1d5d35b2dd 100644 --- a/tests/ui/resolve/extern-prelude.rs +++ b/tests/ui/resolve/extern-prelude.rs @@ -25,7 +25,7 @@ fn shadow_mod() { fn shadow_prelude() { // Extern prelude shadows standard library prelude - let x = Vec::new(0f32, ()); // OK + let x: () = Vec::new(0f32, ()); // OK } fn main() {} diff --git a/tests/ui/resolve/issue-105069.stderr b/tests/ui/resolve/issue-105069.stderr index 1e6c9c6e2dc34..a049cac830ab4 100644 --- a/tests/ui/resolve/issue-105069.stderr +++ b/tests/ui/resolve/issue-105069.stderr @@ -4,17 +4,19 @@ error[E0659]: `V` is ambiguous LL | use V; | ^ ambiguous name | - = note: ambiguous because of multiple potential import sources + = note: ambiguous because of multiple glob imports of a name in the same module note: `V` could refer to the variant imported here --> $DIR/issue-105069.rs:1:5 | LL | use self::A::*; | ^^^^^^^^^^ + = help: consider adding an explicit import of `V` to disambiguate note: `V` could also refer to the variant imported here --> $DIR/issue-105069.rs:3:5 | LL | use self::B::*; | ^^^^^^^^^^ + = help: consider adding an explicit import of `V` to disambiguate error: aborting due to previous error diff --git a/tests/ui/resolve/issue-109153.rs b/tests/ui/resolve/issue-109153.rs new file mode 100644 index 0000000000000..bff6c911236e6 --- /dev/null +++ b/tests/ui/resolve/issue-109153.rs @@ -0,0 +1,14 @@ +use foo::*; + +mod foo { + pub mod bar { + pub mod bar { + pub mod bar {} + } + } +} + +use bar::bar; //~ ERROR `bar` is ambiguous +use bar::*; + +fn main() { } diff --git a/tests/ui/resolve/issue-109153.stderr b/tests/ui/resolve/issue-109153.stderr new file mode 100644 index 0000000000000..1a345d2a3e3a7 --- /dev/null +++ b/tests/ui/resolve/issue-109153.stderr @@ -0,0 +1,23 @@ +error[E0659]: `bar` is ambiguous + --> $DIR/issue-109153.rs:11:5 + | +LL | use bar::bar; + | ^^^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `bar` could refer to the module imported here + --> $DIR/issue-109153.rs:1:5 + | +LL | use foo::*; + | ^^^^^^ + = help: consider adding an explicit import of `bar` to disambiguate +note: `bar` could also refer to the module imported here + --> $DIR/issue-109153.rs:12:5 + | +LL | use bar::*; + | ^^^^^^ + = help: consider adding an explicit import of `bar` to disambiguate + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/resolve/resolve-pseudo-shadowing.rs b/tests/ui/resolve/resolve-pseudo-shadowing.rs index 85c684ca0328e..0ee0d0efad6c9 100644 --- a/tests/ui/resolve/resolve-pseudo-shadowing.rs +++ b/tests/ui/resolve/resolve-pseudo-shadowing.rs @@ -3,7 +3,7 @@ fn check(_c: Clone) { fn check2() { - let _ = <() as std::clone::Clone>::clone(&()); + let () = <() as std::clone::Clone>::clone(&()); } check2(); } diff --git a/tests/ui/return-nil.rs b/tests/ui/return-nil.rs index fd5203ff0ed60..4fc937f96a1f4 100644 --- a/tests/ui/return-nil.rs +++ b/tests/ui/return-nil.rs @@ -1,6 +1,6 @@ // run-pass // pretty-expanded FIXME #23616 -fn f() { let x: () = (); return x; } +fn f() { let x = (); return x; } -pub fn main() { let _x = f(); } +pub fn main() { f(); } diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-allowed.rs b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-allowed.rs index a547d09d04822..2de37c859c97a 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-allowed.rs +++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-allowed.rs @@ -97,5 +97,5 @@ fn main() { #[cfg_attr(something, cfg(nothing))] #[deny(unused_mut)] c: i32, | {}; - let _ = c(1, 2); + c(1, 2); } diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs index a4d9d32b514ac..14539d4b6d8fa 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs +++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs @@ -116,6 +116,6 @@ fn main() { //~^ ERROR unused variable: `c` #[cfg_attr(something, cfg(nothing))] d: i32, | {}; - let _ = a(1); - let _ = c(1, 2); + a(1); + c(1, 2); } diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives.fixed b/tests/ui/rust-2018/edition-lint-infer-outlives.fixed index 868bdf2e068d8..5058d61b58802 100644 --- a/tests/ui/rust-2018/edition-lint-infer-outlives.fixed +++ b/tests/ui/rust-2018/edition-lint-infer-outlives.fixed @@ -801,4 +801,10 @@ where yoo: &'a U } +// https://github.com/rust-lang/rust/issues/105150 +struct InferredWhereBoundWithInlineBound<'a, T: ?Sized> +{ + data: &'a T, +} + fn main() {} diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives.rs b/tests/ui/rust-2018/edition-lint-infer-outlives.rs index 75783764ad6c9..3f63cb8e90030 100644 --- a/tests/ui/rust-2018/edition-lint-infer-outlives.rs +++ b/tests/ui/rust-2018/edition-lint-infer-outlives.rs @@ -801,4 +801,12 @@ where yoo: &'a U } +// https://github.com/rust-lang/rust/issues/105150 +struct InferredWhereBoundWithInlineBound<'a, T: ?Sized> +//~^ ERROR outlives requirements can be inferred + where T: 'a, +{ + data: &'a T, +} + fn main() {} diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives.stderr b/tests/ui/rust-2018/edition-lint-infer-outlives.stderr index e655fb4842c71..dbf301fd8a1b7 100644 --- a/tests/ui/rust-2018/edition-lint-infer-outlives.stderr +++ b/tests/ui/rust-2018/edition-lint-infer-outlives.stderr @@ -10,6 +10,15 @@ note: the lint level is defined here LL | #![deny(explicit_outlives_requirements)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: outlives requirements can be inferred + --> $DIR/edition-lint-infer-outlives.rs:805:56 + | +LL | struct InferredWhereBoundWithInlineBound<'a, T: ?Sized> + | ________________________________________________________^ +LL | | +LL | | where T: 'a, + | |________________^ help: remove this bound + error: outlives requirements can be inferred --> $DIR/edition-lint-infer-outlives.rs:26:31 | @@ -922,5 +931,5 @@ error: outlives requirements can be inferred LL | union BeeWhereOutlivesAyTeeWhereDebug<'a, 'b, T> where 'b: 'a, T: Debug { | ^^^^^^^^ help: remove this bound -error: aborting due to 153 previous errors +error: aborting due to 154 previous errors diff --git a/tests/ui/traits/bound/generic_trait.rs b/tests/ui/traits/bound/generic_trait.rs index 18382bb59a4e5..2484c5a88fb31 100644 --- a/tests/ui/traits/bound/generic_trait.rs +++ b/tests/ui/traits/bound/generic_trait.rs @@ -24,7 +24,7 @@ impl connection_factory for my_connection_factory { pub fn main() { let factory = (); - let connection = factory.create(); + let connection: () = factory.create(); let result = connection.read(); assert_eq!(result, 43); } diff --git a/tests/ui/traits/object/print_vtable_sizes.rs b/tests/ui/traits/object/print_vtable_sizes.rs new file mode 100644 index 0000000000000..5656094990be6 --- /dev/null +++ b/tests/ui/traits/object/print_vtable_sizes.rs @@ -0,0 +1,61 @@ +// check-pass +// compile-flags: -Z print-vtable-sizes +#![crate_type = "lib"] + +trait A: AsRef<[T::V]> + AsMut<[T::V]> {} + +trait B: AsRef + AsRef + AsRef + AsRef {} + +trait C { + fn x() {} // not object safe, shouldn't be reported +} + +// This ideally should not have any upcasting cost, +// but currently does due to a bug +trait D: Send + Sync + help::MarkerWithSuper {} + +// This can't have no cost without reordering, +// because `Super::f`. +trait E: help::MarkerWithSuper + Send + Sync {} + +trait F { + fn a(&self); + fn b(&self); + fn c(&self); + + fn d() -> Self + where + Self: Sized; +} + +trait G: AsRef + AsRef + help::MarkerWithSuper { + fn a(&self); + fn b(&self); + fn c(&self); + fn d(&self); + fn e(&self); + + fn f() -> Self + where + Self: Sized; +} + +// Traits with the same name +const _: () = { + trait S {} +}; +const _: () = { + trait S {} +}; + +mod help { + pub trait V { + type V; + } + + pub trait MarkerWithSuper: Super {} + + pub trait Super { + fn f(&self); + } +} diff --git a/tests/ui/traits/object/print_vtable_sizes.stdout b/tests/ui/traits/object/print_vtable_sizes.stdout new file mode 100644 index 0000000000000..3ba650bc36045 --- /dev/null +++ b/tests/ui/traits/object/print_vtable_sizes.stdout @@ -0,0 +1,11 @@ +print-vtable-sizes { "crate_name": "", "trait_name": "D", "entries": "7", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "3", "upcasting_cost_percent": "75" } +print-vtable-sizes { "crate_name": "", "trait_name": "E", "entries": "6", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "2", "upcasting_cost_percent": "50" } +print-vtable-sizes { "crate_name": "", "trait_name": "G", "entries": "14", "entries_ignoring_upcasting": "11", "entries_for_upcasting": "3", "upcasting_cost_percent": "27.27272727272727" } +print-vtable-sizes { "crate_name": "", "trait_name": "A", "entries": "6", "entries_ignoring_upcasting": "5", "entries_for_upcasting": "1", "upcasting_cost_percent": "20" } +print-vtable-sizes { "crate_name": "", "trait_name": "B", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "", "trait_name": "F", "entries": "6", "entries_ignoring_upcasting": "6", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "", "trait_name": "help::MarkerWithSuper", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "", "trait_name": "help::Super", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "", "trait_name": "help::V", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } diff --git a/tests/ui/transmutability/alignment/align-fail.rs b/tests/ui/transmutability/alignment/align-fail.rs new file mode 100644 index 0000000000000..7f6090a6e4db5 --- /dev/null +++ b/tests/ui/transmutability/alignment/align-fail.rs @@ -0,0 +1,23 @@ +// check-fail +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn main() { + assert::is_maybe_transmutable::<&'static [u8; 0], &'static [u16; 0]>(); //~ ERROR `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]` +} diff --git a/tests/ui/transmutability/alignment/align-fail.stderr b/tests/ui/transmutability/alignment/align-fail.stderr new file mode 100644 index 0000000000000..59246fb1b0371 --- /dev/null +++ b/tests/ui/transmutability/alignment/align-fail.stderr @@ -0,0 +1,30 @@ +error[E0277]: `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]` in the defining scope of `assert::Context` + --> $DIR/align-fail.rs:22:55 + | +LL | ...tatic [u8; 0], &'static [u16; 0]>(); + | ^^^^^^^^^^^^^^^^^ The minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2) + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/align-fail.rs:10:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` +help: consider removing the leading `&`-reference + | +LL - assert::is_maybe_transmutable::<&'static [u8; 0], &'static [u16; 0]>(); +LL + assert::is_maybe_transmutable::<&'static [u8; 0], [u16; 0]>(); + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/alignment/align-pass.rs b/tests/ui/transmutability/alignment/align-pass.rs new file mode 100644 index 0000000000000..62dc672eacb9b --- /dev/null +++ b/tests/ui/transmutability/alignment/align-pass.rs @@ -0,0 +1,23 @@ +// check-pass +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn main() { + assert::is_maybe_transmutable::<&'static [u16; 0], &'static [u8; 0]>(); +} diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr index 9877a6606a9fa..46cdaa925630a 100644 --- a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr +++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr @@ -90,7 +90,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0i16` in the defining scop --> $DIR/primitive_reprs_should_have_correct_length.rs:72:44 | LL | assert::is_transmutable::(); - | ^^^^^^^ At least one value of `u8` isn't a bit-valid value of `V0i16` + | ^^^^^^^ The size of `u8` is smaller than the size of `V0i16` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -134,7 +134,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0u16` in the defining scop --> $DIR/primitive_reprs_should_have_correct_length.rs:80:44 | LL | assert::is_transmutable::(); - | ^^^^^^^ At least one value of `u8` isn't a bit-valid value of `V0u16` + | ^^^^^^^ The size of `u8` is smaller than the size of `V0u16` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -178,7 +178,7 @@ error[E0277]: `u16` cannot be safely transmuted into `V0i32` in the defining sco --> $DIR/primitive_reprs_should_have_correct_length.rs:96:44 | LL | assert::is_transmutable::(); - | ^^^^^^^ At least one value of `u16` isn't a bit-valid value of `V0i32` + | ^^^^^^^ The size of `u16` is smaller than the size of `V0i32` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -222,7 +222,7 @@ error[E0277]: `u16` cannot be safely transmuted into `V0u32` in the defining sco --> $DIR/primitive_reprs_should_have_correct_length.rs:104:44 | LL | assert::is_transmutable::(); - | ^^^^^^^ At least one value of `u16` isn't a bit-valid value of `V0u32` + | ^^^^^^^ The size of `u16` is smaller than the size of `V0u32` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -266,7 +266,7 @@ error[E0277]: `u32` cannot be safely transmuted into `V0i64` in the defining sco --> $DIR/primitive_reprs_should_have_correct_length.rs:120:44 | LL | assert::is_transmutable::(); - | ^^^^^^^ At least one value of `u32` isn't a bit-valid value of `V0i64` + | ^^^^^^^ The size of `u32` is smaller than the size of `V0i64` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -310,7 +310,7 @@ error[E0277]: `u32` cannot be safely transmuted into `V0u64` in the defining sco --> $DIR/primitive_reprs_should_have_correct_length.rs:128:44 | LL | assert::is_transmutable::(); - | ^^^^^^^ At least one value of `u32` isn't a bit-valid value of `V0u64` + | ^^^^^^^ The size of `u32` is smaller than the size of `V0u64` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -354,7 +354,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0isize` in the defining sc --> $DIR/primitive_reprs_should_have_correct_length.rs:144:44 | LL | assert::is_transmutable::(); - | ^^^^^^^ At least one value of `u8` isn't a bit-valid value of `V0isize` + | ^^^^^^^ The size of `u8` is smaller than the size of `V0isize` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -398,7 +398,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0usize` in the defining sc --> $DIR/primitive_reprs_should_have_correct_length.rs:152:44 | LL | assert::is_transmutable::(); - | ^^^^^^^ At least one value of `u8` isn't a bit-valid value of `V0usize` + | ^^^^^^^ The size of `u8` is smaller than the size of `V0usize` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs index ebe34e13432b5..8d19cabc0f9f0 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs @@ -18,5 +18,5 @@ fn should_gracefully_handle_unknown_dst_field() { struct Context; #[repr(C)] struct Src; #[repr(C)] struct Dst(Missing); //~ cannot find type - assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted } diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr index 475e6f429f3c9..c2df398b8ff91 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr @@ -4,6 +4,22 @@ error[E0412]: cannot find type `Missing` in this scope LL | #[repr(C)] struct Dst(Missing); | ^^^^^^^ not found in this scope -error: aborting due to previous error +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_gracefully_handle_unknown_dst_field::Context` + --> $DIR/unknown_src_field.rs:21:36 + | +LL | assert::is_transmutable::(); + | ^^^ `Dst` has an unknown layout + | +note: required by a bound in `is_transmutable` + --> $DIR/unknown_src_field.rs:13:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0412`. +Some errors have detailed explanations: E0277, E0412. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/primitives/bool-mut.rs b/tests/ui/transmutability/primitives/bool-mut.rs new file mode 100644 index 0000000000000..49dbe90e4b8b3 --- /dev/null +++ b/tests/ui/transmutability/primitives/bool-mut.rs @@ -0,0 +1,17 @@ +// check-fail +//[next] compile-flags: -Ztrait-solver=next + +#![feature(transmutability)] +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn main() { + assert::is_transmutable::<&'static mut bool, &'static mut u8>() //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/primitives/bool-mut.stderr b/tests/ui/transmutability/primitives/bool-mut.stderr new file mode 100644 index 0000000000000..b36991e1c01c6 --- /dev/null +++ b/tests/ui/transmutability/primitives/bool-mut.stderr @@ -0,0 +1,18 @@ +error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context` + --> $DIR/bool-mut.rs:16:50 + | +LL | assert::is_transmutable::<&'static mut bool, &'static mut u8>() + | ^^^^^^^^^^^^^^^ At least one value of `u8` isn't a bit-valid value of `bool` + | +note: required by a bound in `is_transmutable` + --> $DIR/bool-mut.rs:11:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/primitives/bool.current.stderr b/tests/ui/transmutability/primitives/bool.current.stderr index 47c8438a251c2..4b3eb6c517d91 100644 --- a/tests/ui/transmutability/primitives/bool.current.stderr +++ b/tests/ui/transmutability/primitives/bool.current.stderr @@ -1,11 +1,11 @@ error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context` - --> $DIR/bool.rs:24:35 + --> $DIR/bool.rs:21:35 | LL | assert::is_transmutable::(); | ^^^^ At least one value of `u8` isn't a bit-valid value of `bool` | note: required by a bound in `is_transmutable` - --> $DIR/bool.rs:14:14 + --> $DIR/bool.rs:11:14 | LL | pub fn is_transmutable() | --------------- required by a bound in this function diff --git a/tests/ui/transmutability/primitives/bool.next.stderr b/tests/ui/transmutability/primitives/bool.next.stderr index 47c8438a251c2..4b3eb6c517d91 100644 --- a/tests/ui/transmutability/primitives/bool.next.stderr +++ b/tests/ui/transmutability/primitives/bool.next.stderr @@ -1,11 +1,11 @@ error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context` - --> $DIR/bool.rs:24:35 + --> $DIR/bool.rs:21:35 | LL | assert::is_transmutable::(); | ^^^^ At least one value of `u8` isn't a bit-valid value of `bool` | note: required by a bound in `is_transmutable` - --> $DIR/bool.rs:14:14 + --> $DIR/bool.rs:11:14 | LL | pub fn is_transmutable() | --------------- required by a bound in this function diff --git a/tests/ui/transmutability/primitives/bool.rs b/tests/ui/transmutability/primitives/bool.rs index de77cfc78aa89..654e7b47edecc 100644 --- a/tests/ui/transmutability/primitives/bool.rs +++ b/tests/ui/transmutability/primitives/bool.rs @@ -1,10 +1,7 @@ // revisions: current next //[next] compile-flags: -Ztrait-solver=next -#![crate_type = "lib"] #![feature(transmutability)] -#![allow(dead_code)] -#![allow(incomplete_features)] mod assert { use std::mem::{Assume, BikeshedIntrinsicFrom}; pub struct Context; @@ -20,7 +17,7 @@ mod assert { {} } -fn contrast_with_u8() { +fn main() { assert::is_transmutable::(); //~ ERROR cannot be safely transmuted assert::is_maybe_transmutable::(); assert::is_transmutable::(); diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs new file mode 100644 index 0000000000000..a6e2889d3f23d --- /dev/null +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs @@ -0,0 +1,25 @@ +// check-fail +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn main() { + #[repr(C)] struct A(bool, &'static A); + #[repr(C)] struct B(u8, &'static B); + assert::is_maybe_transmutable::<&'static A, &'static mut B>(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr new file mode 100644 index 0000000000000..4b4d6ad0298ee --- /dev/null +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr @@ -0,0 +1,25 @@ +error[E0277]: `&A` cannot be safely transmuted into `&mut B` in the defining scope of `assert::Context` + --> $DIR/recursive-wrapper-types-bit-compatible-mut.rs:24:49 + | +LL | assert::is_maybe_transmutable::<&'static A, &'static mut B>(); + | ^^^^^^^^^^^^^^ `&A` is a shared reference, but `&mut B` is a unique reference + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/recursive-wrapper-types-bit-compatible-mut.rs:10:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs new file mode 100644 index 0000000000000..3ea80173afaa9 --- /dev/null +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs @@ -0,0 +1,26 @@ +// check-fail +// FIXME(bryangarza): Change to check-pass when coinduction is supported for BikeshedIntrinsicFrom +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn main() { + #[repr(C)] struct A(bool, &'static A); + #[repr(C)] struct B(u8, &'static B); + assert::is_maybe_transmutable::<&'static A, &'static B>(); //~ ERROR overflow evaluating the requirement +} diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.stderr new file mode 100644 index 0000000000000..fae332e6af932 --- /dev/null +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.stderr @@ -0,0 +1,25 @@ +error[E0275]: overflow evaluating the requirement `B: BikeshedIntrinsicFrom` + --> $DIR/recursive-wrapper-types-bit-compatible.rs:25:5 + | +LL | assert::is_maybe_transmutable::<&'static A, &'static B>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/recursive-wrapper-types-bit-compatible.rs:11:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs new file mode 100644 index 0000000000000..e8582d2fd0212 --- /dev/null +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs @@ -0,0 +1,25 @@ +// check-fail +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn main() { + #[repr(C)] struct A(bool, &'static A); + #[repr(C)] struct B(u8, &'static B); + assert::is_maybe_transmutable::<&'static B, &'static A>(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr new file mode 100644 index 0000000000000..ecfe4865962f7 --- /dev/null +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr @@ -0,0 +1,25 @@ +error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context` + --> $DIR/recursive-wrapper-types-bit-incompatible.rs:24:49 + | +LL | assert::is_maybe_transmutable::<&'static B, &'static A>(); + | ^^^^^^^^^^ At least one value of `B` isn't a bit-valid value of `A` + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/recursive-wrapper-types-bit-incompatible.rs:10:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/references/recursive-wrapper-types.rs b/tests/ui/transmutability/references/recursive-wrapper-types.rs new file mode 100644 index 0000000000000..59d1ad84a5d4c --- /dev/null +++ b/tests/ui/transmutability/references/recursive-wrapper-types.rs @@ -0,0 +1,27 @@ +// check-fail +// FIXME(bryangarza): Change to check-pass when coinduction is supported for BikeshedIntrinsicFrom +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn main() { + #[repr(C)] struct A(&'static B); + #[repr(C)] struct B(&'static A); + assert::is_maybe_transmutable::<&'static A, &'static B>(); //~ overflow evaluating the requirement + assert::is_maybe_transmutable::<&'static B, &'static A>(); +} diff --git a/tests/ui/transmutability/references.next.stderr b/tests/ui/transmutability/references/recursive-wrapper-types.stderr similarity index 56% rename from tests/ui/transmutability/references.next.stderr rename to tests/ui/transmutability/references/recursive-wrapper-types.stderr index 819c9b92bc81a..35a60c226437a 100644 --- a/tests/ui/transmutability/references.next.stderr +++ b/tests/ui/transmutability/references/recursive-wrapper-types.stderr @@ -1,11 +1,11 @@ -error[E0277]: `&Unit` cannot be safely transmuted into `&Unit` in the defining scope of `assert::Context` - --> $DIR/references.rs:29:52 +error[E0275]: overflow evaluating the requirement `A: BikeshedIntrinsicFrom` + --> $DIR/recursive-wrapper-types.rs:25:5 | -LL | assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); - | ^^^^^^^^^^^^^ `&Unit` does not have a well-specified layout +LL | assert::is_maybe_transmutable::<&'static A, &'static B>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: required by a bound in `is_maybe_transmutable` - --> $DIR/references.rs:16:14 + --> $DIR/recursive-wrapper-types.rs:11:14 | LL | pub fn is_maybe_transmutable() | --------------------- required by a bound in this function @@ -14,7 +14,7 @@ LL | Dst: BikeshedIntrinsicFrom @@ -22,4 +22,4 @@ LL | | }> error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/transmutability/references/u8-to-unit.rs b/tests/ui/transmutability/references/u8-to-unit.rs new file mode 100644 index 0000000000000..8b37492bd6b1c --- /dev/null +++ b/tests/ui/transmutability/references/u8-to-unit.rs @@ -0,0 +1,24 @@ +// check-pass +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn main() { + #[repr(C)] struct Unit; + assert::is_maybe_transmutable::<&'static u8, &'static Unit>(); +} diff --git a/tests/ui/transmutability/references.rs b/tests/ui/transmutability/references/unit-to-itself.rs similarity index 55% rename from tests/ui/transmutability/references.rs rename to tests/ui/transmutability/references/unit-to-itself.rs index 8c2b25ebba1e3..04a7e16d7cccc 100644 --- a/tests/ui/transmutability/references.rs +++ b/tests/ui/transmutability/references/unit-to-itself.rs @@ -1,11 +1,5 @@ -// revisions: current next -//[next] compile-flags: -Ztrait-solver=next - -//! Transmutations involving references are not yet supported. - -#![crate_type = "lib"] +// check-pass #![feature(transmutability)] -#![allow(dead_code, incomplete_features, non_camel_case_types)] mod assert { use std::mem::{Assume, BikeshedIntrinsicFrom}; @@ -16,15 +10,15 @@ mod assert { Dst: BikeshedIntrinsicFrom {} } -fn not_yet_implemented() { +fn main() { #[repr(C)] struct Unit; - assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); } diff --git a/tests/ui/transmutability/references/unit-to-u8.rs b/tests/ui/transmutability/references/unit-to-u8.rs new file mode 100644 index 0000000000000..eff516e9a9691 --- /dev/null +++ b/tests/ui/transmutability/references/unit-to-u8.rs @@ -0,0 +1,24 @@ +// check-fail +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn main() { + #[repr(C)] struct Unit; + assert::is_maybe_transmutable::<&'static Unit, &'static u8>(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/references.current.stderr b/tests/ui/transmutability/references/unit-to-u8.stderr similarity index 76% rename from tests/ui/transmutability/references.current.stderr rename to tests/ui/transmutability/references/unit-to-u8.stderr index 819c9b92bc81a..f2b72357f792b 100644 --- a/tests/ui/transmutability/references.current.stderr +++ b/tests/ui/transmutability/references/unit-to-u8.stderr @@ -1,11 +1,11 @@ -error[E0277]: `&Unit` cannot be safely transmuted into `&Unit` in the defining scope of `assert::Context` - --> $DIR/references.rs:29:52 +error[E0277]: `Unit` cannot be safely transmuted into `u8` in the defining scope of `assert::Context` + --> $DIR/unit-to-u8.rs:23:52 | -LL | assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); - | ^^^^^^^^^^^^^ `&Unit` does not have a well-specified layout +LL | assert::is_maybe_transmutable::<&'static Unit, &'static u8>(); + | ^^^^^^^^^^^ The size of `Unit` is smaller than the size of `u8` | note: required by a bound in `is_maybe_transmutable` - --> $DIR/references.rs:16:14 + --> $DIR/unit-to-u8.rs:10:14 | LL | pub fn is_maybe_transmutable() | --------------------- required by a bound in this function diff --git a/tests/ui/transmutability/region-infer.stderr b/tests/ui/transmutability/region-infer.stderr index d6b65e9e4a08b..307d0dfe50d22 100644 --- a/tests/ui/transmutability/region-infer.stderr +++ b/tests/ui/transmutability/region-infer.stderr @@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `W<'_>` in the defining scop --> $DIR/region-infer.rs:20:5 | LL | test(); - | ^^^^ `W<'_>` does not have a well-specified layout + | ^^^^ The size of `()` is smaller than the size of `W<'_>` | note: required by a bound in `test` --> $DIR/region-infer.rs:11:12 diff --git a/tests/ui/try-block/issue-45124.rs b/tests/ui/try-block/issue-45124.rs index 942014c9184d8..2cf2ade65e91f 100644 --- a/tests/ui/try-block/issue-45124.rs +++ b/tests/ui/try-block/issue-45124.rs @@ -8,7 +8,7 @@ fn main() { let mut a = 0; let () = { let _: Result<(), ()> = try { - let _ = Err(())?; + let () = Err(())?; return }; a += 1; diff --git a/tests/ui/tuple/index-float.rs b/tests/ui/tuple/index-float.rs index eda2bf48581a0..53b025c9135b2 100644 --- a/tests/ui/tuple/index-float.rs +++ b/tests/ui/tuple/index-float.rs @@ -3,8 +3,8 @@ fn main() { let tuple = (((),),); - let _ = tuple. 0.0; // OK, whitespace - let _ = tuple.0. 0; // OK, whitespace + let () = tuple. 0.0; // OK, whitespace + let () = tuple.0. 0; // OK, whitespace - let _ = tuple./*special cases*/0.0; // OK, comment + let () = tuple./*special cases*/0.0; // OK, comment } diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed new file mode 100644 index 0000000000000..bdb884f54312c --- /dev/null +++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed @@ -0,0 +1,10 @@ +// run-rustfix + +fn main() { + let _ptr1: *const u32 = std::ptr::null(); + let _ptr2: *const u32 = std::ptr::null(); + let _a = _ptr1.wrapping_add(5); //~ ERROR cannot add + let _b = _ptr1.wrapping_sub(5); //~ ERROR cannot subtract + let _c = unsafe { _ptr2.offset_from(_ptr1) }; //~ ERROR cannot subtract + let _d = _ptr1.wrapping_add(5); //~ ERROR cannot index +} diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs new file mode 100644 index 0000000000000..cf68850cc4dee --- /dev/null +++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs @@ -0,0 +1,10 @@ +// run-rustfix + +fn main() { + let _ptr1: *const u32 = std::ptr::null(); + let _ptr2: *const u32 = std::ptr::null(); + let _a = _ptr1 + 5; //~ ERROR cannot add + let _b = _ptr1 - 5; //~ ERROR cannot subtract + let _c = _ptr2 - _ptr1; //~ ERROR cannot subtract + let _d = _ptr1[5]; //~ ERROR cannot index +} diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr new file mode 100644 index 0000000000000..c55930da225ba --- /dev/null +++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr @@ -0,0 +1,54 @@ +error[E0369]: cannot add `{integer}` to `*const u32` + --> $DIR/issue-112252-ptr-arithmetics-help.rs:6:20 + | +LL | let _a = _ptr1 + 5; + | ----- ^ - {integer} + | | + | *const u32 + | +help: consider using `wrapping_add` or `add` for pointer + {integer} + | +LL | let _a = _ptr1.wrapping_add(5); + | ~~~~~~~~~~~~~~ + + +error[E0369]: cannot subtract `{integer}` from `*const u32` + --> $DIR/issue-112252-ptr-arithmetics-help.rs:7:20 + | +LL | let _b = _ptr1 - 5; + | ----- ^ - {integer} + | | + | *const u32 + | +help: consider using `wrapping_sub` or `sub` for pointer - {integer} + | +LL | let _b = _ptr1.wrapping_sub(5); + | ~~~~~~~~~~~~~~ + + +error[E0369]: cannot subtract `*const u32` from `*const u32` + --> $DIR/issue-112252-ptr-arithmetics-help.rs:8:20 + | +LL | let _c = _ptr2 - _ptr1; + | ----- ^ ----- *const u32 + | | + | *const u32 + | +help: consider using `offset_from` for pointer - pointer if the pointers point to the same allocation + | +LL | let _c = unsafe { _ptr2.offset_from(_ptr1) }; + | ++++++++ ~~~~~~~~~~~~~ +++ + +error[E0608]: cannot index into a value of type `*const u32` + --> $DIR/issue-112252-ptr-arithmetics-help.rs:9:14 + | +LL | let _d = _ptr1[5]; + | ^^^^^^^^ + | +help: consider using `wrapping_add` or `add` for indexing into raw pointer + | +LL | let _d = _ptr1.wrapping_add(5); + | ~~~~~~~~~~~~~~ ~ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0369, E0608. +For more information about an error, try `rustc --explain E0369`. diff --git a/tests/ui/typeck/ptr-null-mutability-suggestions.fixed b/tests/ui/typeck/ptr-null-mutability-suggestions.fixed new file mode 100644 index 0000000000000..d00536b29cff8 --- /dev/null +++ b/tests/ui/typeck/ptr-null-mutability-suggestions.fixed @@ -0,0 +1,11 @@ +// run-rustfix + +#[allow(unused_imports)] +use std::ptr; + +fn expecting_null_mut(_: *mut u8) {} + +fn main() { + expecting_null_mut(core::ptr::null_mut()); + //~^ ERROR mismatched types +} diff --git a/tests/ui/typeck/ptr-null-mutability-suggestions.rs b/tests/ui/typeck/ptr-null-mutability-suggestions.rs new file mode 100644 index 0000000000000..ea3066d2289f5 --- /dev/null +++ b/tests/ui/typeck/ptr-null-mutability-suggestions.rs @@ -0,0 +1,11 @@ +// run-rustfix + +#[allow(unused_imports)] +use std::ptr; + +fn expecting_null_mut(_: *mut u8) {} + +fn main() { + expecting_null_mut(ptr::null()); + //~^ ERROR mismatched types +} diff --git a/tests/ui/typeck/ptr-null-mutability-suggestions.stderr b/tests/ui/typeck/ptr-null-mutability-suggestions.stderr new file mode 100644 index 0000000000000..705b029bdeab5 --- /dev/null +++ b/tests/ui/typeck/ptr-null-mutability-suggestions.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/ptr-null-mutability-suggestions.rs:9:24 + | +LL | expecting_null_mut(ptr::null()); + | ------------------ ^^^^^^^^^^^ + | | | + | | types differ in mutability + | | help: consider using `core::ptr::null_mut` instead: `core::ptr::null_mut()` + | arguments to this function are incorrect + | + = note: expected raw pointer `*mut u8` + found raw pointer `*const _` +note: function defined here + --> $DIR/ptr-null-mutability-suggestions.rs:6:4 + | +LL | fn expecting_null_mut(_: *mut u8) {} + | ^^^^^^^^^^^^^^^^^^ ---------- + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/typeck/type-placeholder-fn-in-const.rs b/tests/ui/typeck/type-placeholder-fn-in-const.rs index ab2e2d8c53aa3..bbb95a5798af5 100644 --- a/tests/ui/typeck/type-placeholder-fn-in-const.rs +++ b/tests/ui/typeck/type-placeholder-fn-in-const.rs @@ -3,12 +3,13 @@ struct MyStruct; trait Test { const TEST: fn() -> _; //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] - //~| ERROR: the placeholder `_` is not allowed within types on item signatures for constants [E0121] + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121] } impl Test for MyStruct { const TEST: fn() -> _ = 42; //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121] } fn main() {} diff --git a/tests/ui/typeck/type-placeholder-fn-in-const.stderr b/tests/ui/typeck/type-placeholder-fn-in-const.stderr index e7b2e554a8d42..302359d2500c9 100644 --- a/tests/ui/typeck/type-placeholder-fn-in-const.stderr +++ b/tests/ui/typeck/type-placeholder-fn-in-const.stderr @@ -4,7 +4,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | const TEST: fn() -> _; | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/type-placeholder-fn-in-const.rs:4:25 | LL | const TEST: fn() -> _; @@ -16,6 +16,12 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | const TEST: fn() -> _ = 42; | ^ not allowed in type signatures -error: aborting due to 3 previous errors +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants + --> $DIR/type-placeholder-fn-in-const.rs:10:25 + | +LL | const TEST: fn() -> _ = 42; + | ^ not allowed in type signatures + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index 46aed0f603e87..4eba14f5a93fb 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -190,9 +190,9 @@ trait Qux { type B = _; //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types const C: _; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants const D: _ = 42; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants // type E: _; // FIXME: make the parser propagate the existence of `B` type F: std::ops::Fn(_); //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types @@ -203,10 +203,10 @@ impl Qux for Struct { type B = _; //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types const C: _; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants //~| ERROR associated constant in `impl` without body const D: _ = 42; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants } fn map(_: fn() -> Option<&'static T>) -> Option { diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index bc02547c65eb8..0c5e7e3cecb19 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -525,13 +525,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | type B = _; | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/typeck_type_placeholder_item.rs:192:14 | LL | const C: _; | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/typeck_type_placeholder_item.rs:194:14 | LL | const D: _ = 42; @@ -642,13 +642,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | type B = _; | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/typeck_type_placeholder_item.rs:205:14 | LL | const C: _; | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/typeck_type_placeholder_item.rs:208:14 | LL | const D: _ = 42; diff --git a/tests/ui/typeck/typeck_type_placeholder_item_help.rs b/tests/ui/typeck/typeck_type_placeholder_item_help.rs index c459d8c3cdc17..914f8a2b28b34 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item_help.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item_help.rs @@ -16,14 +16,14 @@ const TEST4: fn() -> _ = 42; trait Test5 { const TEST5: _ = 42; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants } struct Test6; impl Test6 { const TEST6: _ = 13; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants } pub fn main() { diff --git a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr index 07a5dbd93c743..ed6f4088019f7 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr @@ -37,7 +37,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | const TEST4: fn() -> _ = 42; | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/typeck_type_placeholder_item_help.rs:18:18 | LL | const TEST5: _ = 42; @@ -46,7 +46,7 @@ LL | const TEST5: _ = 42; | not allowed in type signatures | help: replace with the correct type: `i32` -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/typeck_type_placeholder_item_help.rs:25:18 | LL | const TEST6: _ = 13; diff --git a/tests/ui/unsafe/auxiliary/external_unsafe_macro.rs b/tests/ui/unsafe/auxiliary/external_unsafe_macro.rs new file mode 100644 index 0000000000000..b3837338b331e --- /dev/null +++ b/tests/ui/unsafe/auxiliary/external_unsafe_macro.rs @@ -0,0 +1,4 @@ +pub unsafe fn unsf() {} + +#[macro_export] +macro_rules! unsafe_macro { () => ($crate::unsf()) } diff --git a/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr b/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr index 6f005fe895848..0c0826c1cfb39 100644 --- a/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr +++ b/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr @@ -5,6 +5,11 @@ LL | unsf(); | ^^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior +note: an unsafe function restricts its caller, but its body is safe by default + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:11:1 + | +LL | unsafe fn deny_level() { + | ^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9 | @@ -46,6 +51,11 @@ LL | unsf(); | ^^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior +note: an unsafe function restricts its caller, but its body is safe by default + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:1 + | +LL | unsafe fn warning_level() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8 | diff --git a/tests/ui/unsafe/wrapping-unsafe-block-sugg.fixed b/tests/ui/unsafe/wrapping-unsafe-block-sugg.fixed new file mode 100644 index 0000000000000..db1c102210e3b --- /dev/null +++ b/tests/ui/unsafe/wrapping-unsafe-block-sugg.fixed @@ -0,0 +1,66 @@ +// run-rustfix +// aux-build:external_unsafe_macro.rs + +#![deny(unsafe_op_in_unsafe_fn)] //~ NOTE + +extern crate external_unsafe_macro; + +unsafe fn unsf() {} + +pub unsafe fn foo() { unsafe { + //~^ NOTE an unsafe function restricts its caller, but its body is safe by default + unsf(); //~ ERROR call to unsafe function is unsafe + //~^ NOTE + //~| NOTE + unsf(); //~ ERROR call to unsafe function is unsafe + //~^ NOTE + //~| NOTE +}} + +pub unsafe fn bar(x: *const i32) -> i32 { unsafe { + //~^ NOTE an unsafe function restricts its caller, but its body is safe by default + let y = *x; //~ ERROR dereference of raw pointer is unsafe and requires unsafe block + //~^ NOTE + //~| NOTE + y + *x //~ ERROR dereference of raw pointer is unsafe and requires unsafe block + //~^ NOTE + //~| NOTE +}} + +static mut BAZ: i32 = 0; +pub unsafe fn baz() -> i32 { unsafe { + //~^ NOTE an unsafe function restricts its caller, but its body is safe by default + let y = BAZ; //~ ERROR use of mutable static is unsafe and requires unsafe block + //~^ NOTE + //~| NOTE + y + BAZ //~ ERROR use of mutable static is unsafe and requires unsafe block + //~^ NOTE + //~| NOTE +}} + +macro_rules! unsafe_macro { () => (unsf()) } +//~^ ERROR call to unsafe function is unsafe +//~| NOTE +//~| NOTE +//~| ERROR call to unsafe function is unsafe +//~| NOTE +//~| NOTE + +pub unsafe fn unsafe_in_macro() { unsafe { + //~^ NOTE an unsafe function restricts its caller, but its body is safe by default + unsafe_macro!(); + //~^ NOTE + //~| NOTE + unsafe_macro!(); + //~^ NOTE + //~| NOTE +}} + +pub unsafe fn unsafe_in_external_macro() { + // FIXME: https://github.com/rust-lang/rust/issues/112504 + // FIXME: ~^ NOTE an unsafe function restricts its caller, but its body is safe by default + external_unsafe_macro::unsafe_macro!(); + external_unsafe_macro::unsafe_macro!(); +} + +fn main() {} diff --git a/tests/ui/unsafe/wrapping-unsafe-block-sugg.rs b/tests/ui/unsafe/wrapping-unsafe-block-sugg.rs new file mode 100644 index 0000000000000..9c6be45896e25 --- /dev/null +++ b/tests/ui/unsafe/wrapping-unsafe-block-sugg.rs @@ -0,0 +1,66 @@ +// run-rustfix +// aux-build:external_unsafe_macro.rs + +#![deny(unsafe_op_in_unsafe_fn)] //~ NOTE + +extern crate external_unsafe_macro; + +unsafe fn unsf() {} + +pub unsafe fn foo() { + //~^ NOTE an unsafe function restricts its caller, but its body is safe by default + unsf(); //~ ERROR call to unsafe function is unsafe + //~^ NOTE + //~| NOTE + unsf(); //~ ERROR call to unsafe function is unsafe + //~^ NOTE + //~| NOTE +} + +pub unsafe fn bar(x: *const i32) -> i32 { + //~^ NOTE an unsafe function restricts its caller, but its body is safe by default + let y = *x; //~ ERROR dereference of raw pointer is unsafe and requires unsafe block + //~^ NOTE + //~| NOTE + y + *x //~ ERROR dereference of raw pointer is unsafe and requires unsafe block + //~^ NOTE + //~| NOTE +} + +static mut BAZ: i32 = 0; +pub unsafe fn baz() -> i32 { + //~^ NOTE an unsafe function restricts its caller, but its body is safe by default + let y = BAZ; //~ ERROR use of mutable static is unsafe and requires unsafe block + //~^ NOTE + //~| NOTE + y + BAZ //~ ERROR use of mutable static is unsafe and requires unsafe block + //~^ NOTE + //~| NOTE +} + +macro_rules! unsafe_macro { () => (unsf()) } +//~^ ERROR call to unsafe function is unsafe +//~| NOTE +//~| NOTE +//~| ERROR call to unsafe function is unsafe +//~| NOTE +//~| NOTE + +pub unsafe fn unsafe_in_macro() { + //~^ NOTE an unsafe function restricts its caller, but its body is safe by default + unsafe_macro!(); + //~^ NOTE + //~| NOTE + unsafe_macro!(); + //~^ NOTE + //~| NOTE +} + +pub unsafe fn unsafe_in_external_macro() { + // FIXME: https://github.com/rust-lang/rust/issues/112504 + // FIXME: ~^ NOTE an unsafe function restricts its caller, but its body is safe by default + external_unsafe_macro::unsafe_macro!(); + external_unsafe_macro::unsafe_macro!(); +} + +fn main() {} diff --git a/tests/ui/unsafe/wrapping-unsafe-block-sugg.stderr b/tests/ui/unsafe/wrapping-unsafe-block-sugg.stderr new file mode 100644 index 0000000000000..43f619c27d274 --- /dev/null +++ b/tests/ui/unsafe/wrapping-unsafe-block-sugg.stderr @@ -0,0 +1,99 @@ +error: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/wrapping-unsafe-block-sugg.rs:12:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior +note: an unsafe function restricts its caller, but its body is safe by default + --> $DIR/wrapping-unsafe-block-sugg.rs:10:1 + | +LL | pub unsafe fn foo() { + | ^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/wrapping-unsafe-block-sugg.rs:4:9 + | +LL | #![deny(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/wrapping-unsafe-block-sugg.rs:15:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) + --> $DIR/wrapping-unsafe-block-sugg.rs:22:13 + | +LL | let y = *x; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior +note: an unsafe function restricts its caller, but its body is safe by default + --> $DIR/wrapping-unsafe-block-sugg.rs:20:1 + | +LL | pub unsafe fn bar(x: *const i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) + --> $DIR/wrapping-unsafe-block-sugg.rs:25:9 + | +LL | y + *x + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: use of mutable static is unsafe and requires unsafe block (error E0133) + --> $DIR/wrapping-unsafe-block-sugg.rs:33:13 + | +LL | let y = BAZ; + | ^^^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior +note: an unsafe function restricts its caller, but its body is safe by default + --> $DIR/wrapping-unsafe-block-sugg.rs:31:1 + | +LL | pub unsafe fn baz() -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: use of mutable static is unsafe and requires unsafe block (error E0133) + --> $DIR/wrapping-unsafe-block-sugg.rs:36:9 + | +LL | y + BAZ + | ^^^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/wrapping-unsafe-block-sugg.rs:41:36 + | +LL | macro_rules! unsafe_macro { () => (unsf()) } + | ^^^^^^ call to unsafe function +... +LL | unsafe_macro!(); + | --------------- in this macro invocation + | + = note: consult the function's documentation for information on how to avoid undefined behavior +note: an unsafe function restricts its caller, but its body is safe by default + --> $DIR/wrapping-unsafe-block-sugg.rs:49:1 + | +LL | pub unsafe fn unsafe_in_macro() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `unsafe_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/wrapping-unsafe-block-sugg.rs:41:36 + | +LL | macro_rules! unsafe_macro { () => (unsf()) } + | ^^^^^^ call to unsafe function +... +LL | unsafe_macro!(); + | --------------- in this macro invocation + | + = note: consult the function's documentation for information on how to avoid undefined behavior + = note: this error originates in the macro `unsafe_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 8 previous errors + diff --git a/tests/ui/unsized-locals/rust-call.rs b/tests/ui/unsized-locals/rust-call.rs new file mode 100644 index 0000000000000..ff4075aa4c03c --- /dev/null +++ b/tests/ui/unsized-locals/rust-call.rs @@ -0,0 +1,12 @@ +#![feature(unsized_tuple_coercion)] +#![feature(unboxed_closures)] +#![feature(unsized_fn_params)] + +fn bad() -> extern "rust-call" fn(([u8],)) { todo!() } + +fn main() { + let f = bad(); + let slice: Box<([u8],)> = Box::new(([1; 8],)); + f(*slice); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time +} diff --git a/tests/ui/unsized-locals/rust-call.stderr b/tests/ui/unsized-locals/rust-call.stderr new file mode 100644 index 0000000000000..fff7ef75b3322 --- /dev/null +++ b/tests/ui/unsized-locals/rust-call.stderr @@ -0,0 +1,13 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/rust-call.rs:10:7 + | +LL | f(*slice); + | ^^^^^^ doesn't have a size known at compile-time + | + = help: within `([u8],)`, the trait `Sized` is not implemented for `[u8]` + = note: required because it appears within the type `([u8],)` + = note: argument required to be sized due to `extern "rust-call"` ABI + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/weird-exprs.rs b/tests/ui/weird-exprs.rs index c4fa850a4f9d1..59b4bb8ef8598 100644 --- a/tests/ui/weird-exprs.rs +++ b/tests/ui/weird-exprs.rs @@ -81,7 +81,7 @@ fn angrydome() { break; } } -fn evil_lincoln() { let _evil = println!("lincoln"); } +fn evil_lincoln() { let _evil: () = println!("lincoln"); } fn dots() { assert_eq!(String::from(".................................................."), @@ -137,7 +137,7 @@ fn punch_card() -> impl std::fmt::Debug { } fn r#match() { - let val = match match match match match () { + let val: () = match match match match match () { () => () } { () => () @@ -166,7 +166,7 @@ fn match_nested_if() { } fn monkey_barrel() { - let val = ()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=(); + let val: () = ()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=(); assert_eq!(val, ()); }