From a41d236a6e2c4108be79ded5f93fb91d497e46df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 9 Jan 2025 23:13:00 +0000 Subject: [PATCH 01/14] Always force non-trimming of path in `unreachable_patterns` lint Creating a "trimmed DefID path" when no error is being emitted is an ICE (on purpose). If we create a trimmed path for a lint that is then silenced before being emitted causes a known ICE. This side-steps the issue by always using `with_no_trimmed_path!`. This was verified to fix https://github.com/quinn-rs/quinn/, but couldn't write a repro case for the test suite. Fix #135289. (cherry picked from commit 93a19501c2bad56e73f0ac9f3ae062b614d30832) --- compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index a13b00e192167..6631086720068 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1086,14 +1086,7 @@ fn find_fallback_pattern_typo<'tcx>( let vis = cx.tcx.visibility(item.owner_id); if vis.is_accessible_from(parent, cx.tcx) { accessible.push(item_name); - let path = if item_name == name { - // We know that the const wasn't in scope because it has the exact - // same name, so we suggest the full path. - with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id)) - } else { - // The const is likely just typoed, and nothing else. - cx.tcx.def_path_str(item.owner_id) - }; + let path = with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id)); accessible_path.push(path); } else if name == item_name { // The const exists somewhere in this crate, but it can't be imported From eb03c329c22dab193c6c329af1fcada490334f3a Mon Sep 17 00:00:00 2001 From: Tanvi Pooranmal Meena Date: Mon, 13 Jan 2025 15:38:39 +0530 Subject: [PATCH 02/14] Add logic to override profile for non git sources (cherry picked from commit 7d806171d00f53a720e6784a878a98cbef5c3d4a) --- src/bootstrap/bootstrap.py | 5 +++++ src/bootstrap/src/core/config/config.rs | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 89415afbe3bc4..535bdecb092dd 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -1264,6 +1264,11 @@ def bootstrap(args): config_toml = "" profile = RustBuild.get_toml_static(config_toml, "profile") + is_non_git_source = not os.path.exists(os.path.join(rust_root, ".git")) + + if profile is None and is_non_git_source: + profile = "dist" + if profile is not None: # Allows creating alias for profile names, allowing # profiles to be renamed while maintaining back compatibility diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index dd2f11ad4690a..928e9746410d2 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2914,10 +2914,8 @@ impl Config { let if_unchanged = || { if self.rust_info.is_from_tarball() { // Git is needed for running "if-unchanged" logic. - println!( - "WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`." - ); - return false; + println!("ERROR: 'if-unchanged' is only compatible with Git managed sources."); + crate::exit!(1); } // Fetching the LLVM submodule is unnecessary for self-tests. From f3797062a3fd5df98fd236073b17278c3d9f03c2 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 16 Jan 2025 17:34:31 +0300 Subject: [PATCH 03/14] resolve symlinks of LLVM tool binaries before copying them There is a chance that these tools are being installed from an external LLVM and we have no control over them. If any of these tools use symlinks, they will fail during tarball distribution. This change makes copying process to resolve symlinks just before placing them into the destination path. Signed-off-by: onur-ozkan (cherry picked from commit cde58dd5f781c3998d2421132854d2a833937e85) --- src/bootstrap/src/core/build_steps/compile.rs | 8 +++++++- src/bootstrap/src/lib.rs | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index ca337aa9f4c32..eeb5b18fdbc4b 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1790,7 +1790,13 @@ impl Step for Assemble { // When using `download-ci-llvm`, some of the tools // may not exist, so skip trying to copy them. if src_path.exists() { - builder.copy_link(&src_path, &libdir_bin.join(&tool_exe)); + // There is a chance that these tools are being installed from an external LLVM. + // Use `Builder::resolve_symlink_and_copy` instead of `Builder::copy_link` to ensure + // we are copying the original file not the symlinked path, which causes issues for + // tarball distribution. + // + // See https://github.com/rust-lang/rust/issues/135554. + builder.resolve_symlink_and_copy(&src_path, &libdir_bin.join(&tool_exe)); } } } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 8405c22aff08f..ccc115a279fb5 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1657,6 +1657,14 @@ Executed at: {executed_at}"#, paths } + /// Copies a file from `src` to `dst`. + /// + /// If `src` is a symlink, `src` will be resolved to the actual path + /// and copied to `dst` instead of the symlink itself. + pub fn resolve_symlink_and_copy(&self, src: &Path, dst: &Path) { + self.copy_link_internal(src, dst, true); + } + /// Links a file from `src` to `dst`. /// Attempts to use hard links if possible, falling back to copying. /// You can neither rely on this being a copy nor it being a link, From 953a1a0031a5277cdb6e2776ab48c6773c3ded07 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 15 Jan 2025 09:58:04 +0100 Subject: [PATCH 04/14] avoid running the overlap check twice (cherry picked from commit ebbcfd4e7721aaf3211f0e8d3d6e304400c80f78) --- .../src/traits/coherence.rs | 55 +++++++++++-------- .../occurs-check/associated-type.next.stderr | 2 - .../occurs-check/associated-type.old.stderr | 2 - 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 971d3a8110254..190e34618d2af 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -116,28 +116,39 @@ pub fn overlapping_impls( return None; } - let _overlap_with_bad_diagnostics = overlap( - tcx, - TrackAmbiguityCauses::No, - skip_leak_check, - impl1_def_id, - impl2_def_id, - overlap_mode, - )?; - - // In the case where we detect an error, run the check again, but - // this time tracking intercrate ambiguity causes for better - // diagnostics. (These take time and can lead to false errors.) - let overlap = overlap( - tcx, - TrackAmbiguityCauses::Yes, - skip_leak_check, - impl1_def_id, - impl2_def_id, - overlap_mode, - ) - .unwrap(); - Some(overlap) + if tcx.next_trait_solver_in_coherence() { + overlap( + tcx, + TrackAmbiguityCauses::Yes, + skip_leak_check, + impl1_def_id, + impl2_def_id, + overlap_mode, + ) + } else { + let _overlap_with_bad_diagnostics = overlap( + tcx, + TrackAmbiguityCauses::No, + skip_leak_check, + impl1_def_id, + impl2_def_id, + overlap_mode, + )?; + + // In the case where we detect an error, run the check again, but + // this time tracking intercrate ambiguity causes for better + // diagnostics. (These take time and can lead to false errors.) + let overlap = overlap( + tcx, + TrackAmbiguityCauses::Yes, + skip_leak_check, + impl1_def_id, + impl2_def_id, + overlap_mode, + ) + .unwrap(); + Some(overlap) + } } fn fresh_impl_header<'tcx>(infcx: &InferCtxt<'tcx>, impl_def_id: DefId) -> ty::ImplHeader<'tcx> { diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index 466b991471ed9..25f9523f4e455 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr @@ -1,7 +1,5 @@ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:32:1 | diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index 1e0345f4ec05b..e091ddcacb20a 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr @@ -1,7 +1,5 @@ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:32:1 | From e35db4245bf73e30a7b6883c9333db24ff87e34d Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 17 Jan 2025 10:01:45 +0100 Subject: [PATCH 05/14] add cache to `AmbiguityCausesVisitor` (cherry picked from commit 94bf8f04f402a2410ab85a6e6b9e542e3942b2a2) --- .../rustc_trait_selection/src/traits/coherence.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 190e34618d2af..e27143f139641 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -6,7 +6,7 @@ use std::fmt::Debug; -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; @@ -626,6 +626,7 @@ fn compute_intercrate_ambiguity_causes<'tcx>( } struct AmbiguityCausesVisitor<'a, 'tcx> { + cache: FxHashSet>>, causes: &'a mut FxIndexSet>, } @@ -635,6 +636,10 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { } fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) { + if !self.cache.insert(goal.goal()) { + return; + } + let infcx = goal.infcx(); for cand in goal.candidates() { cand.visit_nested_in_probe(self); @@ -759,5 +764,10 @@ fn search_ambiguity_causes<'tcx>( goal: Goal<'tcx, ty::Predicate<'tcx>>, causes: &mut FxIndexSet>, ) { - infcx.probe(|_| infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor { causes })); + infcx.probe(|_| { + infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor { + cache: Default::default(), + causes, + }) + }); } From f6aed49d141b02d2669314e867b632c10be39be9 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 17 Jan 2025 13:23:25 +0100 Subject: [PATCH 06/14] add test (cherry picked from commit 0910173b3558b0ff7e9e160976618cbb55cb6149) --- .../ambiguity-causes-visitor-hang.rs | 56 +++++++++++++++++++ .../ambiguity-causes-visitor-hang.stderr | 14 +++++ 2 files changed, 70 insertions(+) create mode 100644 tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs create mode 100644 tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs new file mode 100644 index 0000000000000..54854b1b8a522 --- /dev/null +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs @@ -0,0 +1,56 @@ +// Computing the ambiguity causes for the overlap ended up +// causing an exponential blowup when recursing into the normalization +// goals for ` as RecursiveSuper>::Assoc`. This test +// takes multiple minutes when doing so and less than a second +// otherwise. + +//@ compile-flags: -Znext-solver=coherence + +trait RecursiveSuper: + Super< + A0 = Self::Assoc, + A1 = Self::Assoc, + A2 = Self::Assoc, + A3 = Self::Assoc, + A4 = Self::Assoc, + A5 = Self::Assoc, + A6 = Self::Assoc, + A7 = Self::Assoc, + A8 = Self::Assoc, + A9 = Self::Assoc, + A10 = Self::Assoc, + A11 = Self::Assoc, + A12 = Self::Assoc, + A13 = Self::Assoc, + A14 = Self::Assoc, + A15 = Self::Assoc, + > +{ + type Assoc; +} + +trait Super { + type A0; + type A1; + type A2; + type A3; + type A4; + type A5; + type A6; + type A7; + type A8; + type A9; + type A10; + type A11; + type A12; + type A13; + type A14; + type A15; +} + +trait Overlap {} +impl Overlap for T {} +impl Overlap for Box {} +//~^ ERROR conflicting implementations of trait `Overlap` for type `Box<_>` + +fn main() {} diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr new file mode 100644 index 0000000000000..3731dc5b74ec0 --- /dev/null +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr @@ -0,0 +1,14 @@ +error[E0119]: conflicting implementations of trait `Overlap` for type `Box<_>` + --> $DIR/ambiguity-causes-visitor-hang.rs:53:1 + | +LL | impl Overlap for T {} + | ------------------------------------- first implementation here +LL | impl Overlap for Box {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` + | + = note: downstream crates may implement trait `Super` for type `std::boxed::Box<_>` + = note: downstream crates may implement trait `RecursiveSuper` for type `std::boxed::Box<_>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. From 4595e112d0c76cd2717f56f6a596f7ebc35f1461 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Fri, 17 Jan 2025 09:44:09 -0800 Subject: [PATCH 07/14] When LLVM's location discriminator value limit is exceeded, emit locations with dummy spans instead of dropping them entirely Revert most of #133194 (except the test and the comment fixes). Then refix not emitting locations at all when the correct location discriminator value exceeds LLVM's capacity. (cherry picked from commit 45ef92731b637a60cbad7cecf5382361bbf40531) --- compiler/rustc_codegen_gcc/src/debuginfo.rs | 18 ++--- .../src/debuginfo/create_scope_map.rs | 59 +++++++---------- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 4 +- .../rustc_codegen_ssa/src/mir/debuginfo.rs | 6 +- .../main.rs | 3 + .../other.rs | 1 + .../proc.rs | 7 ++ .../rmake.rs | 65 +++++++++++++++++++ 8 files changed, 111 insertions(+), 52 deletions(-) create mode 100644 tests/run-make/llvm-location-discriminator-limit-dummy-span/main.rs create mode 100644 tests/run-make/llvm-location-discriminator-limit-dummy-span/other.rs create mode 100644 tests/run-make/llvm-location-discriminator-limit-dummy-span/proc.rs create mode 100644 tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index 6aeb656c1ab40..5d8c5c199b12c 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -113,15 +113,15 @@ fn make_mir_scope<'gcc, 'tcx>( let scope_data = &mir.source_scopes[scope]; let parent_scope = if let Some(parent) = scope_data.parent_scope { make_mir_scope(cx, _instance, mir, variables, debug_context, instantiated, parent); - debug_context.scopes[parent].unwrap() + debug_context.scopes[parent] } else { // The root is the function itself. let file = cx.sess().source_map().lookup_source_file(mir.span.lo()); - debug_context.scopes[scope] = Some(DebugScope { + debug_context.scopes[scope] = DebugScope { file_start_pos: file.start_pos, file_end_pos: file.end_position(), - ..debug_context.scopes[scope].unwrap() - }); + ..debug_context.scopes[scope] + }; instantiated.insert(scope); return; }; @@ -130,7 +130,7 @@ fn make_mir_scope<'gcc, 'tcx>( if !vars.contains(scope) && scope_data.inlined.is_none() { // Do not create a DIScope if there are no variables defined in this // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat. - debug_context.scopes[scope] = Some(parent_scope); + debug_context.scopes[scope] = parent_scope; instantiated.insert(scope); return; } @@ -157,12 +157,12 @@ fn make_mir_scope<'gcc, 'tcx>( // TODO(tempdragon): dbg_scope: Add support for scope extension here. inlined_at.or(p_inlined_at); - debug_context.scopes[scope] = Some(DebugScope { + debug_context.scopes[scope] = DebugScope { dbg_scope, inlined_at, file_start_pos: loc.file.start_pos, file_end_pos: loc.file.end_position(), - }); + }; instantiated.insert(scope); } @@ -232,12 +232,12 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } // Initialize fn debug context (including scopes). - let empty_scope = Some(DebugScope { + let empty_scope = DebugScope { dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)), inlined_at: None, file_start_pos: BytePos(0), file_end_pos: BytePos(0), - }); + }; let mut fn_debug_context = FunctionDebugContext { scopes: IndexVec::from_elem(empty_scope, mir.source_scopes.as_slice()), inlined_function_scopes: Default::default(), diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index 07bd0f4d1c171..11c1f9d39f7fb 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -9,7 +9,7 @@ use rustc_middle::mir::{Body, SourceScope}; use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv}; use rustc_middle::ty::{self, Instance}; use rustc_session::config::DebugInfo; -use rustc_span::{BytePos, hygiene}; +use rustc_span::{BytePos, DUMMY_SP, hygiene}; use super::metadata::file_metadata; use super::utils::DIB; @@ -85,23 +85,15 @@ fn make_mir_scope<'ll, 'tcx>( discriminators, parent, ); - if let Some(parent_scope) = debug_context.scopes[parent] { - parent_scope - } else { - // If the parent scope could not be represented then no children - // can be either. - debug_context.scopes[scope] = None; - instantiated.insert(scope); - return; - } + debug_context.scopes[parent] } else { // The root is the function itself. let file = cx.sess().source_map().lookup_source_file(mir.span.lo()); - debug_context.scopes[scope] = Some(DebugScope { + debug_context.scopes[scope] = DebugScope { file_start_pos: file.start_pos, file_end_pos: file.end_position(), - ..debug_context.scopes[scope].unwrap() - }); + ..debug_context.scopes[scope] + }; instantiated.insert(scope); return; }; @@ -112,7 +104,7 @@ fn make_mir_scope<'ll, 'tcx>( { // Do not create a DIScope if there are no variables defined in this // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat. - debug_context.scopes[scope] = Some(parent_scope); + debug_context.scopes[scope] = parent_scope; instantiated.insert(scope); return; } @@ -145,14 +137,7 @@ fn make_mir_scope<'ll, 'tcx>( }, }; - let mut debug_scope = Some(DebugScope { - dbg_scope, - inlined_at: parent_scope.inlined_at, - file_start_pos: loc.file.start_pos, - file_end_pos: loc.file.end_position(), - }); - - if let Some((_, callsite_span)) = scope_data.inlined { + let inlined_at = scope_data.inlined.map(|(_, callsite_span)| { let callsite_span = hygiene::walk_chain_collapsed(callsite_span, mir.span); let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span); let loc = cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span); @@ -175,29 +160,29 @@ fn make_mir_scope<'ll, 'tcx>( // Note further that we can't key this hashtable on the span itself, // because these spans could have distinct SyntaxContexts. We have // to key on exactly what we're giving to LLVM. - let inlined_at = match discriminators.entry(callsite_span.lo()) { + match discriminators.entry(callsite_span.lo()) { Entry::Occupied(mut o) => { *o.get_mut() += 1; + // NB: We have to emit *something* here or we'll fail LLVM IR verification + // in at least some circumstances (see issue #135322) so if the required + // discriminant cannot be encoded fall back to the dummy location. unsafe { llvm::LLVMRustDILocationCloneWithBaseDiscriminator(loc, *o.get()) } + .unwrap_or_else(|| { + cx.dbg_loc(callsite_scope, parent_scope.inlined_at, DUMMY_SP) + }) } Entry::Vacant(v) => { v.insert(0); - Some(loc) - } - }; - match inlined_at { - Some(inlined_at) => { - debug_scope.as_mut().unwrap().inlined_at = Some(inlined_at); - } - None => { - // LLVM has a maximum discriminator that it can encode (currently - // it uses 12 bits for 4096 possible values). If we exceed that - // there is little we can do but drop the debug info. - debug_scope = None; + loc } } - } + }); - debug_context.scopes[scope] = debug_scope; + debug_context.scopes[scope] = DebugScope { + dbg_scope, + inlined_at: inlined_at.or(parent_scope.inlined_at), + file_start_pos: loc.file.start_pos, + file_end_pos: loc.file.end_position(), + }; instantiated.insert(scope); } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index fae698bea2a6b..244df1be1d75e 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -293,12 +293,12 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { } // Initialize fn debug context (including scopes). - let empty_scope = Some(DebugScope { + let empty_scope = DebugScope { dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)), inlined_at: None, file_start_pos: BytePos(0), file_end_pos: BytePos(0), - }); + }; let mut fn_debug_context = FunctionDebugContext { scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes), inlined_function_scopes: Default::default(), diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 843a996d2bfe5..5924c8991ad64 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -19,9 +19,7 @@ use crate::traits::*; pub struct FunctionDebugContext<'tcx, S, L> { /// Maps from source code to the corresponding debug info scope. - /// May be None if the backend is not capable of representing the scope for - /// some reason. - pub scopes: IndexVec>>, + pub scopes: IndexVec>, /// Maps from an inlined function to its debug info declaration. pub inlined_function_scopes: FxHashMap, S>, @@ -232,7 +230,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &self, source_info: mir::SourceInfo, ) -> Option<(Bx::DIScope, Option, Span)> { - let scope = &self.debug_context.as_ref()?.scopes[source_info.scope]?; + let scope = &self.debug_context.as_ref()?.scopes[source_info.scope]; let span = hygiene::walk_chain_collapsed(source_info.span, self.mir.span); Some((scope.adjust_dbg_scope_for_span(self.cx, span), scope.inlined_at, span)) } diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/main.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/main.rs new file mode 100644 index 0000000000000..421eb4331b3ff --- /dev/null +++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/main.rs @@ -0,0 +1,3 @@ +fn main() { + other::big_function(); +} diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/other.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/other.rs new file mode 100644 index 0000000000000..a3ff578ebe411 --- /dev/null +++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/other.rs @@ -0,0 +1 @@ +proc::declare_big_function!(); diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/proc.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/proc.rs new file mode 100644 index 0000000000000..59d17a9be5933 --- /dev/null +++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/proc.rs @@ -0,0 +1,7 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn declare_big_function(_input: TokenStream) -> TokenStream { + include_str!("./generated.rs").parse().unwrap() +} diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs new file mode 100644 index 0000000000000..2727effe81883 --- /dev/null +++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs @@ -0,0 +1,65 @@ +//! Regression test for . +//! +//! We can't simply drop debuginfo location spans when LLVM's location discriminator value limit is +//! reached. Otherwise, with `-Z verify-llvm-ir` and fat LTO, LLVM will report a broken module for +//! +//! ```text +//! inlinable function call in a function with debug info must have a !dbg location +//! ``` + +//@ ignore-cross-compile +//@ needs-dynamic-linking +//@ only-nightly (requires unstable rustc flag) + +#![deny(warnings)] + +use run_make_support::{dynamic_lib_name, rfs, rust_lib_name, rustc}; + +// Synthesize a function that will have a large (`n`) number of functions +// MIR-inlined into it. When combined with a proc-macro, all of these inline +// callsites will have the same span, forcing rustc to use the DWARF +// discriminator to distinguish between them. LLVM's capacity to store that +// discriminator is not infinite (currently it allocates 12 bits for a +// maximum value of 4096) so if this function gets big enough rustc's error +// handling path will be exercised. +fn generate_program(n: u32) -> String { + let mut program = String::from("pub type BigType = Vec>;\n\n"); + program.push_str("pub fn big_function() -> BigType {\n"); + program.push_str(" vec![\n"); + for i in 1..=n { + program.push_str(&format!("vec![\"string{}\".to_owned()],\n", i)); + } + program.push_str(" ]\n"); + program.push_str("}\n"); + program +} + +fn main() { + // The reported threshold is around 1366 (4096/3), but let's bump it to + // around 1500 to be less sensitive. + rfs::write("generated.rs", generate_program(1500)); + + rustc() + .input("proc.rs") + .crate_type("proc-macro") + .edition("2021") + .arg("-Cdebuginfo=line-tables-only") + .run(); + rustc() + .extern_("proc", dynamic_lib_name("proc")) + .input("other.rs") + .crate_type("rlib") + .edition("2021") + .opt_level("3") + .arg("-Cdebuginfo=line-tables-only") + .run(); + rustc() + .extern_("other", rust_lib_name("other")) + .input("main.rs") + .edition("2021") + .opt_level("3") + .arg("-Cdebuginfo=line-tables-only") + .arg("-Clto=fat") + .arg("-Zverify-llvm-ir") + .run(); +} From 55e4e7d1946509ec839d76b77616bc67c92ab2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 18 Jan 2025 22:08:38 +0000 Subject: [PATCH 08/14] Revert "Auto merge of #134330 - scottmcm:no-more-rvalue-len, r=matthewjasper" This reverts commit e108481f74ff123ad98a63bd107a18d13035b275, reversing changes made to 303e8bd768526a5812bb1776e798e829ddb7d3ca. (cherry picked from commit ca1c17c88d1f625763859396ba7a50f36ac45cc0) --- compiler/rustc_borrowck/src/lib.rs | 10 +++- .../rustc_borrowck/src/places_conflict.rs | 3 +- .../src/polonius/legacy/loan_invalidations.rs | 9 +++- compiler/rustc_borrowck/src/type_check/mod.rs | 2 + compiler/rustc_codegen_cranelift/src/base.rs | 6 +++ compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 29 ++++++++++- .../src/check_consts/check.rs | 3 +- .../src/check_consts/qualifs.rs | 4 +- .../src/check_consts/resolver.rs | 1 + .../rustc_const_eval/src/interpret/step.rs | 8 ++- compiler/rustc_middle/src/mir/pretty.rs | 1 + compiler/rustc_middle/src/mir/statement.rs | 1 + compiler/rustc_middle/src/mir/syntax.rs | 10 ++++ compiler/rustc_middle/src/mir/tcx.rs | 1 + compiler/rustc_middle/src/mir/visit.rs | 8 +++ .../src/builder/custom/parse/instruction.rs | 1 + .../src/builder/expr/as_place.rs | 2 +- .../src/builder/matches/test.rs | 7 ++- .../src/impls/borrowed_locals.rs | 1 + .../src/move_paths/builder.rs | 1 + .../src/dataflow_const_prop.rs | 12 +++++ compiler/rustc_mir_transform/src/dest_prop.rs | 1 + compiler/rustc_mir_transform/src/gvn.rs | 51 +++++++++++++++++++ .../src/known_panics_lint.rs | 15 ++++++ .../rustc_mir_transform/src/promote_consts.rs | 4 +- compiler/rustc_mir_transform/src/validate.rs | 8 +++ .../rustc_smir/src/rustc_smir/convert/mir.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + library/core/src/intrinsics/mir.rs | 3 +- .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- .../custom/arrays.arrays.built.after.mir | 14 +++++ tests/mir-opt/building/custom/arrays.rs | 22 ++++++++ ...mment_2.DeduplicateBlocks.panic-abort.diff | 4 +- ...ment_2.DeduplicateBlocks.panic-unwind.diff | 4 +- ...implifyComparisonIntegral.panic-abort.diff | 32 +++++++----- ...mplifyComparisonIntegral.panic-unwind.diff | 32 +++++++----- ...e_prop.debuginfo.ReferencePropagation.diff | 9 ++-- 37 files changed, 272 insertions(+), 51 deletions(-) create mode 100644 tests/mir-opt/building/custom/arrays.arrays.built.after.mir create mode 100644 tests/mir-opt/building/custom/arrays.rs diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index e7aa827e6801c..38b1d391be70f 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -828,6 +828,7 @@ use self::ReadOrWrite::{Activation, Read, Reservation, Write}; #[derive(Copy, Clone, PartialEq, Eq, Debug)] enum ArtificialField { + ArrayLength, FakeBorrow, } @@ -1345,11 +1346,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { ); } - &Rvalue::Discriminant(place) => { + &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => { + let af = match *rvalue { + Rvalue::Len(..) => Some(ArtificialField::ArrayLength), + Rvalue::Discriminant(..) => None, + _ => unreachable!(), + }; self.access_place( location, (place, span), - (Shallow(None), Read(ReadKind::Copy)), + (Shallow(af), Read(ReadKind::Copy)), LocalMutationIsAllowed::No, state, ); diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index 560b8c0349ad6..679e111caa984 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -203,7 +203,8 @@ fn place_components_conflict<'tcx>( let base_ty = base.ty(body, tcx).ty; match (elem, base_ty.kind(), access) { - (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => { + (_, _, Shallow(Some(ArtificialField::ArrayLength))) + | (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => { // The array length is like additional fields on the // type; it does not overlap any existing data there. // Furthermore, if cannot actually be a prefix of any diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index bb6d593d0d88e..bb73bc9fcbd35 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -298,11 +298,16 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> { self.consume_operand(location, op); } - &Rvalue::Discriminant(place) => { + &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => { + let af = match rvalue { + Rvalue::Len(..) => Some(ArtificialField::ArrayLength), + Rvalue::Discriminant(..) => None, + _ => unreachable!(), + }; self.access_place( location, place, - (Shallow(None), Read(ReadKind::Copy)), + (Shallow(af), Read(ReadKind::Copy)), LocalMutationIsAllowed::No, ); } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 10fb8a399a267..084f122a2107d 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2221,6 +2221,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::RawPtr(..) | Rvalue::ThreadLocalRef(..) + | Rvalue::Len(..) | Rvalue::Discriminant(..) | Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {} } @@ -2236,6 +2237,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | Rvalue::Repeat(..) | Rvalue::Ref(..) | Rvalue::RawPtr(..) + | Rvalue::Len(..) | Rvalue::Cast(..) | Rvalue::ShallowInitBox(..) | Rvalue::BinaryOp(..) diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 956a024fa4dc3..34066eb83fc02 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -828,6 +828,12 @@ fn codegen_stmt<'tcx>( fx.bcx.ins().nop(); } } + Rvalue::Len(place) => { + let place = codegen_place(fx, place); + let usize_layout = fx.layout_of(fx.tcx.types.usize); + let len = codegen_array_len(fx, place); + lval.write_cvalue(fx, CValue::by_val(len, usize_layout)); + } Rvalue::ShallowInitBox(ref operand, content_ty) => { let content_ty = fx.monomorphize(content_ty); let box_layout = fx.layout_of(Ty::new_box(fx.tcx, content_ty)); diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 3b62148abb789..cf53739223467 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -10,9 +10,9 @@ use rustc_session::config::OptLevel; use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument}; -use super::FunctionCx; use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; +use super::{FunctionCx, LocalRef}; use crate::common::IntPredicate; use crate::traits::*; use crate::{MemFlags, base}; @@ -593,6 +593,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_place_to_pointer(bx, place, mk_ptr) } + mir::Rvalue::Len(place) => { + let size = self.evaluate_array_len(bx, place); + OperandRef { + val: OperandValue::Immediate(size), + layout: bx.cx().layout_of(bx.tcx().types.usize), + } + } + mir::Rvalue::BinaryOp(op_with_overflow, box (ref lhs, ref rhs)) if let Some(op) = op_with_overflow.overflowing_to_wrapping() => { @@ -792,6 +800,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } + fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value { + // ZST are passed as operands and require special handling + // because codegen_place() panics if Local is operand. + if let Some(index) = place.as_local() { + if let LocalRef::Operand(op) = self.locals[index] { + if let ty::Array(_, n) = op.layout.ty.kind() { + let n = n + .try_to_target_usize(bx.tcx()) + .expect("expected monomorphic const in codegen"); + return bx.cx().const_usize(n); + } + } + } + // use common size calculation for non zero-sized types + let cg_value = self.codegen_place(bx, place.as_ref()); + cg_value.len(bx.cx()) + } + /// Codegen an `Rvalue::RawPtr` or `Rvalue::Ref` fn codegen_place_to_pointer( &mut self, @@ -1063,6 +1089,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::Ref(..) | mir::Rvalue::CopyForDeref(..) | mir::Rvalue::RawPtr(..) | + mir::Rvalue::Len(..) | mir::Rvalue::Cast(..) | // (*) mir::Rvalue::ShallowInitBox(..) | // (*) mir::Rvalue::BinaryOp(..) | diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index e895c44199b81..f4257ad9671f1 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -488,7 +488,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Use(_) | Rvalue::CopyForDeref(..) | Rvalue::Repeat(..) - | Rvalue::Discriminant(..) => {} + | Rvalue::Discriminant(..) + | Rvalue::Len(_) => {} Rvalue::Aggregate(kind, ..) => { if let AggregateKind::Coroutine(def_id, ..) = kind.as_ref() diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index b1b7fb406b105..e244b50a4b5d9 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -230,7 +230,9 @@ where Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) } - Rvalue::Discriminant(place) => in_place::(cx, in_local, place.as_ref()), + Rvalue::Discriminant(place) | Rvalue::Len(place) => { + in_place::(cx, in_local, place.as_ref()) + } Rvalue::CopyForDeref(place) => in_place::(cx, in_local, place.as_ref()), diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs index 5a6e7ab2beef4..79df63a9e849a 100644 --- a/compiler/rustc_const_eval/src/check_consts/resolver.rs +++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs @@ -197,6 +197,7 @@ where | mir::Rvalue::CopyForDeref(..) | mir::Rvalue::ThreadLocalRef(..) | mir::Rvalue::Repeat(..) + | mir::Rvalue::Len(..) | mir::Rvalue::BinaryOp(..) | mir::Rvalue::NullaryOp(..) | mir::Rvalue::UnaryOp(..) diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 32e77fe1024da..a26c2eca107c5 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -15,7 +15,7 @@ use tracing::{info, instrument, trace}; use super::{ FnArg, FnVal, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy, - Projectable, interp_ok, throw_ub, + Projectable, Scalar, interp_ok, throw_ub, }; use crate::util; @@ -218,6 +218,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_repeat(operand, &dest)?; } + Len(place) => { + let src = self.eval_place(place)?; + let len = src.len(self)?; + self.write_scalar(Scalar::from_target_usize(len, self), &dest)?; + } + Ref(_, borrow_kind, place) => { let src = self.eval_place(place)?; let place = self.force_allocation(&src)?; diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 47522f00bb1b3..2d1a0e36f9009 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1068,6 +1068,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { pretty_print_const(b, fmt, false)?; write!(fmt, "]") } + Len(ref a) => write!(fmt, "Len({a:?})"), Cast(ref kind, ref place, ref ty) => { with_no_trimmed_paths!(write!(fmt, "{place:?} as {ty} ({kind:?})")) } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index da3fa9e324a4d..1ce735cec6313 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -424,6 +424,7 @@ impl<'tcx> Rvalue<'tcx> { | Rvalue::Ref(_, _, _) | Rvalue::ThreadLocalRef(_) | Rvalue::RawPtr(_, _) + | Rvalue::Len(_) | Rvalue::Cast( CastKind::IntToInt | CastKind::FloatToInt diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index bbbaffc5a35cc..0c17a2e0fe5a1 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1351,6 +1351,16 @@ pub enum Rvalue<'tcx> { /// model. RawPtr(Mutability, Place<'tcx>), + /// Yields the length of the place, as a `usize`. + /// + /// If the type of the place is an array, this is the array length. For slices (`[T]`, not + /// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is + /// ill-formed for places of other types. + /// + /// This cannot be a `UnOp(PtrMetadata, _)` because that expects a value, and we only + /// have a place, and `UnOp(PtrMetadata, RawPtr(place))` is not a thing. + Len(Place<'tcx>), + /// Performs essentially all of the casts that can be performed via `as`. /// /// This allows for casts from/to a variety of types. diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index cbb26b83c79cf..db77017310af3 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -210,6 +210,7 @@ impl<'tcx> Rvalue<'tcx> { let place_ty = place.ty(local_decls, tcx).ty; Ty::new_ptr(tcx, place_ty, mutability) } + Rvalue::Len(..) => tcx.types.usize, Rvalue::Cast(.., ty) => ty, Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) => { let lhs_ty = lhs.ty(local_decls, tcx); diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 12a024a219e8e..058acbd4024d1 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -695,6 +695,14 @@ macro_rules! make_mir_visitor { self.visit_place(path, ctx, location); } + Rvalue::Len(path) => { + self.visit_place( + path, + PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect), + location + ); + } + Rvalue::Cast(_cast_kind, operand, ty) => { self.visit_operand(operand, location); self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs index 3dd5de0223081..59f440432ebc1 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs @@ -246,6 +246,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { let offset = self.parse_operand(args[1])?; Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset)))) }, + @call(mir_len, args) => Ok(Rvalue::Len(self.parse_place(args[0])?)), @call(mir_ptr_metadata, args) => Ok(Rvalue::UnaryOp(UnOp::PtrMetadata, self.parse_operand(args[0])?)), @call(mir_copy_for_deref, args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)), ExprKind::Borrow { borrow_kind, arg } => Ok( diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs index 89c7bb357ef51..01aec70f437dd 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs @@ -635,7 +635,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// For arrays it'll be `Operand::Constant` with the actual length; /// For slices it'll be `Operand::Move` of a local using `PtrMetadata`. - pub(in crate::builder) fn len_of_slice_or_array( + fn len_of_slice_or_array( &mut self, block: BasicBlock, place: Place<'tcx>, diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 0d36b7bb3ee7b..8cca84d7fcc64 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -243,8 +243,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } TestKind::Len { len, op } => { + let usize_ty = self.tcx.types.usize; + let actual = self.temp(usize_ty, test.span); + // actual = len(place) - let actual = self.len_of_slice_or_array(block, place, test.span, source_info); + self.cfg.push_assign(block, source_info, actual, Rvalue::Len(place)); // expected = let expected = self.push_usize(block, source_info, len); @@ -259,7 +262,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fail_block, source_info, op, - actual, + Operand::Move(actual), Operand::Move(expected), ); } diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index 217594b3238ab..568d8a5acaf95 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -91,6 +91,7 @@ where | Rvalue::Use(..) | Rvalue::ThreadLocalRef(..) | Rvalue::Repeat(..) + | Rvalue::Len(..) | Rvalue::BinaryOp(..) | Rvalue::NullaryOp(..) | Rvalue::UnaryOp(..) diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 80875f32e4f66..d1b3a389e9e5d 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -413,6 +413,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { Rvalue::Ref(..) | Rvalue::RawPtr(..) | Rvalue::Discriminant(..) + | Rvalue::Len(..) | Rvalue::NullaryOp( NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..) | NullOp::UbChecks, _, diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index cc44114782cf3..51af77778af82 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -408,6 +408,18 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { state: &mut State>, ) -> ValueOrPlace> { let val = match rvalue { + Rvalue::Len(place) => { + let place_ty = place.ty(self.local_decls, self.tcx); + if let ty::Array(_, len) = place_ty.ty.kind() { + Const::Ty(self.tcx.types.usize, *len) + .try_eval_scalar(self.tcx, self.typing_env) + .map_or(FlatSet::Top, FlatSet::Elem) + } else if let [ProjectionElem::Deref] = place.projection[..] { + state.get_len(place.local.into(), &self.map) + } else { + FlatSet::Top + } + } Rvalue::Cast(CastKind::IntToInt | CastKind::IntToFloat, operand, ty) => { let Ok(layout) = self.tcx.layout_of(self.typing_env.as_query_input(*ty)) else { return ValueOrPlace::Value(FlatSet::Top); diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index e99bee6a01f5a..8f977d2979ec3 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -574,6 +574,7 @@ impl WriteInfo { | Rvalue::NullaryOp(_, _) | Rvalue::Ref(_, _, _) | Rvalue::RawPtr(_, _) + | Rvalue::Len(_) | Rvalue::Discriminant(_) | Rvalue::CopyForDeref(_) => {} } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 283ed94b61513..d5a813ec8ec64 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -223,6 +223,8 @@ enum Value<'tcx> { Projection(VnIndex, ProjectionElem>), /// Discriminant of the given value. Discriminant(VnIndex), + /// Length of an array or slice. + Len(VnIndex), // Operations. NullaryOp(NullOp<'tcx>, Ty<'tcx>), @@ -511,6 +513,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { self.ecx.discriminant_for_variant(base.layout.ty, variant).discard_err()?; discr_value.into() } + Len(slice) => { + let slice = self.evaluated[slice].as_ref()?; + let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap(); + let len = slice.len(&self.ecx).discard_err()?; + let imm = ImmTy::from_uint(len, usize_layout); + imm.into() + } NullaryOp(null_op, ty) => { let layout = self.ecx.layout_of(ty).ok()?; if let NullOp::SizeOf | NullOp::AlignOf = null_op @@ -854,6 +863,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } // Operations. + Rvalue::Len(ref mut place) => return self.simplify_len(place, location), Rvalue::Cast(ref mut kind, ref mut value, to) => { return self.simplify_cast(kind, value, to, location); } @@ -1423,6 +1433,47 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { Some(self.insert(Value::Cast { kind: *kind, value, from, to })) } + fn simplify_len(&mut self, place: &mut Place<'tcx>, location: Location) -> Option { + // Trivial case: we are fetching a statically known length. + let place_ty = place.ty(self.local_decls, self.tcx).ty; + if let ty::Array(_, len) = place_ty.kind() { + return self.insert_constant(Const::from_ty_const( + *len, + self.tcx.types.usize, + self.tcx, + )); + } + + let mut inner = self.simplify_place_value(place, location)?; + + // The length information is stored in the wide pointer. + // Reborrowing copies length information from one pointer to the other. + while let Value::Address { place: borrowed, .. } = self.get(inner) + && let [PlaceElem::Deref] = borrowed.projection[..] + && let Some(borrowed) = self.locals[borrowed.local] + { + inner = borrowed; + } + + // We have an unsizing cast, which assigns the length to wide pointer metadata. + if let Value::Cast { kind, from, to, .. } = self.get(inner) + && let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) = kind + && let Some(from) = from.builtin_deref(true) + && let ty::Array(_, len) = from.kind() + && let Some(to) = to.builtin_deref(true) + && let ty::Slice(..) = to.kind() + { + return self.insert_constant(Const::from_ty_const( + *len, + self.tcx.types.usize, + self.tcx, + )); + } + + // Fallback: a symbolic `Len`. + Some(self.insert(Value::Len(inner))) + } + fn pointers_have_same_metadata(&self, left_ptr_ty: Ty<'tcx>, right_ptr_ty: Ty<'tcx>) -> bool { let left_meta_ty = left_ptr_ty.pointee_metadata_ty_or_projection(self.tcx); let right_meta_ty = right_ptr_ty.pointee_metadata_ty_or_projection(self.tcx); diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index f1705d0c831c2..acf3eb2b62cea 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -440,6 +440,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { | Rvalue::Use(..) | Rvalue::CopyForDeref(..) | Rvalue::Repeat(..) + | Rvalue::Len(..) | Rvalue::Cast(..) | Rvalue::ShallowInitBox(..) | Rvalue::Discriminant(..) @@ -599,6 +600,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } + Len(place) => { + let len = if let ty::Array(_, n) = place.ty(self.local_decls(), self.tcx).ty.kind() + { + n.try_to_target_usize(self.tcx)? + } else { + match self.get_const(place)? { + Value::Immediate(src) => src.len(&self.ecx).discard_err()?, + Value::Aggregate { fields, .. } => fields.len() as u64, + Value::Uninit => return None, + } + }; + ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into() + } + Ref(..) | RawPtr(..) => return None, NullaryOp(ref null_op, ty) => { diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 7451f4193042b..6be95b1f0f1e6 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -430,7 +430,9 @@ impl<'tcx> Validator<'_, 'tcx> { self.validate_operand(op)? } - Rvalue::Discriminant(place) => self.validate_place(place.as_ref())?, + Rvalue::Discriminant(place) | Rvalue::Len(place) => { + self.validate_place(place.as_ref())? + } Rvalue::ThreadLocalRef(_) => return Err(Unpromotable), diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index a670da94fcc9e..bce015046e1da 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1009,6 +1009,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } Rvalue::Ref(..) => {} + Rvalue::Len(p) => { + let pty = p.ty(&self.body.local_decls, self.tcx).ty; + check_kinds!( + pty, + "Cannot compute length of non-array type {:?}", + ty::Array(..) | ty::Slice(..) + ); + } Rvalue::BinaryOp(op, vals) => { use BinOp::*; let a = vals.0.ty(&self.body.local_decls, self.tcx); diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index de933952c6a7b..a5a17b4b5730e 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -181,6 +181,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { RawPtr(mutability, place) => { stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables)) } + Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)), Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast( cast_kind.stable(tables), op.stable(tables), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4ecc4201f89d5..e3f55221d7052 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1283,6 +1283,7 @@ symbols! { mir_drop, mir_field, mir_goto, + mir_len, mir_make_place, mir_move, mir_offset, diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index 834f44c7790d9..55dcf7cd47e97 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -233,7 +233,7 @@ //! //! - Operands implicitly convert to `Use` rvalues. //! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue. -//! - [`Discriminant`] and [`CopyForDeref`] have associated functions. +//! - [`Discriminant`], [`Len`], and [`CopyForDeref`] have associated functions. //! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc. //! - The binary operation `Offset` can be created via [`Offset`]. //! - Checked binary operations are represented by wrapping the associated binop in [`Checked`]. @@ -401,6 +401,7 @@ define!("mir_storage_dead", fn StorageDead(local: T)); define!("mir_assume", fn Assume(operand: bool)); define!("mir_deinit", fn Deinit(place: T)); define!("mir_checked", fn Checked(binop: T) -> (T, bool)); +define!("mir_len", fn Len(place: T) -> usize); define!( "mir_ptr_metadata", fn PtrMetadata(place: *const P) ->

::Metadata diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 428b40c5771c8..104ae154e3695 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -109,7 +109,7 @@ fn check_rvalue<'tcx>( ) -> McfResult { match rvalue { Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())), - Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => { + Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => { check_place(tcx, *place, span, body, msrv) }, Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv), diff --git a/tests/mir-opt/building/custom/arrays.arrays.built.after.mir b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir new file mode 100644 index 0000000000000..30d11e31e4d4e --- /dev/null +++ b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir @@ -0,0 +1,14 @@ +// MIR for `arrays` after built + +fn arrays() -> usize { + let mut _0: usize; + let mut _1: [i32; C]; + let mut _2: usize; + + bb0: { + _1 = [const 5_i32; C]; + _2 = Len(_1); + _0 = copy _2; + return; + } +} diff --git a/tests/mir-opt/building/custom/arrays.rs b/tests/mir-opt/building/custom/arrays.rs new file mode 100644 index 0000000000000..4bd6f93e11340 --- /dev/null +++ b/tests/mir-opt/building/custom/arrays.rs @@ -0,0 +1,22 @@ +// skip-filecheck +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; + +// EMIT_MIR arrays.arrays.built.after.mir +#[custom_mir(dialect = "built")] +fn arrays() -> usize { + mir! { + { + let x = [5_i32; C]; + let c = Len(x); + RET = c; + Return() + } + } +} + +fn main() { + assert_eq!(arrays::<20>(), 20); +} 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 index b4197c09ac94b..60742ef0e9a90 100644 --- 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 @@ -22,14 +22,14 @@ bb1: { StorageDead(_3); - _4 = PtrMetadata(copy _2); + _4 = Len((*_2)); _5 = const 4_usize; _6 = Ge(move _4, move _5); switchInt(move _6) -> [0: bb2, otherwise: bb3]; } bb2: { - _7 = PtrMetadata(copy _2); + _7 = Len((*_2)); _8 = const 3_usize; _9 = Ge(move _7, move _8); - switchInt(move _9) -> [0: bb7, otherwise: bb8]; diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff index 4bcb13ca49c12..7337a32f525f9 100644 --- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff +++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff @@ -22,14 +22,14 @@ bb1: { StorageDead(_3); - _4 = PtrMetadata(copy _2); + _4 = Len((*_2)); _5 = const 4_usize; _6 = Ge(move _4, move _5); switchInt(move _6) -> [0: bb2, otherwise: bb3]; } bb2: { - _7 = PtrMetadata(copy _2); + _7 = Len((*_2)); _8 = const 3_usize; _9 = Ge(move _7, move _8); - switchInt(move _9) -> [0: bb7, otherwise: bb8]; diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff index 94ba7082c6612..c02bab3524bca 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff @@ -7,16 +7,18 @@ let _2: &[T]; let _3: &[T; 3]; let _4: [T; 3]; - let mut _8: !; + let mut _5: usize; + let mut _6: bool; + let mut _10: !; scope 1 { debug v => _2; - let _5: &T; - let _6: &T; let _7: &T; + let _8: &T; + let _9: &T; scope 2 { - debug v1 => _5; - debug v2 => _6; - debug v3 => _7; + debug v1 => _7; + debug v2 => _8; + debug v3 => _9; } } @@ -25,23 +27,25 @@ _4 = [copy _1, copy _1, copy _1]; _3 = &_4; _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit)); + nop; + nop; goto -> bb2; } bb1: { - _8 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable; + _10 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable; } bb2: { - StorageLive(_5); - _5 = &(*_2)[0 of 3]; - StorageLive(_6); - _6 = &(*_2)[1 of 3]; StorageLive(_7); - _7 = &(*_2)[2 of 3]; + _7 = &(*_2)[0 of 3]; + StorageLive(_8); + _8 = &(*_2)[1 of 3]; + StorageLive(_9); + _9 = &(*_2)[2 of 3]; + StorageDead(_9); + StorageDead(_8); StorageDead(_7); - StorageDead(_6); - StorageDead(_5); StorageDead(_4); return; } diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff index 0455b2c326eb8..49be042588cb3 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff @@ -7,16 +7,18 @@ let _2: &[T]; let _3: &[T; 3]; let _4: [T; 3]; - let mut _8: !; + let mut _5: usize; + let mut _6: bool; + let mut _10: !; scope 1 { debug v => _2; - let _5: &T; - let _6: &T; let _7: &T; + let _8: &T; + let _9: &T; scope 2 { - debug v1 => _5; - debug v2 => _6; - debug v3 => _7; + debug v1 => _7; + debug v2 => _8; + debug v3 => _9; } } @@ -25,23 +27,25 @@ _4 = [copy _1, copy _1, copy _1]; _3 = &_4; _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit)); + nop; + nop; goto -> bb2; } bb1: { - _8 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue; + _10 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue; } bb2: { - StorageLive(_5); - _5 = &(*_2)[0 of 3]; - StorageLive(_6); - _6 = &(*_2)[1 of 3]; StorageLive(_7); - _7 = &(*_2)[2 of 3]; + _7 = &(*_2)[0 of 3]; + StorageLive(_8); + _8 = &(*_2)[1 of 3]; + StorageLive(_9); + _9 = &(*_2)[2 of 3]; + StorageDead(_9); + StorageDead(_8); StorageDead(_7); - StorageDead(_6); - StorageDead(_5); StorageDead(_4); return; } diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff index e9eea69377f37..05ad9dbf3cccf 100644 --- a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff @@ -92,7 +92,7 @@ StorageDead(_7); - StorageDead(_6); - StorageLive(_10); - StorageLive(_11); +- StorageLive(_11); - StorageLive(_12); StorageLive(_13); _26 = const debuginfo::promoted[0]; @@ -105,8 +105,9 @@ bb5: { StorageDead(_15); StorageDead(_13); - _11 = &(*_12); - _16 = PtrMetadata(copy _11); +- _11 = &(*_12); +- _16 = Len((*_11)); ++ _16 = Len((*_12)); _17 = const 3_usize; _18 = Ge(move _16, move _17); switchInt(move _18) -> [0: bb7, otherwise: bb6]; @@ -136,7 +137,7 @@ bb8: { - StorageDead(_12); - StorageDead(_11); +- StorageDead(_11); - StorageDead(_10); StorageLive(_22); StorageLive(_23); From cb60eb14732e3be12c74a06e0f44ce5412839792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 18 Jan 2025 22:08:53 +0000 Subject: [PATCH 09/14] Revert "Rollup merge of #134371 - scottmcm:fix-134352, r=oli-obk" This reverts commit 7c301ecdf5e806b7aa3c44e4a185049fabbc4381, reversing changes made to dffaad83327454430129802f240121f8c7866208. (cherry picked from commit 0bb4880581a6963e0b895f9550e9147c68b9537a) --- .../src/builder/expr/as_place.rs | 32 ++++--------------- .../issues/index_array_bad_type.rs | 15 --------- .../issues/index_array_bad_type.stderr | 8 ----- 3 files changed, 7 insertions(+), 48 deletions(-) delete mode 100644 tests/ui/const-generics/issues/index_array_bad_type.rs delete mode 100644 tests/ui/const-generics/issues/index_array_bad_type.stderr diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs index 01aec70f437dd..2c88a48424fe2 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs @@ -647,31 +647,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match place_ty.kind() { ty::Array(_elem_ty, len_const) => { - let ty_const = if let Some((_, len_ty)) = len_const.try_to_valtree() - && len_ty != self.tcx.types.usize - { - // Bad const generics can give us a constant from the type that's - // not actually a `usize`, so in that case give an error instead. - // FIXME: It'd be nice if the type checker made sure this wasn't - // possible, instead. - let err = self.tcx.dcx().span_delayed_bug( - span, - format!( - "Array length should have already been a type error, as it's {len_ty:?}" - ), - ); - ty::Const::new_error(self.tcx, err) - } else { - // We know how long an array is, so just use that as a constant - // directly -- no locals needed. We do need one statement so - // that borrow- and initialization-checking consider it used, - // though. FIXME: Do we really *need* to count this as a use? - // Could partial array tracking work off something else instead? - self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place); - *len_const - }; - - let const_ = Const::from_ty_const(ty_const, usize_ty, self.tcx); + // We know how long an array is, so just use that as a constant + // directly -- no locals needed. We do need one statement so + // that borrow- and initialization-checking consider it used, + // though. FIXME: Do we really *need* to count this as a use? + // Could partial array tracking work off something else instead? + self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place); + let const_ = Const::from_ty_const(*len_const, usize_ty, self.tcx); Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ })) } ty::Slice(_elem_ty) => { diff --git a/tests/ui/const-generics/issues/index_array_bad_type.rs b/tests/ui/const-generics/issues/index_array_bad_type.rs deleted file mode 100644 index 41e4dba026c2e..0000000000000 --- a/tests/ui/const-generics/issues/index_array_bad_type.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ check-fail -//@ compile-flags: -C opt-level=0 - -#![crate_type = "lib"] - -// This used to fail in the known-panics lint, as the MIR was ill-typed due to -// the length constant not actually having type usize. -// https://github.com/rust-lang/rust/issues/134352 - -pub struct BadStruct(pub [u8; N]); -//~^ ERROR: the constant `N` is not of type `usize` - -pub fn bad_array_length_type(value: BadStruct<3>) -> u8 { - value.0[0] -} diff --git a/tests/ui/const-generics/issues/index_array_bad_type.stderr b/tests/ui/const-generics/issues/index_array_bad_type.stderr deleted file mode 100644 index e4417192150ee..0000000000000 --- a/tests/ui/const-generics/issues/index_array_bad_type.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: the constant `N` is not of type `usize` - --> $DIR/index_array_bad_type.rs:10:40 - | -LL | pub struct BadStruct(pub [u8; N]); - | ^^^^^^^ expected `usize`, found `i64` - -error: aborting due to 1 previous error - From 016422a9933b30aa9fa6cb7f96f60373819aa423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 18 Jan 2025 22:09:19 +0000 Subject: [PATCH 10/14] Revert "Auto merge of #133734 - scottmcm:lower-indexing-to-ptrmetadata, r=davidtwco,RalfJung" This reverts commit b57d93d8b9525fa261404b4cd9c0670eeb1264b8, reversing changes made to 0aeaa5eb22180fdf12a8489e63c4daa18da6f236. (cherry picked from commit 122a55bb442bd1995df9cf9b36e6f65ed3ef4a1d) --- .../src/check_consts/check.rs | 25 +- .../rustc_const_eval/src/interpret/step.rs | 13 +- compiler/rustc_middle/src/mir/consts.rs | 3 - .../src/builder/expr/as_place.rs | 92 +----- .../rustc_mir_transform/src/instsimplify.rs | 13 + compiler/rustc_mir_transform/src/validate.rs | 8 + compiler/rustc_span/src/hygiene.rs | 4 - ...fg-pre-optimizations.after.panic-abort.mir | 8 +- ...g-pre-optimizations.after.panic-unwind.mir | 8 +- ...rray_and_slice.index_array.built.after.mir | 31 -- ....index_const_generic_array.built.after.mir | 31 -- ...ray_and_slice.index_custom.built.after.mir | 34 -- ..._and_slice.index_mut_slice.built.after.mir | 34 -- ...rray_and_slice.index_slice.built.after.mir | 32 -- .../mir-opt/building/index_array_and_slice.rs | 71 ---- ...rray_index.main.GVN.32bit.panic-abort.diff | 11 +- ...ray_index.main.GVN.32bit.panic-unwind.diff | 11 +- ...rray_index.main.GVN.64bit.panic-abort.diff | 11 +- ...ray_index.main.GVN.64bit.panic-unwind.diff | 11 +- ...for_slices.main.GVN.32bit.panic-abort.diff | 13 +- ...or_slices.main.GVN.32bit.panic-unwind.diff | 13 +- ...for_slices.main.GVN.64bit.panic-abort.diff | 13 +- ...or_slices.main.GVN.64bit.panic-unwind.diff | 13 +- ...rray_index.main.GVN.32bit.panic-abort.diff | 11 +- ...ray_index.main.GVN.32bit.panic-unwind.diff | 11 +- ...rray_index.main.GVN.64bit.panic-abort.diff | 11 +- ...ray_index.main.GVN.64bit.panic-unwind.diff | 11 +- .../repeat.main.GVN.32bit.panic-abort.diff | 11 +- .../repeat.main.GVN.32bit.panic-unwind.diff | 11 +- .../repeat.main.GVN.64bit.panic-abort.diff | 11 +- .../repeat.main.GVN.64bit.panic-unwind.diff | 11 +- .../slice_len.main.GVN.32bit.panic-abort.diff | 7 +- ...slice_len.main.GVN.32bit.panic-unwind.diff | 7 +- .../slice_len.main.GVN.64bit.panic-abort.diff | 7 +- ...slice_len.main.GVN.64bit.panic-unwind.diff | 7 +- ...ssue_107511.main.CopyProp.panic-abort.diff | 12 +- ...sue_107511.main.CopyProp.panic-unwind.diff | 12 +- ...n.DataflowConstProp.32bit.panic-abort.diff | 11 +- ....DataflowConstProp.32bit.panic-unwind.diff | 11 +- ...n.DataflowConstProp.64bit.panic-abort.diff | 11 +- ....DataflowConstProp.64bit.panic-unwind.diff | 11 +- .../dataflow-const-prop/array_index.rs | 3 +- ...n.DataflowConstProp.32bit.panic-abort.diff | 11 +- ....DataflowConstProp.32bit.panic-unwind.diff | 11 +- ...n.DataflowConstProp.64bit.panic-abort.diff | 11 +- ....DataflowConstProp.64bit.panic-unwind.diff | 11 +- .../dataflow-const-prop/large_array_index.rs | 2 +- ...n.DataflowConstProp.32bit.panic-abort.diff | 11 +- ....DataflowConstProp.32bit.panic-unwind.diff | 11 +- ...n.DataflowConstProp.64bit.panic-abort.diff | 11 +- ....DataflowConstProp.64bit.panic-unwind.diff | 11 +- tests/mir-opt/dataflow-const-prop/repeat.rs | 3 +- ...n.DataflowConstProp.32bit.panic-abort.diff | 77 +++++ ....DataflowConstProp.32bit.panic-unwind.diff | 77 +++++ ...n.DataflowConstProp.64bit.panic-abort.diff | 77 +++++ ....DataflowConstProp.64bit.panic-unwind.diff | 77 +++++ .../mir-opt/dataflow-const-prop/slice_len.rs | 34 ++ ...nstant_index_overflow.GVN.panic-abort.diff | 4 +- ...stant_index_overflow.GVN.panic-unwind.diff | 4 +- ...bounds_checks_lengths.GVN.panic-abort.diff | 72 ----- ...ounds_checks_lengths.GVN.panic-unwind.diff | 72 ----- .../gvn.repeated_index.GVN.panic-abort.diff | 48 +-- .../gvn.repeated_index.GVN.panic-unwind.diff | 48 +-- tests/mir-opt/gvn.rs | 20 -- ...e_ptr_same_provenance.GVN.panic-abort.diff | 302 +++++++++--------- ..._ptr_same_provenance.GVN.panic-unwind.diff | 302 +++++++++--------- ...implify-after-simplifycfg.panic-abort.diff | 77 +++++ ...mplify-after-simplifycfg.panic-unwind.diff | 77 +++++ .../mir-opt/instsimplify/combine_array_len.rs | 15 + tests/mir-opt/issue_72181.foo.built.after.mir | 9 +- .../mir-opt/issue_72181.main.built.after.mir | 9 +- tests/mir-opt/issue_91633.foo.built.after.mir | 12 +- tests/mir-opt/issue_91633.fun.built.after.mir | 2 +- ...array_len.array_bound.GVN.panic-abort.diff | 20 +- ...rray_len.array_bound.GVN.panic-unwind.diff | 20 +- ...y_len.array_bound_mut.GVN.panic-abort.diff | 43 ++- ..._len.array_bound_mut.GVN.panic-unwind.diff | 43 ++- ....bound.LowerSliceLenCalls.panic-abort.diff | 2 +- ...bound.LowerSliceLenCalls.panic-unwind.diff | 2 +- ...egion_subtyping_basic.main.nll.0.32bit.mir | 47 +-- ...egion_subtyping_basic.main.nll.0.64bit.mir | 47 +-- ...o_variable.main.GVN.32bit.panic-abort.diff | 26 +- ..._variable.main.GVN.32bit.panic-unwind.diff | 26 +- ...o_variable.main.GVN.64bit.panic-abort.diff | 26 +- ..._variable.main.GVN.64bit.panic-unwind.diff | 26 +- ...acementOfAggregates.32bit.panic-abort.diff | 38 +-- ...cementOfAggregates.32bit.panic-unwind.diff | 38 +-- ...acementOfAggregates.64bit.panic-abort.diff | 38 +-- ...cementOfAggregates.64bit.panic-unwind.diff | 38 +-- tests/mir-opt/pre-codegen/slice_index.rs | 2 +- ...dex_usize.PreCodegen.after.panic-abort.mir | 2 +- ...ex_usize.PreCodegen.after.panic-unwind.mir | 2 +- ...ange_loop.PreCodegen.after.panic-abort.mir | 30 +- ...nge_loop.PreCodegen.after.panic-unwind.mir | 30 +- tests/ui/borrowck/borrowck-describe-lvalue.rs | 1 + .../borrowck/borrowck-describe-lvalue.stderr | 25 +- .../diagnostics/arrays.rs | 6 +- .../diagnostics/arrays.stderr | 40 ++- tests/ui/consts/issue-65348.rs | 4 +- tests/ui/stable-mir-print/operands.stdout | 294 ++++++++--------- 100 files changed, 1663 insertions(+), 1451 deletions(-) delete mode 100644 tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir delete mode 100644 tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir delete mode 100644 tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir delete mode 100644 tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir delete mode 100644 tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir delete mode 100644 tests/mir-opt/building/index_array_and_slice.rs create mode 100644 tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff create mode 100644 tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff create mode 100644 tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff create mode 100644 tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff create mode 100644 tests/mir-opt/dataflow-const-prop/slice_len.rs delete mode 100644 tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff delete mode 100644 tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff create mode 100644 tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff create mode 100644 tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff create mode 100644 tests/mir-opt/instsimplify/combine_array_len.rs diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index f4257ad9671f1..cbc0d5b059629 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -573,27 +573,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { ) => {} Rvalue::ShallowInitBox(_, _) => {} - Rvalue::UnaryOp(op, operand) => { + Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(self.body, self.tcx); - match op { - UnOp::Not | UnOp::Neg => { - if is_int_bool_float_or_char(ty) { - // Int, bool, float, and char operations are fine. - } else { - span_bug!( - self.span, - "non-primitive type in `Rvalue::UnaryOp{op:?}`: {ty:?}", - ); - } - } - UnOp::PtrMetadata => { - if !ty.is_ref() && !ty.is_unsafe_ptr() { - span_bug!( - self.span, - "non-pointer type in `Rvalue::UnaryOp({op:?})`: {ty:?}", - ); - } - } + if is_int_bool_float_or_char(ty) { + // Int, bool, float, and char operations are fine. + } else { + span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty); } } diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index a26c2eca107c5..b61865be66788 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -9,7 +9,6 @@ use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::{bug, mir, span_bug}; use rustc_span::source_map::Spanned; -use rustc_span::{DesugaringKind, Span}; use rustc_target::callconv::FnAbi; use tracing::{info, instrument, trace}; @@ -81,9 +80,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { use rustc_middle::mir::StatementKind::*; match &stmt.kind { - Assign(box (place, rvalue)) => { - self.eval_rvalue_into_place(rvalue, *place, stmt.source_info.span)? - } + Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?, SetDiscriminant { place, variant_index } => { let dest = self.eval_place(**place)?; @@ -162,7 +159,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { &mut self, rvalue: &mir::Rvalue<'tcx>, place: mir::Place<'tcx>, - span: Span, ) -> InterpResult<'tcx> { let dest = self.eval_place(place)?; // FIXME: ensure some kind of non-aliasing between LHS and RHS? @@ -254,13 +250,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let src = self.eval_place(place)?; let place = self.force_allocation(&src)?; let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout); - if !place_base_raw - && span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow) - { + if !place_base_raw { // If this was not already raw, it needs retagging. - // As a special hack, we exclude the desugared `PtrMetadata(&raw const *_n)` - // from indexing. (Really we should not do any retag on `&raw` but that does not - // currently work with Stacked Borrows.) val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?; } self.write_immediate(*val, &dest)?; diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 1231ea8856961..60e1ff1d0493f 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -467,9 +467,6 @@ impl<'tcx> Const<'tcx> { let const_val = tcx.valtree_to_const_val((ty, valtree)); Self::Val(const_val, ty) } - ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => { - Self::Unevaluated(UnevaluatedConst { def, args, promoted: None }, ty) - } _ => Self::Ty(ty, c), } } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs index 2c88a48424fe2..b1851e79d5c65 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs @@ -11,7 +11,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance}; use rustc_middle::{bug, span_bug}; -use rustc_span::{DesugaringKind, Span}; +use rustc_span::Span; use tracing::{debug, instrument, trace}; use crate::builder::ForGuard::{OutsideGuard, RefWithinGuard}; @@ -630,80 +630,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.and(base_place.index(idx)) } - /// Given a place that's either an array or a slice, returns an operand - /// with the length of the array/slice. - /// - /// For arrays it'll be `Operand::Constant` with the actual length; - /// For slices it'll be `Operand::Move` of a local using `PtrMetadata`. - fn len_of_slice_or_array( - &mut self, - block: BasicBlock, - place: Place<'tcx>, - span: Span, - source_info: SourceInfo, - ) -> Operand<'tcx> { - let place_ty = place.ty(&self.local_decls, self.tcx).ty; - let usize_ty = self.tcx.types.usize; - - match place_ty.kind() { - ty::Array(_elem_ty, len_const) => { - // We know how long an array is, so just use that as a constant - // directly -- no locals needed. We do need one statement so - // that borrow- and initialization-checking consider it used, - // though. FIXME: Do we really *need* to count this as a use? - // Could partial array tracking work off something else instead? - self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place); - let const_ = Const::from_ty_const(*len_const, usize_ty, self.tcx); - Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ })) - } - ty::Slice(_elem_ty) => { - let ptr_or_ref = if let [PlaceElem::Deref] = place.projection[..] - && let local_ty = self.local_decls[place.local].ty - && local_ty.is_trivially_pure_clone_copy() - { - // It's extremely common that we have something that can be - // directly passed to `PtrMetadata`, so avoid an unnecessary - // temporary and statement in those cases. Note that we can - // only do that for `Copy` types -- not `&mut [_]` -- because - // the MIR we're building here needs to pass NLL later. - Operand::Copy(Place::from(place.local)) - } else { - let len_span = self.tcx.with_stable_hashing_context(|hcx| { - let span = source_info.span; - span.mark_with_reason( - None, - DesugaringKind::IndexBoundsCheckReborrow, - span.edition(), - hcx, - ) - }); - let ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty); - let slice_ptr = self.temp(ptr_ty, span); - self.cfg.push_assign( - block, - SourceInfo { span: len_span, ..source_info }, - slice_ptr, - Rvalue::RawPtr(Mutability::Not, place), - ); - Operand::Move(slice_ptr) - }; - - let len = self.temp(usize_ty, span); - self.cfg.push_assign( - block, - source_info, - len, - Rvalue::UnaryOp(UnOp::PtrMetadata, ptr_or_ref), - ); - - Operand::Move(len) - } - _ => { - span_bug!(span, "len called on place of type {place_ty:?}") - } - } - } - fn bounds_check( &mut self, block: BasicBlock, @@ -712,25 +638,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr_span: Span, source_info: SourceInfo, ) -> BasicBlock { - let slice = slice.to_place(self); + let usize_ty = self.tcx.types.usize; + let bool_ty = self.tcx.types.bool; + // bounds check: + let len = self.temp(usize_ty, expr_span); + let lt = self.temp(bool_ty, expr_span); // len = len(slice) - let len = self.len_of_slice_or_array(block, slice, expr_span, source_info); - + self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.to_place(self))); // lt = idx < len - let bool_ty = self.tcx.types.bool; - let lt = self.temp(bool_ty, expr_span); self.cfg.push_assign( block, source_info, lt, Rvalue::BinaryOp( BinOp::Lt, - Box::new((Operand::Copy(Place::from(index)), len.to_copy())), + Box::new((Operand::Copy(Place::from(index)), Operand::Copy(len))), ), ); - let msg = BoundsCheck { len, index: Operand::Copy(Place::from(index)) }; - + let msg = BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(index)) }; // assert!(lt, "...") self.assert(block, Operand::Move(lt), true, msg, expr_span) } diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 1a65affe8121a..f5938e7b60e80 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -46,6 +46,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify { } ctx.simplify_bool_cmp(rvalue); ctx.simplify_ref_deref(rvalue); + ctx.simplify_len(rvalue); ctx.simplify_ptr_aggregate(rvalue); ctx.simplify_cast(rvalue); } @@ -130,6 +131,18 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { } } + /// Transform `Len([_; N])` ==> `N`. + fn simplify_len(&self, rvalue: &mut Rvalue<'tcx>) { + if let Rvalue::Len(ref place) = *rvalue { + let place_ty = place.ty(self.local_decls, self.tcx).ty; + if let ty::Array(_, len) = *place_ty.kind() { + let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx); + let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None }; + *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant))); + } + } + } + /// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`. fn simplify_ptr_aggregate(&self, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index bce015046e1da..404fbb6b83937 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1115,6 +1115,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } UnOp::PtrMetadata => { + if !matches!(self.body.phase, MirPhase::Runtime(_)) { + // It would probably be fine to support this in earlier phases, but at + // the time of writing it's only ever introduced from intrinsic + // lowering or other runtime-phase optimization passes, so earlier + // things can just `bug!` on it. + self.fail(location, "PtrMetadata should be in runtime MIR only"); + } + check_kinds!( a, "Cannot PtrMetadata non-pointer non-reference type {:?}", diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 3cdae437b7d46..a5826137181db 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1163,9 +1163,6 @@ pub enum DesugaringKind { WhileLoop, /// `async Fn()` bound modifier BoundModifier, - /// Marks a `&raw const *_1` needed as part of getting the length of a mutable - /// slice for the bounds check, so that MIRI's retag handling can recognize it. - IndexBoundsCheckReborrow, } impl DesugaringKind { @@ -1182,7 +1179,6 @@ impl DesugaringKind { DesugaringKind::ForLoop => "`for` loop", DesugaringKind::WhileLoop => "`while` loop", DesugaringKind::BoundModifier => "trait bound modifier", - DesugaringKind::IndexBoundsCheckReborrow => "slice indexing", } } } diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir index 8d9176ef301ff..a467987e88612 100644 --- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir +++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir @@ -7,7 +7,8 @@ fn main() -> () { let mut _5: u32; let mut _6: *mut usize; let _7: usize; - let mut _8: bool; + let mut _8: usize; + let mut _9: bool; scope 1 { debug x => _1; let mut _2: usize; @@ -40,8 +41,9 @@ fn main() -> () { StorageDead(_6); StorageLive(_7); _7 = copy _2; - _8 = Lt(copy _7, const 3_usize); - assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind unreachable]; + _8 = Len(_1); + _9 = Lt(copy _7, copy _8); + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable]; } bb2: { diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir index e1df0e3e2a3b2..bd7365543bdce 100644 --- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir +++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir @@ -7,7 +7,8 @@ fn main() -> () { let mut _5: u32; let mut _6: *mut usize; let _7: usize; - let mut _8: bool; + let mut _8: usize; + let mut _9: bool; scope 1 { debug x => _1; let mut _2: usize; @@ -40,8 +41,9 @@ fn main() -> () { StorageDead(_6); StorageLive(_7); _7 = copy _2; - _8 = Lt(copy _7, const 3_usize); - assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind continue]; + _8 = Len(_1); + _9 = Lt(copy _7, copy _8); + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue]; } bb2: { diff --git a/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir deleted file mode 100644 index d28a2031013f3..0000000000000 --- a/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir +++ /dev/null @@ -1,31 +0,0 @@ -// MIR for `index_array` after built - -fn index_array(_1: &[i32; 7], _2: usize) -> &i32 { - debug array => _1; - debug index => _2; - let mut _0: &i32; - let _3: &i32; - let _4: usize; - let mut _5: bool; - - bb0: { - StorageLive(_3); - StorageLive(_4); - _4 = copy _2; - FakeRead(ForIndex, (*_1)); - _5 = Lt(copy _4, const 7_usize); - assert(move _5, "index out of bounds: the length is {} but the index is {}", const 7_usize, copy _4) -> [success: bb1, unwind: bb2]; - } - - bb1: { - _3 = &(*_1)[_4]; - _0 = &(*_3); - StorageDead(_4); - StorageDead(_3); - return; - } - - bb2 (cleanup): { - resume; - } -} diff --git a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir deleted file mode 100644 index e9627532c3828..0000000000000 --- a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir +++ /dev/null @@ -1,31 +0,0 @@ -// MIR for `index_const_generic_array` after built - -fn index_const_generic_array(_1: &[i32; N], _2: usize) -> &i32 { - debug array => _1; - debug index => _2; - let mut _0: &i32; - let _3: &i32; - let _4: usize; - let mut _5: bool; - - bb0: { - StorageLive(_3); - StorageLive(_4); - _4 = copy _2; - FakeRead(ForIndex, (*_1)); - _5 = Lt(copy _4, const N); - assert(move _5, "index out of bounds: the length is {} but the index is {}", const N, copy _4) -> [success: bb1, unwind: bb2]; - } - - bb1: { - _3 = &(*_1)[_4]; - _0 = &(*_3); - StorageDead(_4); - StorageDead(_3); - return; - } - - bb2 (cleanup): { - resume; - } -} diff --git a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir deleted file mode 100644 index 00f2b7e07d551..0000000000000 --- a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir +++ /dev/null @@ -1,34 +0,0 @@ -// MIR for `index_custom` after built - -fn index_custom(_1: &WithSliceTail, _2: usize) -> &i32 { - debug custom => _1; - debug index => _2; - let mut _0: &i32; - let _3: &i32; - let _4: usize; - let mut _5: *const [i32]; - let mut _6: usize; - let mut _7: bool; - - bb0: { - StorageLive(_3); - StorageLive(_4); - _4 = copy _2; - _5 = &raw const ((*_1).1: [i32]); - _6 = PtrMetadata(move _5); - _7 = Lt(copy _4, copy _6); - assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2]; - } - - bb1: { - _3 = &((*_1).1: [i32])[_4]; - _0 = &(*_3); - StorageDead(_4); - StorageDead(_3); - return; - } - - bb2 (cleanup): { - resume; - } -} diff --git a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir deleted file mode 100644 index cb0b2f600c81a..0000000000000 --- a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir +++ /dev/null @@ -1,34 +0,0 @@ -// MIR for `index_mut_slice` after built - -fn index_mut_slice(_1: &mut [i32], _2: usize) -> &i32 { - debug slice => _1; - debug index => _2; - let mut _0: &i32; - let _3: &i32; - let _4: usize; - let mut _5: *const [i32]; - let mut _6: usize; - let mut _7: bool; - - bb0: { - StorageLive(_3); - StorageLive(_4); - _4 = copy _2; - _5 = &raw const (*_1); - _6 = PtrMetadata(move _5); - _7 = Lt(copy _4, copy _6); - assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2]; - } - - bb1: { - _3 = &(*_1)[_4]; - _0 = &(*_3); - StorageDead(_4); - StorageDead(_3); - return; - } - - bb2 (cleanup): { - resume; - } -} diff --git a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir deleted file mode 100644 index 0911df590497c..0000000000000 --- a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir +++ /dev/null @@ -1,32 +0,0 @@ -// MIR for `index_slice` after built - -fn index_slice(_1: &[i32], _2: usize) -> &i32 { - debug slice => _1; - debug index => _2; - let mut _0: &i32; - let _3: &i32; - let _4: usize; - let mut _5: usize; - let mut _6: bool; - - bb0: { - StorageLive(_3); - StorageLive(_4); - _4 = copy _2; - _5 = PtrMetadata(copy _1); - _6 = Lt(copy _4, copy _5); - assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb2]; - } - - bb1: { - _3 = &(*_1)[_4]; - _0 = &(*_3); - StorageDead(_4); - StorageDead(_3); - return; - } - - bb2 (cleanup): { - resume; - } -} diff --git a/tests/mir-opt/building/index_array_and_slice.rs b/tests/mir-opt/building/index_array_and_slice.rs deleted file mode 100644 index 16d0b983132df..0000000000000 --- a/tests/mir-opt/building/index_array_and_slice.rs +++ /dev/null @@ -1,71 +0,0 @@ -//@ compile-flags: -C opt-level=0 - -// EMIT_MIR index_array_and_slice.index_array.built.after.mir -fn index_array(array: &[i32; 7], index: usize) -> &i32 { - // CHECK: bb0: - // CHECK: [[LT:_.+]] = Lt(copy _2, const 7_usize); - // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const 7_usize, copy _2) -> [success: bb1, unwind - - // CHECK: bb1: - // CHECK: _0 = &(*_1)[_2]; - &array[index] -} - -// EMIT_MIR index_array_and_slice.index_const_generic_array.built.after.mir -fn index_const_generic_array(array: &[i32; N], index: usize) -> &i32 { - // CHECK: bb0: - // CHECK: [[LT:_.+]] = Lt(copy _2, const N); - // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const N, copy _2) -> [success: bb1, unwind - - // CHECK: bb1: - // CHECK: _0 = &(*_1)[_2]; - &array[index] -} - -// EMIT_MIR index_array_and_slice.index_slice.built.after.mir -fn index_slice(slice: &[i32], index: usize) -> &i32 { - // CHECK: bb0: - // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1); - // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]); - // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1, - - // CHECK: bb1: - // CHECK: _0 = &(*_1)[_2]; - &slice[index] -} - -// EMIT_MIR index_array_and_slice.index_mut_slice.built.after.mir -fn index_mut_slice(slice: &mut [i32], index: usize) -> &i32 { - // While the filecheck here is identical to the above test, the emitted MIR is different. - // This cannot `copy _1` in the *built* MIR, only in the *runtime* MIR. - - // CHECK: bb0: - // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1); - // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]); - // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1, - - // CHECK: bb1: - // CHECK: _0 = &(*_1)[_2]; - &slice[index] -} - -struct WithSliceTail(f64, [i32]); - -// EMIT_MIR index_array_and_slice.index_custom.built.after.mir -fn index_custom(custom: &WithSliceTail, index: usize) -> &i32 { - // CHECK: bb0: - // CHECK: [[PTR:_.+]] = &raw const ((*_1).1: [i32]); - // CHECK: [[LEN:_.+]] = PtrMetadata(move [[PTR]]); - // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]); - // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1, - - // CHECK: bb1: - // CHECK: _0 = &((*_1).1: [i32])[_2]; - &custom.1[index] -} - -fn main() { - index_array(&[1, 2, 3, 4, 5, 6, 7], 3); - index_slice(&[1, 2, 3, 4, 5, 6, 7][..], 3); - _ = index_custom; -} diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff index 3a5a8d0099128..e754af95ce399 100644 --- a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff @@ -6,7 +6,8 @@ let _1: u32; let mut _2: [u32; 4]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 4_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable]; ++ _4 = const 4_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff index 62d6e6007e5c9..e15a35c7fe945 100644 --- a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff @@ -6,7 +6,8 @@ let _1: u32; let mut _2: [u32; 4]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 4_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue]; ++ _4 = const 4_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff index 3a5a8d0099128..e754af95ce399 100644 --- a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff @@ -6,7 +6,8 @@ let _1: u32; let mut _2: [u32; 4]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 4_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable]; ++ _4 = const 4_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff index 62d6e6007e5c9..e15a35c7fe945 100644 --- a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff @@ -6,7 +6,8 @@ let _1: u32; let mut _2: [u32; 4]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 4_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue]; ++ _4 = const 4_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff index be42c4d60c807..15d3014036713 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff @@ -30,22 +30,19 @@ StorageDead(_2); StorageDead(_3); StorageLive(_5); -- StorageLive(_6); -+ nop; + StorageLive(_6); _6 = const 3_usize; -- _7 = PtrMetadata(copy _1); + _7 = Len((*_1)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; -+ _7 = const 3_usize; -+ _8 = const false; -+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable]; ++ _8 = Lt(const 3_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind unreachable]; } bb1: { - _5 = copy (*_1)[_6]; -- StorageDead(_6); + _5 = copy (*_1)[3 of 4]; -+ nop; + StorageDead(_6); _0 = const (); StorageDead(_5); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff index b51d0c0845f38..dd411d84f9fbe 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff @@ -30,22 +30,19 @@ StorageDead(_2); StorageDead(_3); StorageLive(_5); -- StorageLive(_6); -+ nop; + StorageLive(_6); _6 = const 3_usize; -- _7 = PtrMetadata(copy _1); + _7 = Len((*_1)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; -+ _7 = const 3_usize; -+ _8 = const false; -+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue]; ++ _8 = Lt(const 3_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind continue]; } bb1: { - _5 = copy (*_1)[_6]; -- StorageDead(_6); + _5 = copy (*_1)[3 of 4]; -+ nop; + StorageDead(_6); _0 = const (); StorageDead(_5); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff index be42c4d60c807..15d3014036713 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff @@ -30,22 +30,19 @@ StorageDead(_2); StorageDead(_3); StorageLive(_5); -- StorageLive(_6); -+ nop; + StorageLive(_6); _6 = const 3_usize; -- _7 = PtrMetadata(copy _1); + _7 = Len((*_1)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; -+ _7 = const 3_usize; -+ _8 = const false; -+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable]; ++ _8 = Lt(const 3_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind unreachable]; } bb1: { - _5 = copy (*_1)[_6]; -- StorageDead(_6); + _5 = copy (*_1)[3 of 4]; -+ nop; + StorageDead(_6); _0 = const (); StorageDead(_5); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff index b51d0c0845f38..dd411d84f9fbe 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff @@ -30,22 +30,19 @@ StorageDead(_2); StorageDead(_3); StorageLive(_5); -- StorageLive(_6); -+ nop; + StorageLive(_6); _6 = const 3_usize; -- _7 = PtrMetadata(copy _1); + _7 = Len((*_1)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; -+ _7 = const 3_usize; -+ _8 = const false; -+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue]; ++ _8 = Lt(const 3_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind continue]; } bb1: { - _5 = copy (*_1)[_6]; -- StorageDead(_6); + _5 = copy (*_1)[3 of 4]; -+ nop; + StorageDead(_6); _0 = const (); StorageDead(_5); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff index 3569998b13fa5..49ea51deed69d 100644 --- a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff @@ -6,7 +6,8 @@ let _1: u8; let mut _2: [u8; 5000]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u8; 5000]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 5000_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable]; ++ _4 = const 5000_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff index 50b31c9ac136c..103bfbcaf6426 100644 --- a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff @@ -6,7 +6,8 @@ let _1: u8; let mut _2: [u8; 5000]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u8; 5000]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 5000_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue]; ++ _4 = const 5000_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff index 3569998b13fa5..49ea51deed69d 100644 --- a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff @@ -6,7 +6,8 @@ let _1: u8; let mut _2: [u8; 5000]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u8; 5000]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 5000_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable]; ++ _4 = const 5000_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff index 50b31c9ac136c..103bfbcaf6426 100644 --- a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff @@ -6,7 +6,8 @@ let _1: u8; let mut _2: [u8; 5000]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u8; 5000]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 5000_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue]; ++ _4 = const 5000_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff index a41668b6fa36a..f7c1c2da01fc1 100644 --- a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff @@ -7,7 +7,8 @@ let mut _2: u32; let mut _3: [u32; 8]; let _4: usize; - let mut _5: bool; + let mut _5: usize; + let mut _6: bool; scope 1 { debug x => _1; } @@ -19,9 +20,11 @@ _3 = [const 42_u32; 8]; StorageLive(_4); _4 = const 2_usize; -- _5 = Lt(copy _4, const 8_usize); -- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable]; -+ _5 = const true; +- _5 = Len(_3); +- _6 = Lt(copy _4, copy _5); +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable]; ++ _5 = const 8_usize; ++ _6 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff index 2313084b49e6f..436773c855636 100644 --- a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff @@ -7,7 +7,8 @@ let mut _2: u32; let mut _3: [u32; 8]; let _4: usize; - let mut _5: bool; + let mut _5: usize; + let mut _6: bool; scope 1 { debug x => _1; } @@ -19,9 +20,11 @@ _3 = [const 42_u32; 8]; StorageLive(_4); _4 = const 2_usize; -- _5 = Lt(copy _4, const 8_usize); -- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue]; -+ _5 = const true; +- _5 = Len(_3); +- _6 = Lt(copy _4, copy _5); +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue]; ++ _5 = const 8_usize; ++ _6 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff index a41668b6fa36a..f7c1c2da01fc1 100644 --- a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff @@ -7,7 +7,8 @@ let mut _2: u32; let mut _3: [u32; 8]; let _4: usize; - let mut _5: bool; + let mut _5: usize; + let mut _6: bool; scope 1 { debug x => _1; } @@ -19,9 +20,11 @@ _3 = [const 42_u32; 8]; StorageLive(_4); _4 = const 2_usize; -- _5 = Lt(copy _4, const 8_usize); -- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable]; -+ _5 = const true; +- _5 = Len(_3); +- _6 = Lt(copy _4, copy _5); +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable]; ++ _5 = const 8_usize; ++ _6 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff index 2313084b49e6f..436773c855636 100644 --- a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff @@ -7,7 +7,8 @@ let mut _2: u32; let mut _3: [u32; 8]; let _4: usize; - let mut _5: bool; + let mut _5: usize; + let mut _6: bool; scope 1 { debug x => _1; } @@ -19,9 +20,11 @@ _3 = [const 42_u32; 8]; StorageLive(_4); _4 = const 2_usize; -- _5 = Lt(copy _4, const 8_usize); -- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue]; -+ _5 = const true; +- _5 = Len(_3); +- _6 = Lt(copy _4, copy _5); +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue]; ++ _5 = const 8_usize; ++ _6 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff index 0798b30392956..8a8ea5b7e200b 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff @@ -30,12 +30,11 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); + _7 = Len((*_2)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; -+ _7 = const 3_usize; -+ _8 = const true; -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; ++ _8 = Lt(const 1_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable]; } bb1: { diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff index c0b3d4d321902..f0c844884f670 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff @@ -30,12 +30,11 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); + _7 = Len((*_2)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; -+ _7 = const 3_usize; -+ _8 = const true; -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; ++ _8 = Lt(const 1_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff index 0798b30392956..8a8ea5b7e200b 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff @@ -30,12 +30,11 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); + _7 = Len((*_2)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; -+ _7 = const 3_usize; -+ _8 = const true; -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; ++ _8 = Lt(const 1_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable]; } bb1: { diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff index c0b3d4d321902..f0c844884f670 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff @@ -30,12 +30,11 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); + _7 = Len((*_2)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; -+ _7 = const 3_usize; -+ _8 = const true; -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; ++ _8 = Lt(const 1_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue]; } bb1: { 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 index 689083dfc1d3a..6d967257df1f5 100644 --- 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 @@ -18,7 +18,8 @@ let mut _15: !; let mut _17: i32; let _18: usize; - let mut _19: bool; + let mut _19: usize; + let mut _20: bool; scope 1 { debug sum => _1; let _2: [i32; 4]; @@ -91,10 +92,11 @@ StorageLive(_17); - StorageLive(_18); - _18 = copy _16; -- _19 = Lt(copy _18, const 4_usize); -- assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _18) -> [success: bb8, unwind unreachable]; -+ _19 = Lt(copy _16, const 4_usize); -+ assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _16) -> [success: bb8, unwind unreachable]; + _19 = Len(_2); +- _20 = Lt(copy _18, copy _19); +- assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _18) -> [success: bb8, unwind unreachable]; ++ _20 = Lt(copy _16, copy _19); ++ assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _16) -> [success: bb8, unwind unreachable]; } bb7: { diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff index 7f768a9f834d9..3580c87c46995 100644 --- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff +++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff @@ -18,7 +18,8 @@ let mut _15: !; let mut _17: i32; let _18: usize; - let mut _19: bool; + let mut _19: usize; + let mut _20: bool; scope 1 { debug sum => _1; let _2: [i32; 4]; @@ -91,10 +92,11 @@ StorageLive(_17); - StorageLive(_18); - _18 = copy _16; -- _19 = Lt(copy _18, const 4_usize); -- assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _18) -> [success: bb8, unwind continue]; -+ _19 = Lt(copy _16, const 4_usize); -+ assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _16) -> [success: bb8, unwind continue]; + _19 = Len(_2); +- _20 = Lt(copy _18, copy _19); +- assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _18) -> [success: bb8, unwind continue]; ++ _20 = Lt(copy _16, copy _19); ++ assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _16) -> [success: bb8, unwind continue]; } bb7: { diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff index 0275d7e8a0d4d..a46daef435f3b 100644 --- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff @@ -6,7 +6,8 @@ let _1: u32; let mut _2: [u32; 4]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 4_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable]; ++ _4 = const 4_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff index 490ed4b55a1da..1a4e15b45faad 100644 --- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff @@ -6,7 +6,8 @@ let _1: u32; let mut _2: [u32; 4]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 4_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue]; ++ _4 = const 4_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff index 0275d7e8a0d4d..a46daef435f3b 100644 --- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff @@ -6,7 +6,8 @@ let _1: u32; let mut _2: [u32; 4]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 4_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable]; ++ _4 = const 4_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff index 490ed4b55a1da..1a4e15b45faad 100644 --- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff @@ -6,7 +6,8 @@ let _1: u32; let mut _2: [u32; 4]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 4_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue]; ++ _4 = const 4_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/dataflow-const-prop/array_index.rs b/tests/mir-opt/dataflow-const-prop/array_index.rs index 1aa8dcd28f4eb..e442ef99f79e6 100644 --- a/tests/mir-opt/dataflow-const-prop/array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/array_index.rs @@ -11,10 +11,9 @@ fn main() { // CHECK: [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // CHECK-NOT: {{_.*}} = Len( - // CHECK-NOT: {{_.*}} = PtrMetadata( // CHECK-NOT: {{_.*}} = Lt( // CHECK-NOT: assert(move _ - // CHECK: {{_.*}} = const 2_usize; + // CHECK: {{_.*}} = const 4_usize; // CHECK: {{_.*}} = const true; // CHECK: assert(const true // CHECK: [[x]] = copy [[array_lit]][2 of 3]; diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff index f0d59ef5923fb..b7ff0b671f7bf 100644 --- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff @@ -6,7 +6,8 @@ let _1: u8; let mut _2: [u8; 5000]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u8; 5000]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 5000_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable]; ++ _4 = const 5000_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff index 959c3e75214fb..af6e3626142fc 100644 --- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff @@ -6,7 +6,8 @@ let _1: u8; let mut _2: [u8; 5000]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u8; 5000]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 5000_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue]; ++ _4 = const 5000_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff index f0d59ef5923fb..b7ff0b671f7bf 100644 --- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff @@ -6,7 +6,8 @@ let _1: u8; let mut _2: [u8; 5000]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u8; 5000]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 5000_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable]; ++ _4 = const 5000_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff index 959c3e75214fb..af6e3626142fc 100644 --- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff @@ -6,7 +6,8 @@ let _1: u8; let mut _2: [u8; 5000]; let _3: usize; - let mut _4: bool; + let mut _4: usize; + let mut _5: bool; scope 1 { debug x => _1; } @@ -17,9 +18,11 @@ _2 = [const 0_u8; 5000]; StorageLive(_3); _3 = const 2_usize; -- _4 = Lt(copy _3, const 5000_usize); -- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue]; -+ _4 = const true; +- _4 = Len(_2); +- _5 = Lt(copy _3, copy _4); +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue]; ++ _4 = const 5000_usize; ++ _5 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.rs b/tests/mir-opt/dataflow-const-prop/large_array_index.rs index e490cfde24726..e9f2fa2badf95 100644 --- a/tests/mir-opt/dataflow-const-prop/large_array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/large_array_index.rs @@ -10,7 +10,7 @@ fn main() { // CHECK: debug x => [[x:_.*]]; // CHECK: [[array_lit:_.*]] = [const 0_u8; 5000]; - // CHECK: {{_.*}} = const 2_usize; + // CHECK: {{_.*}} = const 5000_usize; // CHECK: {{_.*}} = const true; // CHECK: assert(const true // CHECK: [[x]] = copy [[array_lit]][2 of 3]; diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff index 618121ea6326c..dfa541b1200d5 100644 --- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff @@ -7,7 +7,8 @@ let mut _2: u32; let mut _3: [u32; 8]; let _4: usize; - let mut _5: bool; + let mut _5: usize; + let mut _6: bool; scope 1 { debug x => _1; } @@ -19,9 +20,11 @@ _3 = [const 42_u32; 8]; StorageLive(_4); _4 = const 2_usize; -- _5 = Lt(copy _4, const 8_usize); -- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable]; -+ _5 = const true; +- _5 = Len(_3); +- _6 = Lt(copy _4, copy _5); +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable]; ++ _5 = const 8_usize; ++ _6 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff index 1788f58432b8e..9ede3c5f7ac21 100644 --- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff @@ -7,7 +7,8 @@ let mut _2: u32; let mut _3: [u32; 8]; let _4: usize; - let mut _5: bool; + let mut _5: usize; + let mut _6: bool; scope 1 { debug x => _1; } @@ -19,9 +20,11 @@ _3 = [const 42_u32; 8]; StorageLive(_4); _4 = const 2_usize; -- _5 = Lt(copy _4, const 8_usize); -- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue]; -+ _5 = const true; +- _5 = Len(_3); +- _6 = Lt(copy _4, copy _5); +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue]; ++ _5 = const 8_usize; ++ _6 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff index 618121ea6326c..dfa541b1200d5 100644 --- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff @@ -7,7 +7,8 @@ let mut _2: u32; let mut _3: [u32; 8]; let _4: usize; - let mut _5: bool; + let mut _5: usize; + let mut _6: bool; scope 1 { debug x => _1; } @@ -19,9 +20,11 @@ _3 = [const 42_u32; 8]; StorageLive(_4); _4 = const 2_usize; -- _5 = Lt(copy _4, const 8_usize); -- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable]; -+ _5 = const true; +- _5 = Len(_3); +- _6 = Lt(copy _4, copy _5); +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable]; ++ _5 = const 8_usize; ++ _6 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff index 1788f58432b8e..9ede3c5f7ac21 100644 --- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff @@ -7,7 +7,8 @@ let mut _2: u32; let mut _3: [u32; 8]; let _4: usize; - let mut _5: bool; + let mut _5: usize; + let mut _6: bool; scope 1 { debug x => _1; } @@ -19,9 +20,11 @@ _3 = [const 42_u32; 8]; StorageLive(_4); _4 = const 2_usize; -- _5 = Lt(copy _4, const 8_usize); -- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue]; -+ _5 = const true; +- _5 = Len(_3); +- _6 = Lt(copy _4, copy _5); +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue]; ++ _5 = const 8_usize; ++ _6 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue]; } diff --git a/tests/mir-opt/dataflow-const-prop/repeat.rs b/tests/mir-opt/dataflow-const-prop/repeat.rs index 1bc2cb82a6068..2067aa3d709e2 100644 --- a/tests/mir-opt/dataflow-const-prop/repeat.rs +++ b/tests/mir-opt/dataflow-const-prop/repeat.rs @@ -9,9 +9,8 @@ fn main() { // CHECK: [[array_lit:_.*]] = [const 42_u32; 8]; // CHECK-NOT: {{_.*}} = Len( - // CHECK-NOT: {{_.*}} = PtrMetadata( // CHECK-NOT: {{_.*}} = Lt( - // CHECK: {{_.*}} = const 2_usize; + // CHECK: {{_.*}} = const 8_usize; // CHECK: {{_.*}} = const true; // CHECK: assert(const true diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff new file mode 100644 index 0000000000000..e71992316dcf4 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff @@ -0,0 +1,77 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); + let _1: u32; + let mut _2: &[u32]; + let mut _3: &[u32; 3]; + let _4: &[u32; 3]; + let _5: [u32; 3]; + let _6: usize; + let mut _7: usize; + let mut _8: bool; + let mut _10: &[u32]; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: &[u32; 3]; + scope 1 { + debug local => _1; + let _9: u32; + scope 2 { + debug constant => _9; + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); + StorageLive(_4); + _14 = const main::promoted[0]; + _4 = copy _14; + _3 = copy _4; + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + StorageDead(_3); + StorageLive(_6); + _6 = const 1_usize; +- _7 = Len((*_2)); +- _8 = Lt(copy _6, copy _7); +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; + } + + bb1: { +- _1 = copy (*_2)[_6]; ++ _1 = copy (*_2)[1 of 2]; + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); + StorageLive(_9); + StorageLive(_10); + _10 = const main::SLICE; + StorageLive(_11); + _11 = const 1_usize; +- _12 = Len((*_10)); +- _13 = Lt(copy _11, copy _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable]; + } + + bb2: { +- _9 = copy (*_10)[_11]; ++ _9 = copy (*_10)[1 of 2]; + StorageDead(_11); + StorageDead(_10); + _0 = const (); + StorageDead(_9); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff new file mode 100644 index 0000000000000..26de859576896 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff @@ -0,0 +1,77 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); + let _1: u32; + let mut _2: &[u32]; + let mut _3: &[u32; 3]; + let _4: &[u32; 3]; + let _5: [u32; 3]; + let _6: usize; + let mut _7: usize; + let mut _8: bool; + let mut _10: &[u32]; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: &[u32; 3]; + scope 1 { + debug local => _1; + let _9: u32; + scope 2 { + debug constant => _9; + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); + StorageLive(_4); + _14 = const main::promoted[0]; + _4 = copy _14; + _3 = copy _4; + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + StorageDead(_3); + StorageLive(_6); + _6 = const 1_usize; +- _7 = Len((*_2)); +- _8 = Lt(copy _6, copy _7); +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; + } + + bb1: { +- _1 = copy (*_2)[_6]; ++ _1 = copy (*_2)[1 of 2]; + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); + StorageLive(_9); + StorageLive(_10); + _10 = const main::SLICE; + StorageLive(_11); + _11 = const 1_usize; +- _12 = Len((*_10)); +- _13 = Lt(copy _11, copy _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue]; + } + + bb2: { +- _9 = copy (*_10)[_11]; ++ _9 = copy (*_10)[1 of 2]; + StorageDead(_11); + StorageDead(_10); + _0 = const (); + StorageDead(_9); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff new file mode 100644 index 0000000000000..e71992316dcf4 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff @@ -0,0 +1,77 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); + let _1: u32; + let mut _2: &[u32]; + let mut _3: &[u32; 3]; + let _4: &[u32; 3]; + let _5: [u32; 3]; + let _6: usize; + let mut _7: usize; + let mut _8: bool; + let mut _10: &[u32]; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: &[u32; 3]; + scope 1 { + debug local => _1; + let _9: u32; + scope 2 { + debug constant => _9; + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); + StorageLive(_4); + _14 = const main::promoted[0]; + _4 = copy _14; + _3 = copy _4; + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + StorageDead(_3); + StorageLive(_6); + _6 = const 1_usize; +- _7 = Len((*_2)); +- _8 = Lt(copy _6, copy _7); +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; + } + + bb1: { +- _1 = copy (*_2)[_6]; ++ _1 = copy (*_2)[1 of 2]; + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); + StorageLive(_9); + StorageLive(_10); + _10 = const main::SLICE; + StorageLive(_11); + _11 = const 1_usize; +- _12 = Len((*_10)); +- _13 = Lt(copy _11, copy _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable]; + } + + bb2: { +- _9 = copy (*_10)[_11]; ++ _9 = copy (*_10)[1 of 2]; + StorageDead(_11); + StorageDead(_10); + _0 = const (); + StorageDead(_9); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff new file mode 100644 index 0000000000000..26de859576896 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff @@ -0,0 +1,77 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); + let _1: u32; + let mut _2: &[u32]; + let mut _3: &[u32; 3]; + let _4: &[u32; 3]; + let _5: [u32; 3]; + let _6: usize; + let mut _7: usize; + let mut _8: bool; + let mut _10: &[u32]; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: &[u32; 3]; + scope 1 { + debug local => _1; + let _9: u32; + scope 2 { + debug constant => _9; + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); + StorageLive(_4); + _14 = const main::promoted[0]; + _4 = copy _14; + _3 = copy _4; + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + StorageDead(_3); + StorageLive(_6); + _6 = const 1_usize; +- _7 = Len((*_2)); +- _8 = Lt(copy _6, copy _7); +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; + } + + bb1: { +- _1 = copy (*_2)[_6]; ++ _1 = copy (*_2)[1 of 2]; + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); + StorageLive(_9); + StorageLive(_10); + _10 = const main::SLICE; + StorageLive(_11); + _11 = const 1_usize; +- _12 = Len((*_10)); +- _13 = Lt(copy _11, copy _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue]; + } + + bb2: { +- _9 = copy (*_10)[_11]; ++ _9 = copy (*_10)[1 of 2]; + StorageDead(_11); + StorageDead(_10); + _0 = const (); + StorageDead(_9); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.rs b/tests/mir-opt/dataflow-const-prop/slice_len.rs new file mode 100644 index 0000000000000..e0e68f9fde54a --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/slice_len.rs @@ -0,0 +1,34 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ test-mir-pass: DataflowConstProp +//@ compile-flags: -Zmir-enable-passes=+InstSimplify-after-simplifycfg +// EMIT_MIR_FOR_EACH_BIT_WIDTH + +// EMIT_MIR slice_len.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( +fn main() { + // CHECK: debug local => [[local:_.*]]; + // CHECK: debug constant => [[constant:_.*]]; + + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK-NOT: assert(move _ + // CHECK: {{_.*}} = const 3_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true, + + // CHECK: [[local]] = copy (*{{_.*}})[1 of 2]; + let local = (&[1u32, 2, 3] as &[u32])[1]; + + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK-NOT: assert(move _ + const SLICE: &[u32] = &[1, 2, 3]; + // CHECK: {{_.*}} = const 3_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true, + + // CHECK-NOT: [[constant]] = {{copy|move}} (*{{_.*}})[_ + // CHECK: [[constant]] = copy (*{{_.*}})[1 of 2]; + let constant = SLICE[1]; +} diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff index 183b4d2599f53..3f052ee19fdfe 100644 --- a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff @@ -53,7 +53,7 @@ StorageLive(_8); - _8 = copy _2; + _8 = const usize::MAX; - _9 = PtrMetadata(copy _1); + _9 = Len((*_1)); - _10 = Lt(copy _8, copy _9); - assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable]; + _10 = Lt(const usize::MAX, copy _9); @@ -72,7 +72,7 @@ StorageDead(_5); StorageLive(_11); _11 = const 0_usize; - _12 = PtrMetadata(copy _1); + _12 = Len((*_1)); - _13 = Lt(copy _11, copy _12); - assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind unreachable]; + _13 = Lt(const 0_usize, copy _12); diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff index 03e8aa3bd9b98..84b738c7804e0 100644 --- a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff @@ -53,7 +53,7 @@ StorageLive(_8); - _8 = copy _2; + _8 = const usize::MAX; - _9 = PtrMetadata(copy _1); + _9 = Len((*_1)); - _10 = Lt(copy _8, copy _9); - assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue]; + _10 = Lt(const usize::MAX, copy _9); @@ -72,7 +72,7 @@ StorageDead(_5); StorageLive(_11); _11 = const 0_usize; - _12 = PtrMetadata(copy _1); + _12 = Len((*_1)); - _13 = Lt(copy _11, copy _12); - assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind continue]; + _13 = Lt(const 0_usize, copy _12); diff --git a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff deleted file mode 100644 index 4b077f580f100..0000000000000 --- a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff +++ /dev/null @@ -1,72 +0,0 @@ -- // MIR for `dedup_multiple_bounds_checks_lengths` before GVN -+ // MIR for `dedup_multiple_bounds_checks_lengths` after GVN - - fn dedup_multiple_bounds_checks_lengths(_1: &[i32]) -> [i32; 3] { - debug x => _1; - let mut _0: [i32; 3]; - let mut _2: i32; - let _3: usize; - let mut _4: usize; - let mut _5: bool; - let mut _6: i32; - let _7: usize; - let mut _8: usize; - let mut _9: bool; - let mut _10: i32; - let _11: usize; - let mut _12: usize; - let mut _13: bool; - - bb0: { - StorageLive(_2); - StorageLive(_3); - _3 = const 42_usize; - _4 = PtrMetadata(copy _1); -- _5 = Lt(copy _3, copy _4); -- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable]; -+ _5 = Lt(const 42_usize, copy _4); -+ assert(move _5, "index out of bounds: the length is {} but the index is {}", copy _4, const 42_usize) -> [success: bb1, unwind unreachable]; - } - - bb1: { -- _2 = copy (*_1)[_3]; -+ _2 = copy (*_1)[42 of 43]; - StorageLive(_6); - StorageLive(_7); - _7 = const 13_usize; -- _8 = PtrMetadata(copy _1); -- _9 = Lt(copy _7, copy _8); -- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable]; -+ _8 = copy _4; -+ _9 = Lt(const 13_usize, copy _4); -+ assert(move _9, "index out of bounds: the length is {} but the index is {}", copy _4, const 13_usize) -> [success: bb2, unwind unreachable]; - } - - bb2: { -- _6 = copy (*_1)[_7]; -+ _6 = copy (*_1)[13 of 14]; - StorageLive(_10); - StorageLive(_11); - _11 = const 7_usize; -- _12 = PtrMetadata(copy _1); -- _13 = Lt(copy _11, copy _12); -- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb3, unwind unreachable]; -+ _12 = copy _4; -+ _13 = Lt(const 7_usize, copy _4); -+ assert(move _13, "index out of bounds: the length is {} but the index is {}", copy _4, const 7_usize) -> [success: bb3, unwind unreachable]; - } - - bb3: { -- _10 = copy (*_1)[_11]; -+ _10 = copy (*_1)[7 of 8]; - _0 = [move _2, move _6, move _10]; - StorageDead(_10); - StorageDead(_6); - StorageDead(_2); - StorageDead(_11); - StorageDead(_7); - StorageDead(_3); - return; - } - } - diff --git a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff deleted file mode 100644 index 87e69d440069e..0000000000000 --- a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff +++ /dev/null @@ -1,72 +0,0 @@ -- // MIR for `dedup_multiple_bounds_checks_lengths` before GVN -+ // MIR for `dedup_multiple_bounds_checks_lengths` after GVN - - fn dedup_multiple_bounds_checks_lengths(_1: &[i32]) -> [i32; 3] { - debug x => _1; - let mut _0: [i32; 3]; - let mut _2: i32; - let _3: usize; - let mut _4: usize; - let mut _5: bool; - let mut _6: i32; - let _7: usize; - let mut _8: usize; - let mut _9: bool; - let mut _10: i32; - let _11: usize; - let mut _12: usize; - let mut _13: bool; - - bb0: { - StorageLive(_2); - StorageLive(_3); - _3 = const 42_usize; - _4 = PtrMetadata(copy _1); -- _5 = Lt(copy _3, copy _4); -- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue]; -+ _5 = Lt(const 42_usize, copy _4); -+ assert(move _5, "index out of bounds: the length is {} but the index is {}", copy _4, const 42_usize) -> [success: bb1, unwind continue]; - } - - bb1: { -- _2 = copy (*_1)[_3]; -+ _2 = copy (*_1)[42 of 43]; - StorageLive(_6); - StorageLive(_7); - _7 = const 13_usize; -- _8 = PtrMetadata(copy _1); -- _9 = Lt(copy _7, copy _8); -- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue]; -+ _8 = copy _4; -+ _9 = Lt(const 13_usize, copy _4); -+ assert(move _9, "index out of bounds: the length is {} but the index is {}", copy _4, const 13_usize) -> [success: bb2, unwind continue]; - } - - bb2: { -- _6 = copy (*_1)[_7]; -+ _6 = copy (*_1)[13 of 14]; - StorageLive(_10); - StorageLive(_11); - _11 = const 7_usize; -- _12 = PtrMetadata(copy _1); -- _13 = Lt(copy _11, copy _12); -- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb3, unwind continue]; -+ _12 = copy _4; -+ _13 = Lt(const 7_usize, copy _4); -+ assert(move _13, "index out of bounds: the length is {} but the index is {}", copy _4, const 7_usize) -> [success: bb3, unwind continue]; - } - - bb3: { -- _10 = copy (*_1)[_11]; -+ _10 = copy (*_1)[7 of 8]; - _0 = [move _2, move _6, move _10]; - StorageDead(_10); - StorageDead(_6); - StorageDead(_2); - StorageDead(_11); - StorageDead(_7); - StorageDead(_3); - return; - } - } - diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff index 7f44176b75683..d4b22d05f6c78 100644 --- a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff @@ -10,11 +10,13 @@ let _5: (); let mut _6: T; let _7: usize; - let mut _8: bool; - let _9: (); - let mut _10: T; - let _11: usize; - let mut _12: bool; + let mut _8: usize; + let mut _9: bool; + let _10: (); + let mut _11: T; + let _12: usize; + let mut _13: usize; + let mut _14: bool; scope 1 { debug a => _3; } @@ -30,10 +32,12 @@ StorageLive(_6); StorageLive(_7); _7 = const 0_usize; -- _8 = Lt(copy _7, const N); -- assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, copy _7) -> [success: bb1, unwind unreachable]; -+ _8 = Lt(const 0_usize, const N); -+ assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable]; +- _8 = Len(_3); +- _9 = Lt(copy _7, copy _8); +- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb1, unwind unreachable]; ++ _8 = const N; ++ _9 = Lt(const 0_usize, const N); ++ assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable]; } bb1: { @@ -47,27 +51,29 @@ StorageDead(_6); StorageDead(_7); StorageDead(_5); - StorageLive(_9); StorageLive(_10); StorageLive(_11); - _11 = copy _2; -- _12 = Lt(copy _11, const N); -- assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _11) -> [success: bb3, unwind unreachable]; -+ _12 = Lt(copy _2, const N); -+ assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind unreachable]; + StorageLive(_12); + _12 = copy _2; +- _13 = Len(_3); +- _14 = Lt(copy _12, copy _13); +- assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, copy _12) -> [success: bb3, unwind unreachable]; ++ _13 = const N; ++ _14 = Lt(copy _2, const N); ++ assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind unreachable]; } bb3: { -- _10 = copy _3[_11]; -- _9 = opaque::(move _10) -> [return: bb4, unwind unreachable]; -+ _10 = copy _1; -+ _9 = opaque::(copy _1) -> [return: bb4, unwind unreachable]; +- _11 = copy _3[_12]; +- _10 = opaque::(move _11) -> [return: bb4, unwind unreachable]; ++ _11 = copy _1; ++ _10 = opaque::(copy _1) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_10); StorageDead(_11); - StorageDead(_9); + StorageDead(_12); + StorageDead(_10); _0 = const (); StorageDead(_3); return; diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff index d34882d725f49..708c0f92e542e 100644 --- a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff @@ -10,11 +10,13 @@ let _5: (); let mut _6: T; let _7: usize; - let mut _8: bool; - let _9: (); - let mut _10: T; - let _11: usize; - let mut _12: bool; + let mut _8: usize; + let mut _9: bool; + let _10: (); + let mut _11: T; + let _12: usize; + let mut _13: usize; + let mut _14: bool; scope 1 { debug a => _3; } @@ -30,10 +32,12 @@ StorageLive(_6); StorageLive(_7); _7 = const 0_usize; -- _8 = Lt(copy _7, const N); -- assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, copy _7) -> [success: bb1, unwind continue]; -+ _8 = Lt(const 0_usize, const N); -+ assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue]; +- _8 = Len(_3); +- _9 = Lt(copy _7, copy _8); +- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb1, unwind continue]; ++ _8 = const N; ++ _9 = Lt(const 0_usize, const N); ++ assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue]; } bb1: { @@ -47,27 +51,29 @@ StorageDead(_6); StorageDead(_7); StorageDead(_5); - StorageLive(_9); StorageLive(_10); StorageLive(_11); - _11 = copy _2; -- _12 = Lt(copy _11, const N); -- assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _11) -> [success: bb3, unwind continue]; -+ _12 = Lt(copy _2, const N); -+ assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind continue]; + StorageLive(_12); + _12 = copy _2; +- _13 = Len(_3); +- _14 = Lt(copy _12, copy _13); +- assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, copy _12) -> [success: bb3, unwind continue]; ++ _13 = const N; ++ _14 = Lt(copy _2, const N); ++ assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind continue]; } bb3: { -- _10 = copy _3[_11]; -- _9 = opaque::(move _10) -> [return: bb4, unwind continue]; -+ _10 = copy _1; -+ _9 = opaque::(copy _1) -> [return: bb4, unwind continue]; +- _11 = copy _3[_12]; +- _10 = opaque::(move _11) -> [return: bb4, unwind continue]; ++ _11 = copy _1; ++ _10 = opaque::(copy _1) -> [return: bb4, unwind continue]; } bb4: { - StorageDead(_10); StorageDead(_11); - StorageDead(_9); + StorageDead(_12); + StorageDead(_10); _0 = const (); StorageDead(_3); return; diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 19b58a917f87c..97513248e23c6 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -835,25 +835,6 @@ fn array_len(x: &mut [i32; 42]) -> usize { std::intrinsics::ptr_metadata(x) } -// Check that we only load the length once, rather than all 3 times. -fn dedup_multiple_bounds_checks_lengths(x: &[i32]) -> [i32; 3] { - // CHECK-LABEL: fn dedup_multiple_bounds_checks_lengths - // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1); - // CHECK: Lt(const 42_usize, copy [[LEN]]); - // CHECK: assert{{.+}}copy [[LEN]] - // CHECK: [[A:_.+]] = copy (*_1)[42 of 43]; - // CHECK-NOT: PtrMetadata - // CHECK: Lt(const 13_usize, copy [[LEN]]); - // CHECK: assert{{.+}}copy [[LEN]] - // CHECK: [[B:_.+]] = copy (*_1)[13 of 14]; - // CHECK-NOT: PtrMetadata - // CHECK: Lt(const 7_usize, copy [[LEN]]); - // CHECK: assert{{.+}}copy [[LEN]] - // CHECK: [[C:_.+]] = copy (*_1)[7 of 8]; - // CHECK: _0 = [move [[A]], move [[B]], move [[C]]] - [x[42], x[13], x[7]] -} - #[custom_mir(dialect = "runtime")] fn generic_cast_metadata(ps: *const [T], pa: *const A, pb: *const B) { // CHECK-LABEL: fn generic_cast_metadata @@ -1031,7 +1012,6 @@ fn identity(x: T) -> T { // EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff // EMIT_MIR gvn.manual_slice_mut_len.GVN.diff // EMIT_MIR gvn.array_len.GVN.diff -// EMIT_MIR gvn.dedup_multiple_bounds_checks_lengths.GVN.diff // EMIT_MIR gvn.generic_cast_metadata.GVN.diff // EMIT_MIR gvn.cast_pointer_eq.GVN.diff // EMIT_MIR gvn.cast_pointer_then_transmute.GVN.diff diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff index 1b305e746f5ee..6b6152c1117e3 100644 --- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff @@ -10,60 +10,62 @@ let mut _6: &i32; let _7: &i32; let _8: usize; - let mut _9: bool; - let mut _11: *const dyn std::marker::Send; - let _12: &dyn std::marker::Send; - let mut _13: &i32; - let _14: &i32; - let _15: usize; - let mut _16: bool; - let _17: (); + let mut _9: usize; + let mut _10: bool; + let mut _12: *const dyn std::marker::Send; + let _13: &dyn std::marker::Send; + let mut _14: &i32; + let _15: &i32; + let _16: usize; + let mut _17: usize; let mut _18: bool; - let mut _19: *const dyn std::marker::Send; - let mut _20: *const dyn std::marker::Send; + let _19: (); + let mut _20: bool; let mut _21: *const dyn std::marker::Send; - let _22: (); - let mut _23: bool; - let mut _24: *const dyn std::marker::Send; - let mut _25: *const dyn std::marker::Send; + let mut _22: *const dyn std::marker::Send; + let mut _23: *const dyn std::marker::Send; + let _24: (); + let mut _25: bool; let mut _26: *const dyn std::marker::Send; - let _27: (); - let mut _28: bool; - let mut _29: *const dyn std::marker::Send; - let mut _30: *const dyn std::marker::Send; + let mut _27: *const dyn std::marker::Send; + let mut _28: *const dyn std::marker::Send; + let _29: (); + let mut _30: bool; let mut _31: *const dyn std::marker::Send; - let _32: (); - let mut _33: bool; - let mut _34: *const dyn std::marker::Send; - let mut _35: *const dyn std::marker::Send; + let mut _32: *const dyn std::marker::Send; + let mut _33: *const dyn std::marker::Send; + let _34: (); + let mut _35: bool; let mut _36: *const dyn std::marker::Send; - let _37: (); - let mut _38: bool; - let mut _39: *const dyn std::marker::Send; - let mut _40: *const dyn std::marker::Send; + let mut _37: *const dyn std::marker::Send; + let mut _38: *const dyn std::marker::Send; + let _39: (); + let mut _40: bool; let mut _41: *const dyn std::marker::Send; - let _42: (); - let mut _43: bool; - let mut _44: *const dyn std::marker::Send; - let mut _45: *const dyn std::marker::Send; + let mut _42: *const dyn std::marker::Send; + let mut _43: *const dyn std::marker::Send; + let _44: (); + let mut _45: bool; let mut _46: *const dyn std::marker::Send; - let mut _47: &[i32; 2]; + let mut _47: *const dyn std::marker::Send; + let mut _48: *const dyn std::marker::Send; + let mut _49: &[i32; 2]; scope 1 { debug slice => _1; let _3: *const dyn std::marker::Send; scope 2 { debug a => _3; - let _10: *const dyn std::marker::Send; + let _11: *const dyn std::marker::Send; scope 3 { - debug b => _10; + debug b => _11; } } } bb0: { StorageLive(_1); - _47 = const wide_ptr_same_provenance::promoted[0]; - _1 = &(*_47); + _49 = const wide_ptr_same_provenance::promoted[0]; + _1 = &(*_49); StorageLive(_3); - StorageLive(_4); + nop; @@ -72,9 +74,11 @@ StorageLive(_7); StorageLive(_8); _8 = const 0_usize; -- _9 = Lt(copy _8, const 2_usize); -- assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind unreachable]; -+ _9 = const true; +- _9 = Len((*_1)); +- _10 = Lt(copy _8, copy _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb1, unwind unreachable]; ++ _9 = const 2_usize; ++ _10 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind unreachable]; } @@ -91,168 +95,170 @@ + nop; StorageDead(_7); StorageDead(_5); - StorageLive(_10); -- StorageLive(_11); + StorageLive(_11); +- StorageLive(_12); + nop; - StorageLive(_12); StorageLive(_13); StorageLive(_14); StorageLive(_15); - _15 = const 1_usize; -- _16 = Lt(copy _15, const 2_usize); -- assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind unreachable]; -+ _16 = const true; + StorageLive(_16); + _16 = const 1_usize; +- _17 = Len((*_1)); +- _18 = Lt(copy _16, copy _17); +- assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, copy _16) -> [success: bb2, unwind unreachable]; ++ _17 = const 2_usize; ++ _18 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind unreachable]; } bb2: { -- _14 = &(*_1)[_15]; -+ _14 = &(*_1)[1 of 2]; - _13 = &(*_14); - _12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); - StorageDead(_13); - _11 = &raw const (*_12); -- _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -- StorageDead(_11); -+ _10 = copy _11; -+ nop; +- _15 = &(*_1)[_16]; ++ _15 = &(*_1)[1 of 2]; + _14 = &(*_15); + _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_14); - StorageDead(_12); - StorageLive(_17); - StorageLive(_18); + _12 = &raw const (*_13); +- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); +- StorageDead(_12); ++ _11 = copy _12; ++ nop; + StorageDead(_15); + StorageDead(_13); StorageLive(_19); -- _19 = copy _3; -+ _19 = copy _4; StorageLive(_20); StorageLive(_21); -- _21 = copy _10; -- _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _21 = copy _11; -+ _20 = copy _11; +- _21 = copy _3; ++ _21 = copy _4; + StorageLive(_22); + StorageLive(_23); +- _23 = copy _11; +- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _23 = copy _12; ++ _22 = copy _12; + StorageDead(_23); +- _20 = Eq(move _21, move _22); ++ _20 = Eq(copy _4, copy _12); + StorageDead(_22); StorageDead(_21); -- _18 = Eq(move _19, move _20); -+ _18 = Eq(copy _4, copy _11); - StorageDead(_20); - StorageDead(_19); - _17 = opaque::(move _18) -> [return: bb3, unwind unreachable]; + _19 = opaque::(move _20) -> [return: bb3, unwind unreachable]; } bb3: { - StorageDead(_18); - StorageDead(_17); - StorageLive(_22); - StorageLive(_23); + StorageDead(_20); + StorageDead(_19); StorageLive(_24); -- _24 = copy _3; -+ _24 = copy _4; StorageLive(_25); StorageLive(_26); -- _26 = copy _10; -- _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _26 = copy _11; -+ _25 = copy _11; +- _26 = copy _3; ++ _26 = copy _4; + StorageLive(_27); + StorageLive(_28); +- _28 = copy _11; +- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _28 = copy _12; ++ _27 = copy _12; + StorageDead(_28); +- _25 = Ne(move _26, move _27); ++ _25 = Ne(copy _4, copy _12); + StorageDead(_27); StorageDead(_26); -- _23 = Ne(move _24, move _25); -+ _23 = Ne(copy _4, copy _11); - StorageDead(_25); - StorageDead(_24); - _22 = opaque::(move _23) -> [return: bb4, unwind unreachable]; + _24 = opaque::(move _25) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_23); - StorageDead(_22); - StorageLive(_27); - StorageLive(_28); + StorageDead(_25); + StorageDead(_24); StorageLive(_29); -- _29 = copy _3; -+ _29 = copy _4; StorageLive(_30); StorageLive(_31); -- _31 = copy _10; -- _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _31 = copy _11; -+ _30 = copy _11; +- _31 = copy _3; ++ _31 = copy _4; + StorageLive(_32); + StorageLive(_33); +- _33 = copy _11; +- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _33 = copy _12; ++ _32 = copy _12; + StorageDead(_33); +- _30 = Lt(move _31, move _32); ++ _30 = Lt(copy _4, copy _12); + StorageDead(_32); StorageDead(_31); -- _28 = Lt(move _29, move _30); -+ _28 = Lt(copy _4, copy _11); - StorageDead(_30); - StorageDead(_29); - _27 = opaque::(move _28) -> [return: bb5, unwind unreachable]; + _29 = opaque::(move _30) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_28); - StorageDead(_27); - StorageLive(_32); - StorageLive(_33); + StorageDead(_30); + StorageDead(_29); StorageLive(_34); -- _34 = copy _3; -+ _34 = copy _4; StorageLive(_35); StorageLive(_36); -- _36 = copy _10; -- _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _36 = copy _11; -+ _35 = copy _11; +- _36 = copy _3; ++ _36 = copy _4; + StorageLive(_37); + StorageLive(_38); +- _38 = copy _11; +- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _38 = copy _12; ++ _37 = copy _12; + StorageDead(_38); +- _35 = Le(move _36, move _37); ++ _35 = Le(copy _4, copy _12); + StorageDead(_37); StorageDead(_36); -- _33 = Le(move _34, move _35); -+ _33 = Le(copy _4, copy _11); - StorageDead(_35); - StorageDead(_34); - _32 = opaque::(move _33) -> [return: bb6, unwind unreachable]; + _34 = opaque::(move _35) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_33); - StorageDead(_32); - StorageLive(_37); - StorageLive(_38); + StorageDead(_35); + StorageDead(_34); StorageLive(_39); -- _39 = copy _3; -+ _39 = copy _4; StorageLive(_40); StorageLive(_41); -- _41 = copy _10; -- _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _41 = copy _11; -+ _40 = copy _11; +- _41 = copy _3; ++ _41 = copy _4; + StorageLive(_42); + StorageLive(_43); +- _43 = copy _11; +- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _43 = copy _12; ++ _42 = copy _12; + StorageDead(_43); +- _40 = Gt(move _41, move _42); ++ _40 = Gt(copy _4, copy _12); + StorageDead(_42); StorageDead(_41); -- _38 = Gt(move _39, move _40); -+ _38 = Gt(copy _4, copy _11); - StorageDead(_40); - StorageDead(_39); - _37 = opaque::(move _38) -> [return: bb7, unwind unreachable]; + _39 = opaque::(move _40) -> [return: bb7, unwind unreachable]; } bb7: { - StorageDead(_38); - StorageDead(_37); - StorageLive(_42); - StorageLive(_43); + StorageDead(_40); + StorageDead(_39); StorageLive(_44); -- _44 = copy _3; -+ _44 = copy _4; StorageLive(_45); StorageLive(_46); -- _46 = copy _10; -- _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _46 = copy _11; -+ _45 = copy _11; +- _46 = copy _3; ++ _46 = copy _4; + StorageLive(_47); + StorageLive(_48); +- _48 = copy _11; +- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _48 = copy _12; ++ _47 = copy _12; + StorageDead(_48); +- _45 = Ge(move _46, move _47); ++ _45 = Ge(copy _4, copy _12); + StorageDead(_47); StorageDead(_46); -- _43 = Ge(move _44, move _45); -+ _43 = Ge(copy _4, copy _11); - StorageDead(_45); - StorageDead(_44); - _42 = opaque::(move _43) -> [return: bb8, unwind unreachable]; + _44 = opaque::(move _45) -> [return: bb8, unwind unreachable]; } bb8: { - StorageDead(_43); - StorageDead(_42); + StorageDead(_45); + StorageDead(_44); _0 = const (); - StorageDead(_15); - StorageDead(_10); + StorageDead(_16); + StorageDead(_11); StorageDead(_8); StorageDead(_3); StorageDead(_1); diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff index e418ecf25bd4f..093c1ec6ce379 100644 --- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff @@ -10,60 +10,62 @@ let mut _6: &i32; let _7: &i32; let _8: usize; - let mut _9: bool; - let mut _11: *const dyn std::marker::Send; - let _12: &dyn std::marker::Send; - let mut _13: &i32; - let _14: &i32; - let _15: usize; - let mut _16: bool; - let _17: (); + let mut _9: usize; + let mut _10: bool; + let mut _12: *const dyn std::marker::Send; + let _13: &dyn std::marker::Send; + let mut _14: &i32; + let _15: &i32; + let _16: usize; + let mut _17: usize; let mut _18: bool; - let mut _19: *const dyn std::marker::Send; - let mut _20: *const dyn std::marker::Send; + let _19: (); + let mut _20: bool; let mut _21: *const dyn std::marker::Send; - let _22: (); - let mut _23: bool; - let mut _24: *const dyn std::marker::Send; - let mut _25: *const dyn std::marker::Send; + let mut _22: *const dyn std::marker::Send; + let mut _23: *const dyn std::marker::Send; + let _24: (); + let mut _25: bool; let mut _26: *const dyn std::marker::Send; - let _27: (); - let mut _28: bool; - let mut _29: *const dyn std::marker::Send; - let mut _30: *const dyn std::marker::Send; + let mut _27: *const dyn std::marker::Send; + let mut _28: *const dyn std::marker::Send; + let _29: (); + let mut _30: bool; let mut _31: *const dyn std::marker::Send; - let _32: (); - let mut _33: bool; - let mut _34: *const dyn std::marker::Send; - let mut _35: *const dyn std::marker::Send; + let mut _32: *const dyn std::marker::Send; + let mut _33: *const dyn std::marker::Send; + let _34: (); + let mut _35: bool; let mut _36: *const dyn std::marker::Send; - let _37: (); - let mut _38: bool; - let mut _39: *const dyn std::marker::Send; - let mut _40: *const dyn std::marker::Send; + let mut _37: *const dyn std::marker::Send; + let mut _38: *const dyn std::marker::Send; + let _39: (); + let mut _40: bool; let mut _41: *const dyn std::marker::Send; - let _42: (); - let mut _43: bool; - let mut _44: *const dyn std::marker::Send; - let mut _45: *const dyn std::marker::Send; + let mut _42: *const dyn std::marker::Send; + let mut _43: *const dyn std::marker::Send; + let _44: (); + let mut _45: bool; let mut _46: *const dyn std::marker::Send; - let mut _47: &[i32; 2]; + let mut _47: *const dyn std::marker::Send; + let mut _48: *const dyn std::marker::Send; + let mut _49: &[i32; 2]; scope 1 { debug slice => _1; let _3: *const dyn std::marker::Send; scope 2 { debug a => _3; - let _10: *const dyn std::marker::Send; + let _11: *const dyn std::marker::Send; scope 3 { - debug b => _10; + debug b => _11; } } } bb0: { StorageLive(_1); - _47 = const wide_ptr_same_provenance::promoted[0]; - _1 = &(*_47); + _49 = const wide_ptr_same_provenance::promoted[0]; + _1 = &(*_49); StorageLive(_3); - StorageLive(_4); + nop; @@ -72,9 +74,11 @@ StorageLive(_7); StorageLive(_8); _8 = const 0_usize; -- _9 = Lt(copy _8, const 2_usize); -- assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind continue]; -+ _9 = const true; +- _9 = Len((*_1)); +- _10 = Lt(copy _8, copy _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb1, unwind continue]; ++ _9 = const 2_usize; ++ _10 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind continue]; } @@ -91,168 +95,170 @@ + nop; StorageDead(_7); StorageDead(_5); - StorageLive(_10); -- StorageLive(_11); + StorageLive(_11); +- StorageLive(_12); + nop; - StorageLive(_12); StorageLive(_13); StorageLive(_14); StorageLive(_15); - _15 = const 1_usize; -- _16 = Lt(copy _15, const 2_usize); -- assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind continue]; -+ _16 = const true; + StorageLive(_16); + _16 = const 1_usize; +- _17 = Len((*_1)); +- _18 = Lt(copy _16, copy _17); +- assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, copy _16) -> [success: bb2, unwind continue]; ++ _17 = const 2_usize; ++ _18 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind continue]; } bb2: { -- _14 = &(*_1)[_15]; -+ _14 = &(*_1)[1 of 2]; - _13 = &(*_14); - _12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); - StorageDead(_13); - _11 = &raw const (*_12); -- _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -- StorageDead(_11); -+ _10 = copy _11; -+ nop; +- _15 = &(*_1)[_16]; ++ _15 = &(*_1)[1 of 2]; + _14 = &(*_15); + _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_14); - StorageDead(_12); - StorageLive(_17); - StorageLive(_18); + _12 = &raw const (*_13); +- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); +- StorageDead(_12); ++ _11 = copy _12; ++ nop; + StorageDead(_15); + StorageDead(_13); StorageLive(_19); -- _19 = copy _3; -+ _19 = copy _4; StorageLive(_20); StorageLive(_21); -- _21 = copy _10; -- _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _21 = copy _11; -+ _20 = copy _11; +- _21 = copy _3; ++ _21 = copy _4; + StorageLive(_22); + StorageLive(_23); +- _23 = copy _11; +- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _23 = copy _12; ++ _22 = copy _12; + StorageDead(_23); +- _20 = Eq(move _21, move _22); ++ _20 = Eq(copy _4, copy _12); + StorageDead(_22); StorageDead(_21); -- _18 = Eq(move _19, move _20); -+ _18 = Eq(copy _4, copy _11); - StorageDead(_20); - StorageDead(_19); - _17 = opaque::(move _18) -> [return: bb3, unwind continue]; + _19 = opaque::(move _20) -> [return: bb3, unwind continue]; } bb3: { - StorageDead(_18); - StorageDead(_17); - StorageLive(_22); - StorageLive(_23); + StorageDead(_20); + StorageDead(_19); StorageLive(_24); -- _24 = copy _3; -+ _24 = copy _4; StorageLive(_25); StorageLive(_26); -- _26 = copy _10; -- _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _26 = copy _11; -+ _25 = copy _11; +- _26 = copy _3; ++ _26 = copy _4; + StorageLive(_27); + StorageLive(_28); +- _28 = copy _11; +- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _28 = copy _12; ++ _27 = copy _12; + StorageDead(_28); +- _25 = Ne(move _26, move _27); ++ _25 = Ne(copy _4, copy _12); + StorageDead(_27); StorageDead(_26); -- _23 = Ne(move _24, move _25); -+ _23 = Ne(copy _4, copy _11); - StorageDead(_25); - StorageDead(_24); - _22 = opaque::(move _23) -> [return: bb4, unwind continue]; + _24 = opaque::(move _25) -> [return: bb4, unwind continue]; } bb4: { - StorageDead(_23); - StorageDead(_22); - StorageLive(_27); - StorageLive(_28); + StorageDead(_25); + StorageDead(_24); StorageLive(_29); -- _29 = copy _3; -+ _29 = copy _4; StorageLive(_30); StorageLive(_31); -- _31 = copy _10; -- _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _31 = copy _11; -+ _30 = copy _11; +- _31 = copy _3; ++ _31 = copy _4; + StorageLive(_32); + StorageLive(_33); +- _33 = copy _11; +- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _33 = copy _12; ++ _32 = copy _12; + StorageDead(_33); +- _30 = Lt(move _31, move _32); ++ _30 = Lt(copy _4, copy _12); + StorageDead(_32); StorageDead(_31); -- _28 = Lt(move _29, move _30); -+ _28 = Lt(copy _4, copy _11); - StorageDead(_30); - StorageDead(_29); - _27 = opaque::(move _28) -> [return: bb5, unwind continue]; + _29 = opaque::(move _30) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_28); - StorageDead(_27); - StorageLive(_32); - StorageLive(_33); + StorageDead(_30); + StorageDead(_29); StorageLive(_34); -- _34 = copy _3; -+ _34 = copy _4; StorageLive(_35); StorageLive(_36); -- _36 = copy _10; -- _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _36 = copy _11; -+ _35 = copy _11; +- _36 = copy _3; ++ _36 = copy _4; + StorageLive(_37); + StorageLive(_38); +- _38 = copy _11; +- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _38 = copy _12; ++ _37 = copy _12; + StorageDead(_38); +- _35 = Le(move _36, move _37); ++ _35 = Le(copy _4, copy _12); + StorageDead(_37); StorageDead(_36); -- _33 = Le(move _34, move _35); -+ _33 = Le(copy _4, copy _11); - StorageDead(_35); - StorageDead(_34); - _32 = opaque::(move _33) -> [return: bb6, unwind continue]; + _34 = opaque::(move _35) -> [return: bb6, unwind continue]; } bb6: { - StorageDead(_33); - StorageDead(_32); - StorageLive(_37); - StorageLive(_38); + StorageDead(_35); + StorageDead(_34); StorageLive(_39); -- _39 = copy _3; -+ _39 = copy _4; StorageLive(_40); StorageLive(_41); -- _41 = copy _10; -- _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _41 = copy _11; -+ _40 = copy _11; +- _41 = copy _3; ++ _41 = copy _4; + StorageLive(_42); + StorageLive(_43); +- _43 = copy _11; +- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _43 = copy _12; ++ _42 = copy _12; + StorageDead(_43); +- _40 = Gt(move _41, move _42); ++ _40 = Gt(copy _4, copy _12); + StorageDead(_42); StorageDead(_41); -- _38 = Gt(move _39, move _40); -+ _38 = Gt(copy _4, copy _11); - StorageDead(_40); - StorageDead(_39); - _37 = opaque::(move _38) -> [return: bb7, unwind continue]; + _39 = opaque::(move _40) -> [return: bb7, unwind continue]; } bb7: { - StorageDead(_38); - StorageDead(_37); - StorageLive(_42); - StorageLive(_43); + StorageDead(_40); + StorageDead(_39); StorageLive(_44); -- _44 = copy _3; -+ _44 = copy _4; StorageLive(_45); StorageLive(_46); -- _46 = copy _10; -- _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _46 = copy _11; -+ _45 = copy _11; +- _46 = copy _3; ++ _46 = copy _4; + StorageLive(_47); + StorageLive(_48); +- _48 = copy _11; +- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _48 = copy _12; ++ _47 = copy _12; + StorageDead(_48); +- _45 = Ge(move _46, move _47); ++ _45 = Ge(copy _4, copy _12); + StorageDead(_47); StorageDead(_46); -- _43 = Ge(move _44, move _45); -+ _43 = Ge(copy _4, copy _11); - StorageDead(_45); - StorageDead(_44); - _42 = opaque::(move _43) -> [return: bb8, unwind continue]; + _44 = opaque::(move _45) -> [return: bb8, unwind continue]; } bb8: { - StorageDead(_43); - StorageDead(_42); + StorageDead(_45); + StorageDead(_44); _0 = const (); - StorageDead(_15); - StorageDead(_10); + StorageDead(_16); + StorageDead(_11); StorageDead(_8); StorageDead(_3); StorageDead(_1); diff --git a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff new file mode 100644 index 0000000000000..f39df7ffca0fb --- /dev/null +++ b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff @@ -0,0 +1,77 @@ +- // MIR for `norm2` before InstSimplify-after-simplifycfg ++ // MIR for `norm2` after InstSimplify-after-simplifycfg + + fn norm2(_1: [f32; 2]) -> f32 { + debug x => _1; + let mut _0: f32; + let _2: f32; + let _3: usize; + let mut _4: usize; + let mut _5: bool; + let _7: usize; + let mut _8: usize; + let mut _9: bool; + let mut _10: f32; + let mut _11: f32; + let mut _12: f32; + let mut _13: f32; + let mut _14: f32; + let mut _15: f32; + scope 1 { + debug a => _2; + let _6: f32; + scope 2 { + debug b => _6; + } + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = const 0_usize; +- _4 = Len(_1); ++ _4 = const 2_usize; + _5 = Lt(copy _3, copy _4); + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable]; + } + + bb1: { + _2 = copy _1[_3]; + StorageDead(_3); + StorageLive(_6); + StorageLive(_7); + _7 = const 1_usize; +- _8 = Len(_1); ++ _8 = const 2_usize; + _9 = Lt(copy _7, copy _8); + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable]; + } + + bb2: { + _6 = copy _1[_7]; + StorageDead(_7); + StorageLive(_10); + StorageLive(_11); + _11 = copy _2; + StorageLive(_12); + _12 = copy _2; + _10 = Mul(move _11, move _12); + StorageDead(_12); + StorageDead(_11); + StorageLive(_13); + StorageLive(_14); + _14 = copy _6; + StorageLive(_15); + _15 = copy _6; + _13 = Mul(move _14, move _15); + StorageDead(_15); + StorageDead(_14); + _0 = Add(move _10, move _13); + StorageDead(_13); + StorageDead(_10); + StorageDead(_6); + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff new file mode 100644 index 0000000000000..0e7d5653c6820 --- /dev/null +++ b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff @@ -0,0 +1,77 @@ +- // MIR for `norm2` before InstSimplify-after-simplifycfg ++ // MIR for `norm2` after InstSimplify-after-simplifycfg + + fn norm2(_1: [f32; 2]) -> f32 { + debug x => _1; + let mut _0: f32; + let _2: f32; + let _3: usize; + let mut _4: usize; + let mut _5: bool; + let _7: usize; + let mut _8: usize; + let mut _9: bool; + let mut _10: f32; + let mut _11: f32; + let mut _12: f32; + let mut _13: f32; + let mut _14: f32; + let mut _15: f32; + scope 1 { + debug a => _2; + let _6: f32; + scope 2 { + debug b => _6; + } + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = const 0_usize; +- _4 = Len(_1); ++ _4 = const 2_usize; + _5 = Lt(copy _3, copy _4); + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue]; + } + + bb1: { + _2 = copy _1[_3]; + StorageDead(_3); + StorageLive(_6); + StorageLive(_7); + _7 = const 1_usize; +- _8 = Len(_1); ++ _8 = const 2_usize; + _9 = Lt(copy _7, copy _8); + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue]; + } + + bb2: { + _6 = copy _1[_7]; + StorageDead(_7); + StorageLive(_10); + StorageLive(_11); + _11 = copy _2; + StorageLive(_12); + _12 = copy _2; + _10 = Mul(move _11, move _12); + StorageDead(_12); + StorageDead(_11); + StorageLive(_13); + StorageLive(_14); + _14 = copy _6; + StorageLive(_15); + _15 = copy _6; + _13 = Mul(move _14, move _15); + StorageDead(_15); + StorageDead(_14); + _0 = Add(move _10, move _13); + StorageDead(_13); + StorageDead(_10); + StorageDead(_6); + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/instsimplify/combine_array_len.rs b/tests/mir-opt/instsimplify/combine_array_len.rs new file mode 100644 index 0000000000000..91f43f75689de --- /dev/null +++ b/tests/mir-opt/instsimplify/combine_array_len.rs @@ -0,0 +1,15 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ test-mir-pass: InstSimplify-after-simplifycfg + +// EMIT_MIR combine_array_len.norm2.InstSimplify-after-simplifycfg.diff +fn norm2(x: [f32; 2]) -> f32 { + // CHECK-LABEL: fn norm2( + // CHECK-NOT: Len( + let a = x[0]; + let b = x[1]; + a * a + b * b +} + +fn main() { + assert_eq!(norm2([3.0, 4.0]), 5.0 * 5.0); +} diff --git a/tests/mir-opt/issue_72181.foo.built.after.mir b/tests/mir-opt/issue_72181.foo.built.after.mir index 7593b79543258..314cf8b367f57 100644 --- a/tests/mir-opt/issue_72181.foo.built.after.mir +++ b/tests/mir-opt/issue_72181.foo.built.after.mir @@ -4,14 +4,15 @@ fn foo(_1: [(Never, u32); 1]) -> u32 { debug xs => _1; let mut _0: u32; let _2: usize; - let mut _3: bool; + let mut _3: usize; + let mut _4: bool; bb0: { StorageLive(_2); _2 = const 0_usize; - FakeRead(ForIndex, _1); - _3 = Lt(copy _2, const 1_usize); - assert(move _3, "index out of bounds: the length is {} but the index is {}", const 1_usize, copy _2) -> [success: bb1, unwind: bb2]; + _3 = Len(_1); + _4 = Lt(copy _2, copy _3); + assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind: bb2]; } bb1: { diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir index 9f3803f5407fe..aade84a6dd2e8 100644 --- a/tests/mir-opt/issue_72181.main.built.after.mir +++ b/tests/mir-opt/issue_72181.main.built.after.mir @@ -7,7 +7,8 @@ fn main() -> () { let mut _4: Foo; let mut _5: u64; let _6: usize; - let mut _7: bool; + let mut _7: usize; + let mut _8: bool; scope 1 { let _2: [Foo; 2]; scope 2 { @@ -37,9 +38,9 @@ fn main() -> () { StorageLive(_5); StorageLive(_6); _6 = const 0_usize; - FakeRead(ForIndex, _2); - _7 = Lt(copy _6, const 2_usize); - assert(move _7, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _6) -> [success: bb3, unwind: bb5]; + _7 = Len(_2); + _8 = Lt(copy _6, copy _7); + assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb3, unwind: bb5]; } bb2: { diff --git a/tests/mir-opt/issue_91633.foo.built.after.mir b/tests/mir-opt/issue_91633.foo.built.after.mir index bf65b5b4a8ccb..50fdf08375a00 100644 --- a/tests/mir-opt/issue_91633.foo.built.after.mir +++ b/tests/mir-opt/issue_91633.foo.built.after.mir @@ -6,9 +6,8 @@ fn foo(_1: Box<[T]>) -> T { let _2: T; let mut _3: &T; let _4: usize; - let mut _5: *const [T]; - let mut _6: usize; - let mut _7: bool; + let mut _5: usize; + let mut _6: bool; scope 1 { debug f => _2; } @@ -18,10 +17,9 @@ fn foo(_1: Box<[T]>) -> T { StorageLive(_3); StorageLive(_4); _4 = const 0_usize; - _5 = &raw const (*_1); - _6 = PtrMetadata(move _5); - _7 = Lt(copy _4, copy _6); - assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb5]; + _5 = Len((*_1)); + _6 = Lt(copy _4, copy _5); + assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb5]; } bb1: { diff --git a/tests/mir-opt/issue_91633.fun.built.after.mir b/tests/mir-opt/issue_91633.fun.built.after.mir index d2fc438d3e817..5b41b376719b2 100644 --- a/tests/mir-opt/issue_91633.fun.built.after.mir +++ b/tests/mir-opt/issue_91633.fun.built.after.mir @@ -15,7 +15,7 @@ fn fun(_1: &[T]) -> &T { StorageLive(_2); StorageLive(_3); _3 = const 0_usize; - _4 = PtrMetadata(copy _1); + _4 = Len((*_1)); _5 = Lt(copy _3, copy _4); assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb2]; } diff --git a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff index 98c5e868046b5..f052c8f63dcaa 100644 --- a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff @@ -11,14 +11,16 @@ let mut _6: &[u8]; let mut _7: &[u8; N]; let _8: usize; - let mut _9: bool; + let mut _9: usize; + let mut _10: bool; bb0: { - StorageLive(_3); + nop; StorageLive(_4); _4 = copy _1; - StorageLive(_5); +- StorageLive(_5); ++ nop; StorageLive(_6); StorageLive(_7); _7 = &(*_2); @@ -38,13 +40,16 @@ } bb2: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); StorageLive(_8); _8 = copy _1; -- _9 = Lt(copy _8, const N); -- assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind unreachable]; -+ _9 = copy _3; +- _9 = Len((*_2)); +- _10 = Lt(copy _8, copy _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable]; ++ _9 = const N; ++ _10 = copy _3; + assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable]; } @@ -56,7 +61,8 @@ } bb4: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); _0 = const 42_u8; goto -> bb5; diff --git a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff index 72c7313786996..3299e3004317d 100644 --- a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff @@ -11,14 +11,16 @@ let mut _6: &[u8]; let mut _7: &[u8; N]; let _8: usize; - let mut _9: bool; + let mut _9: usize; + let mut _10: bool; bb0: { - StorageLive(_3); + nop; StorageLive(_4); _4 = copy _1; - StorageLive(_5); +- StorageLive(_5); ++ nop; StorageLive(_6); StorageLive(_7); _7 = &(*_2); @@ -38,13 +40,16 @@ } bb2: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); StorageLive(_8); _8 = copy _1; -- _9 = Lt(copy _8, const N); -- assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind continue]; -+ _9 = copy _3; +- _9 = Len((*_2)); +- _10 = Lt(copy _8, copy _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue]; ++ _9 = const N; ++ _10 = copy _3; + assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue]; } @@ -56,7 +61,8 @@ } bb4: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); _0 = const 42_u8; goto -> bb5; diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff index 9ffaf44c02bd2..329eb80b3c4f5 100644 --- a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff @@ -11,16 +11,19 @@ let mut _6: &[u8]; let mut _7: &[u8; N]; let _8: usize; - let mut _9: bool; - let _10: usize; - let mut _11: bool; + let mut _9: usize; + let mut _10: bool; + let _11: usize; + let mut _12: usize; + let mut _13: bool; bb0: { - StorageLive(_3); + nop; StorageLive(_4); _4 = copy _1; - StorageLive(_5); +- StorageLive(_5); ++ nop; StorageLive(_6); StorageLive(_7); _7 = &(*_2); @@ -40,13 +43,16 @@ } bb2: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); StorageLive(_8); _8 = copy _1; -- _9 = Lt(copy _8, const N); -- assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind unreachable]; -+ _9 = copy _3; +- _9 = Len((*_2)); +- _10 = Lt(copy _8, copy _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable]; ++ _9 = const N; ++ _10 = copy _3; + assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable]; } @@ -58,20 +64,23 @@ } bb4: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); - StorageLive(_10); - _10 = const 0_usize; -- _11 = Lt(copy _10, const N); -- assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, copy _10) -> [success: bb5, unwind unreachable]; -+ _11 = Lt(const 0_usize, const N); -+ assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable]; + StorageLive(_11); + _11 = const 0_usize; +- _12 = Len((*_2)); +- _13 = Lt(copy _11, copy _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind unreachable]; ++ _12 = const N; ++ _13 = Lt(const 0_usize, const N); ++ assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable]; } bb5: { -- (*_2)[_10] = const 42_u8; +- (*_2)[_11] = const 42_u8; + (*_2)[0 of 1] = const 42_u8; - StorageDead(_10); + StorageDead(_11); _0 = const 42_u8; goto -> bb6; } diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff index 08008e463357f..ab007e133ecc1 100644 --- a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff @@ -11,16 +11,19 @@ let mut _6: &[u8]; let mut _7: &[u8; N]; let _8: usize; - let mut _9: bool; - let _10: usize; - let mut _11: bool; + let mut _9: usize; + let mut _10: bool; + let _11: usize; + let mut _12: usize; + let mut _13: bool; bb0: { - StorageLive(_3); + nop; StorageLive(_4); _4 = copy _1; - StorageLive(_5); +- StorageLive(_5); ++ nop; StorageLive(_6); StorageLive(_7); _7 = &(*_2); @@ -40,13 +43,16 @@ } bb2: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); StorageLive(_8); _8 = copy _1; -- _9 = Lt(copy _8, const N); -- assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind continue]; -+ _9 = copy _3; +- _9 = Len((*_2)); +- _10 = Lt(copy _8, copy _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue]; ++ _9 = const N; ++ _10 = copy _3; + assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue]; } @@ -58,20 +64,23 @@ } bb4: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); - StorageLive(_10); - _10 = const 0_usize; -- _11 = Lt(copy _10, const N); -- assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, copy _10) -> [success: bb5, unwind continue]; -+ _11 = Lt(const 0_usize, const N); -+ assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue]; + StorageLive(_11); + _11 = const 0_usize; +- _12 = Len((*_2)); +- _13 = Lt(copy _11, copy _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind continue]; ++ _12 = const N; ++ _13 = Lt(const 0_usize, const N); ++ assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue]; } bb5: { -- (*_2)[_10] = const 42_u8; +- (*_2)[_11] = const 42_u8; + (*_2)[0 of 1] = const 42_u8; - StorageDead(_10); + StorageDead(_11); _0 = const 42_u8; goto -> bb6; } 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 index 4b39e18d16cfc..20001f1248ef5 100644 --- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff +++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff @@ -36,7 +36,7 @@ StorageDead(_4); StorageLive(_7); _7 = copy _1; - _8 = PtrMetadata(copy _2); + _8 = Len((*_2)); _9 = Lt(copy _7, copy _8); assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb3, unwind unreachable]; } diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff index f0d4afa21ae4b..ca8f92df5de0c 100644 --- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff +++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff @@ -36,7 +36,7 @@ StorageDead(_4); StorageLive(_7); _7 = copy _1; - _8 = PtrMetadata(copy _2); + _8 = Len((*_2)); _9 = Lt(copy _7, copy _8); assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb3, unwind continue]; } diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 35e44b2314a50..7294302609a24 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -27,19 +27,20 @@ fn main() -> () { let mut _0: (); let mut _1: [usize; ValTree(Leaf(0x00000003): usize)]; let _3: usize; - let mut _4: bool; - let mut _6: bool; - let _7: bool; - let mut _8: usize; - let _9: bool; + let mut _4: usize; + let mut _5: bool; + let mut _7: bool; + let _8: bool; + let mut _9: usize; + let _10: bool; scope 1 { debug v => _1; let _2: &'?3 usize; scope 2 { debug p => _2; - let _5: &'?4 usize; + let _6: &'?4 usize; scope 3 { - debug q => _5; + debug q => _6; } } } @@ -51,50 +52,50 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); _3 = const ConstValue(Scalar(0x00000000): usize); - FakeRead(ForIndex, _1); - _4 = Lt(copy _3, const ConstValue(Scalar(0x00000003): usize)); - assert(move _4, "index out of bounds: the length is {} but the index is {}", const ConstValue(Scalar(0x00000003): usize), copy _3) -> [success: bb1, unwind: bb7]; + _4 = Len(_1); + _5 = Lt(copy _3, copy _4); + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb7]; } bb1: { _2 = &'?2 _1[_3]; FakeRead(ForLet(None), _2); - StorageLive(_5); - _5 = copy _2; - FakeRead(ForLet(None), _5); StorageLive(_6); - _6 = const ConstValue(Scalar(0x01): bool); - switchInt(move _6) -> [0: bb4, otherwise: bb2]; + _6 = copy _2; + FakeRead(ForLet(None), _6); + StorageLive(_7); + _7 = const ConstValue(Scalar(0x01): bool); + switchInt(move _7) -> [0: bb4, otherwise: bb2]; } bb2: { - StorageLive(_7); StorageLive(_8); - _8 = copy (*_5); - _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7]; + StorageLive(_9); + _9 = copy (*_6); + _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; } bb3: { + StorageDead(_9); StorageDead(_8); - StorageDead(_7); _0 = const ConstValue(ZeroSized: ()); goto -> bb6; } bb4: { - StorageLive(_9); - _9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7]; + StorageLive(_10); + _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7]; } bb5: { - StorageDead(_9); + StorageDead(_10); _0 = const ConstValue(ZeroSized: ()); goto -> bb6; } bb6: { + StorageDead(_7); StorageDead(_6); - StorageDead(_5); StorageDead(_3); StorageDead(_2); StorageDead(_1); diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 6d415f42d06f3..85b89a013c4e4 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -27,19 +27,20 @@ fn main() -> () { let mut _0: (); let mut _1: [usize; ValTree(Leaf(0x0000000000000003): usize)]; let _3: usize; - let mut _4: bool; - let mut _6: bool; - let _7: bool; - let mut _8: usize; - let _9: bool; + let mut _4: usize; + let mut _5: bool; + let mut _7: bool; + let _8: bool; + let mut _9: usize; + let _10: bool; scope 1 { debug v => _1; let _2: &'?3 usize; scope 2 { debug p => _2; - let _5: &'?4 usize; + let _6: &'?4 usize; scope 3 { - debug q => _5; + debug q => _6; } } } @@ -51,50 +52,50 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); _3 = const ConstValue(Scalar(0x0000000000000000): usize); - FakeRead(ForIndex, _1); - _4 = Lt(copy _3, const ConstValue(Scalar(0x0000000000000003): usize)); - assert(move _4, "index out of bounds: the length is {} but the index is {}", const ConstValue(Scalar(0x0000000000000003): usize), copy _3) -> [success: bb1, unwind: bb7]; + _4 = Len(_1); + _5 = Lt(copy _3, copy _4); + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb7]; } bb1: { _2 = &'?2 _1[_3]; FakeRead(ForLet(None), _2); - StorageLive(_5); - _5 = copy _2; - FakeRead(ForLet(None), _5); StorageLive(_6); - _6 = const ConstValue(Scalar(0x01): bool); - switchInt(move _6) -> [0: bb4, otherwise: bb2]; + _6 = copy _2; + FakeRead(ForLet(None), _6); + StorageLive(_7); + _7 = const ConstValue(Scalar(0x01): bool); + switchInt(move _7) -> [0: bb4, otherwise: bb2]; } bb2: { - StorageLive(_7); StorageLive(_8); - _8 = copy (*_5); - _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7]; + StorageLive(_9); + _9 = copy (*_6); + _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; } bb3: { + StorageDead(_9); StorageDead(_8); - StorageDead(_7); _0 = const ConstValue(ZeroSized: ()); goto -> bb6; } bb4: { - StorageLive(_9); - _9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7]; + StorageLive(_10); + _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7]; } bb5: { - StorageDead(_9); + StorageDead(_10); _0 = const ConstValue(ZeroSized: ()); goto -> bb6; } bb6: { + StorageDead(_7); StorageDead(_6); - StorageDead(_5); StorageDead(_3); StorageDead(_2); StorageDead(_1); diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff index 5b39e45806e33..6575610727b99 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff @@ -7,16 +7,17 @@ let mut _2: (i32, bool); let mut _4: [i32; 6]; let _5: usize; - let mut _6: bool; - let mut _8: u32; + let mut _6: usize; + let mut _7: bool; + let mut _9: u32; scope 1 { debug x => _1; let _3: i32; scope 2 { debug y => _3; - let _7: u32; + let _8: u32; scope 3 { - debug z => _7; + debug z => _8; } } } @@ -37,9 +38,10 @@ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; StorageLive(_5); _5 = const 3_usize; -- _6 = Lt(copy _5, const 6_usize); -- assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable]; -+ _6 = const true; + _6 = const 6_usize; +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable]; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable]; } @@ -48,13 +50,13 @@ + _3 = const 3_i32; StorageDead(_5); StorageDead(_4); - StorageLive(_7); StorageLive(_8); - _8 = const 42_u32; -- _7 = copy _8; -+ _7 = const 42_u32; + StorageLive(_9); + _9 = const 42_u32; +- _8 = copy _9; ++ _8 = const 42_u32; + StorageDead(_9); StorageDead(_8); - StorageDead(_7); StorageDead(_3); StorageDead(_1); return; diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff index ea2742a6471a1..1a4ed5767fece 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff @@ -7,16 +7,17 @@ let mut _2: (i32, bool); let mut _4: [i32; 6]; let _5: usize; - let mut _6: bool; - let mut _8: u32; + let mut _6: usize; + let mut _7: bool; + let mut _9: u32; scope 1 { debug x => _1; let _3: i32; scope 2 { debug y => _3; - let _7: u32; + let _8: u32; scope 3 { - debug z => _7; + debug z => _8; } } } @@ -37,9 +38,10 @@ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; StorageLive(_5); _5 = const 3_usize; -- _6 = Lt(copy _5, const 6_usize); -- assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue]; -+ _6 = const true; + _6 = const 6_usize; +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue]; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue]; } @@ -48,13 +50,13 @@ + _3 = const 3_i32; StorageDead(_5); StorageDead(_4); - StorageLive(_7); StorageLive(_8); - _8 = const 42_u32; -- _7 = copy _8; -+ _7 = const 42_u32; + StorageLive(_9); + _9 = const 42_u32; +- _8 = copy _9; ++ _8 = const 42_u32; + StorageDead(_9); StorageDead(_8); - StorageDead(_7); StorageDead(_3); StorageDead(_1); return; diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff index 5b39e45806e33..6575610727b99 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff @@ -7,16 +7,17 @@ let mut _2: (i32, bool); let mut _4: [i32; 6]; let _5: usize; - let mut _6: bool; - let mut _8: u32; + let mut _6: usize; + let mut _7: bool; + let mut _9: u32; scope 1 { debug x => _1; let _3: i32; scope 2 { debug y => _3; - let _7: u32; + let _8: u32; scope 3 { - debug z => _7; + debug z => _8; } } } @@ -37,9 +38,10 @@ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; StorageLive(_5); _5 = const 3_usize; -- _6 = Lt(copy _5, const 6_usize); -- assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable]; -+ _6 = const true; + _6 = const 6_usize; +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable]; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable]; } @@ -48,13 +50,13 @@ + _3 = const 3_i32; StorageDead(_5); StorageDead(_4); - StorageLive(_7); StorageLive(_8); - _8 = const 42_u32; -- _7 = copy _8; -+ _7 = const 42_u32; + StorageLive(_9); + _9 = const 42_u32; +- _8 = copy _9; ++ _8 = const 42_u32; + StorageDead(_9); StorageDead(_8); - StorageDead(_7); StorageDead(_3); StorageDead(_1); return; diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff index ea2742a6471a1..1a4ed5767fece 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff @@ -7,16 +7,17 @@ let mut _2: (i32, bool); let mut _4: [i32; 6]; let _5: usize; - let mut _6: bool; - let mut _8: u32; + let mut _6: usize; + let mut _7: bool; + let mut _9: u32; scope 1 { debug x => _1; let _3: i32; scope 2 { debug y => _3; - let _7: u32; + let _8: u32; scope 3 { - debug z => _7; + debug z => _8; } } } @@ -37,9 +38,10 @@ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; StorageLive(_5); _5 = const 3_usize; -- _6 = Lt(copy _5, const 6_usize); -- assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue]; -+ _6 = const true; + _6 = const 6_usize; +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue]; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue]; } @@ -48,13 +50,13 @@ + _3 = const 3_i32; StorageDead(_5); StorageDead(_4); - StorageLive(_7); StorageLive(_8); - _8 = const 42_u32; -- _7 = copy _8; -+ _7 = const 42_u32; + StorageLive(_9); + _9 = const 42_u32; +- _8 = copy _9; ++ _8 = const 42_u32; + StorageDead(_9); StorageDead(_8); - StorageDead(_7); StorageDead(_3); StorageDead(_1); return; 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 index f7fe08831b97d..e2420a341e0ab 100644 --- 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 @@ -7,18 +7,19 @@ let mut _2: (i32, bool); let mut _4: [i32; 6]; let _5: usize; - let mut _6: bool; - let mut _8: Point; -+ let mut _9: u32; + let mut _6: usize; + let mut _7: bool; + let mut _9: Point; + let mut _10: u32; ++ let mut _11: u32; scope 1 { debug x => _1; let _3: i32; scope 2 { debug y => _3; - let _7: u32; + let _8: u32; scope 3 { - debug z => _7; + debug z => _8; } } } @@ -36,30 +37,31 @@ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; StorageLive(_5); _5 = const 3_usize; - _6 = Lt(copy _5, const 6_usize); - assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable]; + _6 = const 6_usize; + _7 = Lt(copy _5, copy _6); + assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable]; } bb2: { _3 = copy _4[_5]; StorageDead(_5); StorageDead(_4); - StorageLive(_7); -- StorageLive(_8); -- _8 = Point { x: const 12_u32, y: const 42_u32 }; -- _7 = copy (_8.1: u32); -- StorageDead(_8); -+ StorageLive(_9); + StorageLive(_8); +- StorageLive(_9); +- _9 = Point { x: const 12_u32, y: const 42_u32 }; +- _8 = copy (_9.1: u32); +- StorageDead(_9); + StorageLive(_10); ++ StorageLive(_11); + nop; -+ _9 = const 12_u32; -+ _10 = const 42_u32; ++ _10 = const 12_u32; ++ _11 = const 42_u32; + nop; -+ _7 = copy _10; -+ StorageDead(_9); ++ _8 = copy _11; + StorageDead(_10); ++ StorageDead(_11); + nop; - StorageDead(_7); + StorageDead(_8); StorageDead(_3); StorageDead(_1); return; diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff index 6e36386bea601..a2fb3b979e622 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff @@ -7,18 +7,19 @@ let mut _2: (i32, bool); let mut _4: [i32; 6]; let _5: usize; - let mut _6: bool; - let mut _8: Point; -+ let mut _9: u32; + let mut _6: usize; + let mut _7: bool; + let mut _9: Point; + let mut _10: u32; ++ let mut _11: u32; scope 1 { debug x => _1; let _3: i32; scope 2 { debug y => _3; - let _7: u32; + let _8: u32; scope 3 { - debug z => _7; + debug z => _8; } } } @@ -36,30 +37,31 @@ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; StorageLive(_5); _5 = const 3_usize; - _6 = Lt(copy _5, const 6_usize); - assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue]; + _6 = const 6_usize; + _7 = Lt(copy _5, copy _6); + assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue]; } bb2: { _3 = copy _4[_5]; StorageDead(_5); StorageDead(_4); - StorageLive(_7); -- StorageLive(_8); -- _8 = Point { x: const 12_u32, y: const 42_u32 }; -- _7 = copy (_8.1: u32); -- StorageDead(_8); -+ StorageLive(_9); + StorageLive(_8); +- StorageLive(_9); +- _9 = Point { x: const 12_u32, y: const 42_u32 }; +- _8 = copy (_9.1: u32); +- StorageDead(_9); + StorageLive(_10); ++ StorageLive(_11); + nop; -+ _9 = const 12_u32; -+ _10 = const 42_u32; ++ _10 = const 12_u32; ++ _11 = const 42_u32; + nop; -+ _7 = copy _10; -+ StorageDead(_9); ++ _8 = copy _11; + StorageDead(_10); ++ StorageDead(_11); + nop; - StorageDead(_7); + StorageDead(_8); StorageDead(_3); StorageDead(_1); return; 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 index f7fe08831b97d..e2420a341e0ab 100644 --- 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 @@ -7,18 +7,19 @@ let mut _2: (i32, bool); let mut _4: [i32; 6]; let _5: usize; - let mut _6: bool; - let mut _8: Point; -+ let mut _9: u32; + let mut _6: usize; + let mut _7: bool; + let mut _9: Point; + let mut _10: u32; ++ let mut _11: u32; scope 1 { debug x => _1; let _3: i32; scope 2 { debug y => _3; - let _7: u32; + let _8: u32; scope 3 { - debug z => _7; + debug z => _8; } } } @@ -36,30 +37,31 @@ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; StorageLive(_5); _5 = const 3_usize; - _6 = Lt(copy _5, const 6_usize); - assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable]; + _6 = const 6_usize; + _7 = Lt(copy _5, copy _6); + assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable]; } bb2: { _3 = copy _4[_5]; StorageDead(_5); StorageDead(_4); - StorageLive(_7); -- StorageLive(_8); -- _8 = Point { x: const 12_u32, y: const 42_u32 }; -- _7 = copy (_8.1: u32); -- StorageDead(_8); -+ StorageLive(_9); + StorageLive(_8); +- StorageLive(_9); +- _9 = Point { x: const 12_u32, y: const 42_u32 }; +- _8 = copy (_9.1: u32); +- StorageDead(_9); + StorageLive(_10); ++ StorageLive(_11); + nop; -+ _9 = const 12_u32; -+ _10 = const 42_u32; ++ _10 = const 12_u32; ++ _11 = const 42_u32; + nop; -+ _7 = copy _10; -+ StorageDead(_9); ++ _8 = copy _11; + StorageDead(_10); ++ StorageDead(_11); + nop; - StorageDead(_7); + StorageDead(_8); StorageDead(_3); StorageDead(_1); return; diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff index 6e36386bea601..a2fb3b979e622 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff @@ -7,18 +7,19 @@ let mut _2: (i32, bool); let mut _4: [i32; 6]; let _5: usize; - let mut _6: bool; - let mut _8: Point; -+ let mut _9: u32; + let mut _6: usize; + let mut _7: bool; + let mut _9: Point; + let mut _10: u32; ++ let mut _11: u32; scope 1 { debug x => _1; let _3: i32; scope 2 { debug y => _3; - let _7: u32; + let _8: u32; scope 3 { - debug z => _7; + debug z => _8; } } } @@ -36,30 +37,31 @@ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; StorageLive(_5); _5 = const 3_usize; - _6 = Lt(copy _5, const 6_usize); - assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue]; + _6 = const 6_usize; + _7 = Lt(copy _5, copy _6); + assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue]; } bb2: { _3 = copy _4[_5]; StorageDead(_5); StorageDead(_4); - StorageLive(_7); -- StorageLive(_8); -- _8 = Point { x: const 12_u32, y: const 42_u32 }; -- _7 = copy (_8.1: u32); -- StorageDead(_8); -+ StorageLive(_9); + StorageLive(_8); +- StorageLive(_9); +- _9 = Point { x: const 12_u32, y: const 42_u32 }; +- _8 = copy (_9.1: u32); +- StorageDead(_9); + StorageLive(_10); ++ StorageLive(_11); + nop; -+ _9 = const 12_u32; -+ _10 = const 42_u32; ++ _10 = const 12_u32; ++ _11 = const 42_u32; + nop; -+ _7 = copy _10; -+ StorageDead(_9); ++ _8 = copy _11; + StorageDead(_10); ++ StorageDead(_11); + nop; - StorageDead(_7); + StorageDead(_8); StorageDead(_3); StorageDead(_1); return; diff --git a/tests/mir-opt/pre-codegen/slice_index.rs b/tests/mir-opt/pre-codegen/slice_index.rs index 5dac535d195ad..574062d6c3569 100644 --- a/tests/mir-opt/pre-codegen/slice_index.rs +++ b/tests/mir-opt/pre-codegen/slice_index.rs @@ -9,7 +9,7 @@ use std::ops::Range; // EMIT_MIR slice_index.slice_index_usize.PreCodegen.after.mir pub fn slice_index_usize(slice: &[u32], index: usize) -> u32 { // CHECK-LABEL: slice_index_usize - // CHECK: [[LEN:_[0-9]+]] = PtrMetadata(copy _1) + // CHECK: [[LEN:_[0-9]+]] = Len((*_1)) // CHECK: Lt(copy _2, copy [[LEN]]) // CHECK-NOT: precondition_check // CHECK: _0 = copy (*_1)[_2]; 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 index 81e60b8ec2ca7..cc1034229fc39 100644 --- 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 @@ -8,7 +8,7 @@ fn slice_index_usize(_1: &[u32], _2: usize) -> u32 { let mut _4: bool; bb0: { - _3 = PtrMetadata(copy _1); + _3 = Len((*_1)); _4 = Lt(copy _2, copy _3); assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir index c0fdc839608da..358226fb5294d 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir @@ -8,7 +8,7 @@ fn slice_index_usize(_1: &[u32], _2: usize) -> u32 { let mut _4: bool; bb0: { - _3 = PtrMetadata(copy _1); + _3 = Len((*_1)); _4 = Lt(copy _2, copy _3); assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind continue]; } 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 index 151783969dd7a..ecac03ad0f9d9 100644 --- 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 @@ -7,19 +7,20 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _3: usize; let mut _4: usize; let mut _9: std::option::Option; - let mut _11: bool; - let mut _13: &impl Fn(usize, &T); - let mut _14: (usize, &T); - let _15: (); + let mut _11: usize; + let mut _12: bool; + let mut _14: &impl Fn(usize, &T); + let mut _15: (usize, &T); + let _16: (); scope 1 { debug ((iter: std::ops::Range).0: usize) => _4; debug ((iter: std::ops::Range).1: usize) => _3; let _10: usize; scope 2 { debug i => _10; - let _12: &T; + let _13: &T; scope 3 { - debug x => _12; + debug x => _13; } } scope 5 (inlined iter::range::>::next) { @@ -81,22 +82,23 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { StorageDead(_6); StorageDead(_7); _10 = copy ((_9 as Some).0: usize); - _11 = Lt(copy _10, copy _3); - assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind unreachable]; + _11 = Len((*_1)); + _12 = Lt(copy _10, copy _11); + assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb6, unwind unreachable]; } bb6: { - _12 = &(*_1)[_10]; - StorageLive(_13); - _13 = &_2; + _13 = &(*_1)[_10]; StorageLive(_14); - _14 = (copy _10, copy _12); - _15 = >::call(move _13, move _14) -> [return: bb7, unwind unreachable]; + _14 = &_2; + StorageLive(_15); + _15 = (copy _10, copy _13); + _16 = >::call(move _14, move _15) -> [return: bb7, unwind unreachable]; } bb7: { + StorageDead(_15); StorageDead(_14); - StorageDead(_13); StorageDead(_9); goto -> bb1; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir index 006329dc20dc9..1032473b9b2a2 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir @@ -7,19 +7,20 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _3: usize; let mut _4: usize; let mut _9: std::option::Option; - let mut _11: bool; - let mut _13: &impl Fn(usize, &T); - let mut _14: (usize, &T); - let _15: (); + let mut _11: usize; + let mut _12: bool; + let mut _14: &impl Fn(usize, &T); + let mut _15: (usize, &T); + let _16: (); scope 1 { debug ((iter: std::ops::Range).0: usize) => _4; debug ((iter: std::ops::Range).1: usize) => _3; let _10: usize; scope 2 { debug i => _10; - let _12: &T; + let _13: &T; scope 3 { - debug x => _12; + debug x => _13; } } scope 5 (inlined iter::range::>::next) { @@ -81,22 +82,23 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { StorageDead(_6); StorageDead(_7); _10 = copy ((_9 as Some).0: usize); - _11 = Lt(copy _10, copy _3); - assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind: bb8]; + _11 = Len((*_1)); + _12 = Lt(copy _10, copy _11); + assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb6, unwind: bb8]; } bb6: { - _12 = &(*_1)[_10]; - StorageLive(_13); - _13 = &_2; + _13 = &(*_1)[_10]; StorageLive(_14); - _14 = (copy _10, copy _12); - _15 = >::call(move _13, move _14) -> [return: bb7, unwind: bb8]; + _14 = &_2; + StorageLive(_15); + _15 = (copy _10, copy _13); + _16 = >::call(move _14, move _15) -> [return: bb7, unwind: bb8]; } bb7: { + StorageDead(_15); StorageDead(_14); - StorageDead(_13); StorageDead(_9); goto -> bb1; } diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.rs b/tests/ui/borrowck/borrowck-describe-lvalue.rs index f3a4b382fa89f..cdcff69d6e529 100644 --- a/tests/ui/borrowck/borrowck-describe-lvalue.rs +++ b/tests/ui/borrowck/borrowck-describe-lvalue.rs @@ -231,6 +231,7 @@ fn main() { let x = &mut v; v[0].y; //~^ ERROR cannot use `v[_].y` because it was mutably borrowed + //~| ERROR cannot use `*v` because it was mutably borrowed drop(x); } // Field of constant index diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.stderr b/tests/ui/borrowck/borrowck-describe-lvalue.stderr index 666a21808d80b..11f2e42d42b7b 100644 --- a/tests/ui/borrowck/borrowck-describe-lvalue.stderr +++ b/tests/ui/borrowck/borrowck-describe-lvalue.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-describe-lvalue.rs:253:13 + --> $DIR/borrowck-describe-lvalue.rs:254:13 | LL | let y = &mut x; | ------ first mutable borrow occurs here @@ -9,7 +9,7 @@ LL | *y = 1; | ------ first borrow later used here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-describe-lvalue.rs:263:20 + --> $DIR/borrowck-describe-lvalue.rs:264:20 | LL | let y = &mut x; | ------ first mutable borrow occurs here @@ -19,7 +19,7 @@ LL | *y = 1; | ------ first borrow later used here error: captured variable cannot escape `FnMut` closure body - --> $DIR/borrowck-describe-lvalue.rs:261:16 + --> $DIR/borrowck-describe-lvalue.rs:262:16 | LL | let mut x = 0; | ----- variable defined here @@ -300,6 +300,17 @@ LL | S { x: F { y: ref x0, .. }, .. } => LL | drop(x); | - mutable borrow later used here +error[E0503]: cannot use `*v` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:232:9 + | +LL | let x = &mut v; + | ------ `v` is borrowed here +LL | v[0].y; + | ^^^^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + error[E0503]: cannot use `v[_].y` because it was mutably borrowed --> $DIR/borrowck-describe-lvalue.rs:232:9 | @@ -307,12 +318,12 @@ LL | let x = &mut v; | ------ `v` is borrowed here LL | v[0].y; | ^^^^^^ use of borrowed `v` -LL | +... LL | drop(x); | - borrow later used here error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:242:24 + --> $DIR/borrowck-describe-lvalue.rs:243:24 | LL | let x = &mut v; | ------ mutable borrow occurs here @@ -346,7 +357,7 @@ LL | drop(x); | - mutable borrow later used here error[E0382]: use of moved value: `x` - --> $DIR/borrowck-describe-lvalue.rs:273:22 + --> $DIR/borrowck-describe-lvalue.rs:274:22 | LL | drop(x); | - value moved here @@ -355,7 +366,7 @@ LL | drop(x); | = note: move occurs because `x` has type `Vec`, which does not implement the `Copy` trait -error: aborting due to 31 previous errors +error: aborting due to 32 previous errors Some errors have detailed explanations: E0382, E0499, E0502, E0503. For more information about an error, try `rustc --explain E0382`. diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs index 2d22c9a856f6b..3abc81e191ebf 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs @@ -12,7 +12,8 @@ fn arrays_1() { // c will capture `arr` completely, therefore another index into the // array can't be modified here arr[1] += 10; - //~^ ERROR: cannot use `arr[_]` because it was mutably borrowed + //~^ ERROR: cannot use `arr` because it was mutably borrowed + //~| ERROR: cannot use `arr[_]` because it was mutably borrowed c(); } @@ -54,7 +55,8 @@ fn arrays_4() { // c will capture `arr` completely, therefore we cannot borrow another index // into the array. println!("{}", arr[3]); - //~^ ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable + //~^ ERROR: cannot use `arr` because it was mutably borrowed + //~| ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable c(); } diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr index 97ecdfab82059..9e5200ef34b54 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr @@ -1,3 +1,17 @@ +error[E0503]: cannot use `arr` because it was mutably borrowed + --> $DIR/arrays.rs:14:5 + | +LL | let mut c = || { + | -- `arr` is borrowed here +LL | arr[0] += 10; + | --- borrow occurs due to use of `arr` in closure +... +LL | arr[1] += 10; + | ^^^^^^ use of borrowed `arr` +... +LL | c(); + | - borrow later used here + error[E0503]: cannot use `arr[_]` because it was mutably borrowed --> $DIR/arrays.rs:14:5 | @@ -8,12 +22,12 @@ LL | arr[0] += 10; ... LL | arr[1] += 10; | ^^^^^^^^^^^^ use of borrowed `arr` -LL | +... LL | c(); | - borrow later used here error[E0506]: cannot assign to `arr[_]` because it is borrowed - --> $DIR/arrays.rs:28:5 + --> $DIR/arrays.rs:29:5 | LL | let c = || { | -- `arr[_]` is borrowed here @@ -27,7 +41,7 @@ LL | c(); | - borrow later used here error[E0506]: cannot assign to `arr[_]` because it is borrowed - --> $DIR/arrays.rs:42:5 + --> $DIR/arrays.rs:43:5 | LL | let c = || { | -- `arr[_]` is borrowed here @@ -40,8 +54,22 @@ LL | LL | c(); | - borrow later used here +error[E0503]: cannot use `arr` because it was mutably borrowed + --> $DIR/arrays.rs:57:20 + | +LL | let mut c = || { + | -- `arr` is borrowed here +LL | arr[1] += 10; + | --- borrow occurs due to use of `arr` in closure +... +LL | println!("{}", arr[3]); + | ^^^^^^ use of borrowed `arr` +... +LL | c(); + | - borrow later used here + error[E0502]: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable - --> $DIR/arrays.rs:56:20 + --> $DIR/arrays.rs:57:20 | LL | let mut c = || { | -- mutable borrow occurs here @@ -57,7 +85,7 @@ LL | c(); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0502]: cannot borrow `arr` as immutable because it is also borrowed as mutable - --> $DIR/arrays.rs:71:24 + --> $DIR/arrays.rs:73:24 | LL | let mut c = || { | -- mutable borrow occurs here @@ -70,7 +98,7 @@ LL | println!("{:#?}", &arr[3..2]); LL | c(); | - mutable borrow later used here -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0502, E0503, E0506. For more information about an error, try `rustc --explain E0502`. diff --git a/tests/ui/consts/issue-65348.rs b/tests/ui/consts/issue-65348.rs index 0d12da3926cd6..1443fcbe1c1ce 100644 --- a/tests/ui/consts/issue-65348.rs +++ b/tests/ui/consts/issue-65348.rs @@ -9,17 +9,15 @@ impl Generic { } pub const fn array() -> &'static T { - #[expect(unconditional_panic)] + #[allow(unconditional_panic)] &Generic::::ARRAY[0] } pub const fn newtype_array() -> &'static T { - #[expect(unconditional_panic)] &Generic::::NEWTYPE_ARRAY.0[0] } pub const fn array_field() -> &'static T { - #[expect(unconditional_panic)] &(Generic::::ARRAY_FIELD.0).1[0] } diff --git a/tests/ui/stable-mir-print/operands.stdout b/tests/ui/stable-mir-print/operands.stdout index c3b1151ae24a3..3c27878b3cf0f 100644 --- a/tests/ui/stable-mir-print/operands.stdout +++ b/tests/ui/stable-mir-print/operands.stdout @@ -5,183 +5,187 @@ fn operands(_1: u8) -> () { let _2: [u8; 10]; let _3: u8; let _4: usize; - let mut _5: bool; - let _6: u8; - let _7: usize; - let mut _8: (usize, bool); - let mut _9: bool; - let mut _10: (&u8, &u8); - let mut _11: &u8; - let mut _12: &u8; - let _13: &u8; - let _14: &u8; - let mut _15: bool; - let mut _16: u8; - let mut _17: u8; - let _18: core::panicking::AssertKind; - let _19: !; - let mut _20: Option>; - let _21: &u8; - let _22: u8; - let mut _23: (&u8, &u8); - let mut _24: &u8; - let mut _25: &u8; - let _26: &u8; - let _27: &u8; - let mut _28: bool; - let mut _29: u8; - let mut _30: u8; - let _31: core::panicking::AssertKind; - let _32: !; - let mut _33: Option>; - let _34: (u8, u8); - let _35: u8; - let _36: u8; - let mut _37: (&u8, &u8); - let mut _38: &u8; - let mut _39: &u8; - let _40: &u8; - let _41: &u8; - let mut _42: bool; - let mut _43: u8; - let mut _44: u8; - let _45: core::panicking::AssertKind; - let _46: !; - let mut _47: Option>; - let _48: usize; - let mut _49: &[u8]; - let mut _50: &[u8; 10]; - let _51: usize; - let _52: &usize; - let mut _53: (&usize, &usize); - let mut _54: &usize; - let mut _55: &usize; - let _56: &usize; - let _57: &usize; - let mut _58: bool; - let mut _59: usize; - let mut _60: usize; - let _61: core::panicking::AssertKind; - let _62: !; - let mut _63: Option>; + let mut _5: usize; + let mut _6: bool; + let _7: u8; + let _8: usize; + let mut _9: (usize, bool); + let mut _10: usize; + let mut _11: bool; + let mut _12: (&u8, &u8); + let mut _13: &u8; + let mut _14: &u8; + let _15: &u8; + let _16: &u8; + let mut _17: bool; + let mut _18: u8; + let mut _19: u8; + let _20: core::panicking::AssertKind; + let _21: !; + let mut _22: Option>; + let _23: &u8; + let _24: u8; + let mut _25: (&u8, &u8); + let mut _26: &u8; + let mut _27: &u8; + let _28: &u8; + let _29: &u8; + let mut _30: bool; + let mut _31: u8; + let mut _32: u8; + let _33: core::panicking::AssertKind; + let _34: !; + let mut _35: Option>; + let _36: (u8, u8); + let _37: u8; + let _38: u8; + let mut _39: (&u8, &u8); + let mut _40: &u8; + let mut _41: &u8; + let _42: &u8; + let _43: &u8; + let mut _44: bool; + let mut _45: u8; + let mut _46: u8; + let _47: core::panicking::AssertKind; + let _48: !; + let mut _49: Option>; + let _50: usize; + let mut _51: &[u8]; + let mut _52: &[u8; 10]; + let _53: usize; + let _54: &usize; + let mut _55: (&usize, &usize); + let mut _56: &usize; + let mut _57: &usize; + let _58: &usize; + let _59: &usize; + let mut _60: bool; + let mut _61: usize; + let mut _62: usize; + let _63: core::panicking::AssertKind; + let _64: !; + let mut _65: Option>; debug val => _1; debug array => _2; debug first => _3; - debug last => _6; - debug left_val => _13; - debug right_val => _14; - debug kind => _18; - debug reference => _21; - debug dereferenced => _22; - debug left_val => _26; - debug right_val => _27; - debug kind => _31; - debug tuple => _34; - debug first_again => _35; - debug first_again_again => _36; - debug left_val => _40; - debug right_val => _41; - debug kind => _45; - debug length => _48; - debug size_of => _51; - debug left_val => _56; - debug right_val => _57; - debug kind => _61; + debug last => _7; + debug left_val => _15; + debug right_val => _16; + debug kind => _20; + debug reference => _23; + debug dereferenced => _24; + debug left_val => _28; + debug right_val => _29; + debug kind => _33; + debug tuple => _36; + debug first_again => _37; + debug first_again_again => _38; + debug left_val => _42; + debug right_val => _43; + debug kind => _47; + debug length => _50; + debug size_of => _53; + debug left_val => _58; + debug right_val => _59; + debug kind => _63; bb0: { _2 = [_1; 10]; _4 = 0_usize; - _5 = Lt(_4, 10_usize); - assert(move _5, "index out of bounds: the length is {} but the index is {}", 10_usize, _4) -> [success: bb1, unwind unreachable]; + _5 = 10_usize; + _6 = Lt(_4, _5); + assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable]; } bb1: { _3 = _2[_4]; - _8 = CheckedSub(10_usize, 1_usize); - assert(!move (_8.1: bool), "attempt to compute `{} - {}`, which would overflow", 10_usize, 1_usize) -> [success: bb2, unwind unreachable]; + _9 = CheckedSub(10_usize, 1_usize); + assert(!move (_9.1: bool), "attempt to compute `{} - {}`, which would overflow", 10_usize, 1_usize) -> [success: bb2, unwind unreachable]; } bb2: { - _7 = move (_8.0: usize); - _9 = Lt(_7, 10_usize); - assert(move _9, "index out of bounds: the length is {} but the index is {}", 10_usize, _7) -> [success: bb3, unwind unreachable]; + _8 = move (_9.0: usize); + _10 = 10_usize; + _11 = Lt(_8, _10); + assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, _8) -> [success: bb3, unwind unreachable]; } bb3: { - _6 = _2[_7]; - _11 = &_3; - _12 = &_6; - _10 = (move _11, move _12); - _13 = (_10.0: &u8); - _14 = (_10.1: &u8); - _16 = (*_13); - _17 = (*_14); - _15 = Eq(move _16, move _17); - switchInt(move _15) -> [0: bb5, otherwise: bb4]; + _7 = _2[_8]; + _13 = &_3; + _14 = &_7; + _12 = (move _13, move _14); + _15 = (_12.0: &u8); + _16 = (_12.1: &u8); + _18 = (*_15); + _19 = (*_16); + _17 = Eq(move _18, move _19); + switchInt(move _17) -> [0: bb5, otherwise: bb4]; } bb4: { - _21 = &_3; - _22 = (*_21); - _24 = &_22; - _25 = &_3; - _23 = (move _24, move _25); - _26 = (_23.0: &u8); - _27 = (_23.1: &u8); - _29 = (*_26); - _30 = (*_27); - _28 = Eq(move _29, move _30); - switchInt(move _28) -> [0: bb7, otherwise: bb6]; + _23 = &_3; + _24 = (*_23); + _26 = &_24; + _27 = &_3; + _25 = (move _26, move _27); + _28 = (_25.0: &u8); + _29 = (_25.1: &u8); + _31 = (*_28); + _32 = (*_29); + _30 = Eq(move _31, move _32); + switchInt(move _30) -> [0: bb7, otherwise: bb6]; } bb5: { - _18 = core::panicking::AssertKind::Eq; - _20 = std::option::Option::None; - _19 = core::panicking::assert_failed::(move _18, _13, _14, move _20) -> unwind unreachable; + _20 = core::panicking::AssertKind::Eq; + _22 = std::option::Option::None; + _21 = core::panicking::assert_failed::(move _20, _15, _16, move _22) -> unwind unreachable; } bb6: { - _34 = (_3, _6); - _35 = (_34.0: u8); - _36 = (_34.0: u8); - _38 = &_35; - _39 = &_36; - _37 = (move _38, move _39); - _40 = (_37.0: &u8); - _41 = (_37.1: &u8); - _43 = (*_40); - _44 = (*_41); - _42 = Eq(move _43, move _44); - switchInt(move _42) -> [0: bb9, otherwise: bb8]; + _36 = (_3, _7); + _37 = (_36.0: u8); + _38 = (_36.0: u8); + _40 = &_37; + _41 = &_38; + _39 = (move _40, move _41); + _42 = (_39.0: &u8); + _43 = (_39.1: &u8); + _45 = (*_42); + _46 = (*_43); + _44 = Eq(move _45, move _46); + switchInt(move _44) -> [0: bb9, otherwise: bb8]; } bb7: { - _31 = core::panicking::AssertKind::Eq; - _33 = std::option::Option::None; - _32 = core::panicking::assert_failed::(move _31, _26, _27, move _33) -> unwind unreachable; + _33 = core::panicking::AssertKind::Eq; + _35 = std::option::Option::None; + _34 = core::panicking::assert_failed::(move _33, _28, _29, move _35) -> unwind unreachable; } bb8: { - _50 = &_2; - _49 = move _50 as &[u8]; - _48 = PtrMetadata(move _49); - _52 = &_48; - _51 = std::mem::size_of_val::(_52) -> [return: bb10, unwind unreachable]; + _52 = &_2; + _51 = move _52 as &[u8]; + _50 = PtrMetadata(move _51); + _54 = &_50; + _53 = std::mem::size_of_val::(_54) -> [return: bb10, unwind unreachable]; } bb9: { - _45 = core::panicking::AssertKind::Eq; - _47 = std::option::Option::None; - _46 = core::panicking::assert_failed::(move _45, _40, _41, move _47) -> unwind unreachable; + _47 = core::panicking::AssertKind::Eq; + _49 = std::option::Option::None; + _48 = core::panicking::assert_failed::(move _47, _42, _43, move _49) -> unwind unreachable; } bb10: { - _54 = &_48; - _55 = &_51; - _53 = (move _54, move _55); - _56 = (_53.0: &usize); - _57 = (_53.1: &usize); - _59 = (*_56); - _60 = (*_57); - _58 = Eq(move _59, move _60); - switchInt(move _58) -> [0: bb12, otherwise: bb11]; + _56 = &_50; + _57 = &_53; + _55 = (move _56, move _57); + _58 = (_55.0: &usize); + _59 = (_55.1: &usize); + _61 = (*_58); + _62 = (*_59); + _60 = Eq(move _61, move _62); + switchInt(move _60) -> [0: bb12, otherwise: bb11]; } bb11: { return; } bb12: { - _61 = core::panicking::AssertKind::Eq; - _63 = std::option::Option::None; - _62 = core::panicking::assert_failed::(move _61, _56, _57, move _63) -> unwind unreachable; + _63 = core::panicking::AssertKind::Eq; + _65 = std::option::Option::None; + _64 = core::panicking::assert_failed::(move _63, _58, _59, move _65) -> unwind unreachable; } } fn operands::{constant#0}() -> usize { From 0ca702d36f6d0084e3bd59f971d1611d105be4af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 18 Jan 2025 21:45:29 +0000 Subject: [PATCH 11/14] add tests for issue 135671 (cherry picked from commit c69dea90d70212bb430f183df62edc09c8c8a89f) --- .../array-disjoint-borrows-issue-135671.rs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs diff --git a/tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs b/tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs new file mode 100644 index 0000000000000..74b5cfcfb04de --- /dev/null +++ b/tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs @@ -0,0 +1,30 @@ +// This is a regression test for issue #135671 where a MIR refactor about arrays and their lengths +// unexpectedly caused borrowck errors for disjoint borrows of array elements, for which we had no +// tests. This is a collection of a few code samples from that issue. + +//@ check-pass + +struct Test { + a: i32, + b: i32, +} + +fn one() { + let inputs: &mut [_] = &mut [Test { a: 0, b: 0 }]; + let a = &mut inputs[0].a; + let b = &mut inputs[0].b; + + *a = 0; + *b = 1; +} + +fn two() { + let slice = &mut [(0, 0)][..]; + std::mem::swap(&mut slice[0].0, &mut slice[0].1); +} + +fn three(a: &mut [(i32, i32)], i: usize, j: usize) -> (&mut i32, &mut i32) { + (&mut a[i].0, &mut a[j].1) +} + +fn main() {} From 4dffd4d120f6a9385fb572f09b6260b24319e61a Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 19 Jan 2025 12:50:49 +0300 Subject: [PATCH 12/14] make it possible to use ci-rustc on tarball sources Previously, bootstrap was using `Config::last_modified_commit` unconditionally to figure the commit has to download precompiled rustc artifact from CI, which was leading builds to fail on tarball sources as `Config::last_modified_commit` requires `git` to be present in the project source. This change makes bootstrap to call `Config::last_modified_commit` only when it's running on git-managed source and read `git-commit-hash` file otherwise. Signed-off-by: onur-ozkan (cherry picked from commit 903cddb392bc9a5bc43194bcbb8b031f2fcc2c56) --- src/bootstrap/src/core/config/config.rs | 36 ++++++++++++++++--------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 928e9746410d2..0587408e987ef 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2863,21 +2863,26 @@ impl Config { allowed_paths.push(":!library"); } - // Look for a version to compare to based on the current commit. - // Only commits merged by bors will have CI artifacts. - let commit = match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged) - { - Some(commit) => commit, - None => { - if if_unchanged { - return None; + let commit = if self.rust_info.is_managed_git_subrepository() { + // Look for a version to compare to based on the current commit. + // Only commits merged by bors will have CI artifacts. + match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged) { + Some(commit) => commit, + None => { + if if_unchanged { + return None; + } + println!("ERROR: could not find commit hash for downloading rustc"); + println!("HELP: maybe your repository history is too shallow?"); + println!("HELP: consider setting `rust.download-rustc=false` in config.toml"); + println!("HELP: or fetch enough history to include one upstream commit"); + crate::exit!(1); } - println!("ERROR: could not find commit hash for downloading rustc"); - println!("HELP: maybe your repository history is too shallow?"); - println!("HELP: consider setting `rust.download-rustc=false` in config.toml"); - println!("HELP: or fetch enough history to include one upstream commit"); - crate::exit!(1); } + } else { + channel::read_commit_info_file(&self.src) + .map(|info| info.sha.trim().to_owned()) + .expect("git-commit-info is missing in the project root") }; if CiEnv::is_ci() && { @@ -2957,6 +2962,11 @@ impl Config { option_name: &str, if_unchanged: bool, ) -> Option { + assert!( + self.rust_info.is_managed_git_subrepository(), + "Can't run `Config::last_modified_commit` on a non-git source." + ); + // Look for a version to compare to based on the current commit. // Only commits merged by bors will have CI artifacts. let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap(); From 00cf039d0054ddef56a14f8d9e58be5eb45db607 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 21 Jan 2025 17:27:24 +0000 Subject: [PATCH 13/14] Remove test panic from File::open (cherry picked from commit fed5f98c47e64bc5e96679165d16e5eec8b4917e) --- library/std/src/sys/pal/windows/fs.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index b3659351b8c11..f8493c21ad444 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -328,9 +328,6 @@ impl File { mem::size_of::() as u32, ); if result == 0 { - if api::get_last_error().code != 0 { - panic!("FILE_ALLOCATION_INFO failed!!!"); - } let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 }; let result = c::SetFileInformationByHandle( handle.as_raw_handle(), From 17a1a4f96aedc5b105d61aad1577aa1d19c7cd2e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 21 Jan 2025 17:24:29 -0800 Subject: [PATCH 14/14] Only assert the `Parser` size on specific arches The size of this struct depends on the alignment of `u128`, for example powerpc64le and s390x have align-8 and end up with only 280 bytes. Our 64-bit tier-1 arches are the same though, so let's just assert on those. (cherry picked from commit aef640a6130ccb3edf9bc720881c3a9dde3c0ecd) --- compiler/rustc_parse/src/parser/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 2637ea268c85b..30871db10a42f 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -189,8 +189,9 @@ pub struct Parser<'a> { } // This type is used a lot, e.g. it's cloned when matching many declarative macro rules with -// nonterminals. Make sure it doesn't unintentionally get bigger. -#[cfg(all(target_pointer_width = "64", not(target_arch = "s390x")))] +// nonterminals. Make sure it doesn't unintentionally get bigger. We only check a few arches +// though, because `TokenTypeSet(u128)` alignment varies on others, changing the total size. +#[cfg(all(target_pointer_width = "64", any(target_arch = "aarch64", target_arch = "x86_64")))] rustc_data_structures::static_assert_size!(Parser<'_>, 288); /// Stores span information about a closure.