From 887965ddb9cbd9d40ee20a7136cca18c28ac98a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 7 Jan 2025 22:06:58 +0000 Subject: [PATCH 01/11] Ensure that we don't try to access fields on a non-struct pattern type in diagnostic Fix #135209. (cherry picked from commit 5f04f98c9aaf04e5f670e04dc12d4665489859fd) --- .../rustc_resolve/src/late/diagnostics.rs | 4 ++- ...uct-pattern-on-non-struct-resolve-error.rs | 7 +++++ ...pattern-on-non-struct-resolve-error.stderr | 28 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs create mode 100644 tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 6ee02e9f47f15..3957a057fdbce 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1130,7 +1130,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let None = following_seg else { return }; for rib in self.ribs[ValueNS].iter().rev() { for (def_id, spans) in &rib.patterns_with_skipped_bindings { - if let Some(fields) = self.r.field_idents(*def_id) { + if let DefKind::Struct = self.r.tcx.def_kind(*def_id) + && let Some(fields) = self.r.field_idents(*def_id) + { for field in fields { if field.name == segment.ident.name { if spans.iter().all(|(_, had_error)| had_error.is_err()) { diff --git a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs new file mode 100644 index 0000000000000..c74c77fea60f4 --- /dev/null +++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs @@ -0,0 +1,7 @@ +// Regression test for #135209. +// We ensure that we don't try to access fields on a non-struct pattern type. +fn main() { + if let Iterator::Item { .. } = 1 { //~ ERROR E0223 + x //~ ERROR E0425 + } +} diff --git a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr new file mode 100644 index 0000000000000..e31b19ab6bcbf --- /dev/null +++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr @@ -0,0 +1,28 @@ +error[E0425]: cannot find value `x` in this scope + --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:5:9 + | +LL | x + | ^ not found in this scope + +error[E0223]: ambiguous associated type + --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12 + | +LL | if let Iterator::Item { .. } = 1 { + | ^^^^^^^^^^^^^^ + | +help: use fully-qualified syntax + | +LL | if let as Iterator>::Item { .. } = 1 { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | if let ::Item { .. } = 1 { + | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL | if let ::Item { .. } = 1 { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | if let as Iterator>::Item { .. } = 1 { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + and 71 other candidates + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0223, E0425. +For more information about an error, try `rustc --explain E0223`. From e98d52408c908d52bc3466d1b59d167a9463512a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 8 Jan 2025 00:10:16 +0000 Subject: [PATCH 02/11] Add check for missing fields in enum variant pattern (cherry picked from commit d44f021904e3d5b2870e3c835cbad5e1421e83ec) --- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- ...ct-pattern-with-missing-fields-resolve-error.rs | 9 +++++++++ ...attern-with-missing-fields-resolve-error.stderr | 14 +++++++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3957a057fdbce..d15eca6927010 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1130,7 +1130,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let None = following_seg else { return }; for rib in self.ribs[ValueNS].iter().rev() { for (def_id, spans) in &rib.patterns_with_skipped_bindings { - if let DefKind::Struct = self.r.tcx.def_kind(*def_id) + if let DefKind::Struct | DefKind::Variant = self.r.tcx.def_kind(*def_id) && let Some(fields) = self.r.field_idents(*def_id) { for field in fields { diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs index 225891e390ff5..39f9f5a2c0208 100644 --- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs +++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs @@ -3,6 +3,10 @@ struct Website { title: Option, } +enum Foo { + Bar { a: i32 }, +} + fn main() { let website = Website { url: "http://www.example.com".into(), @@ -18,4 +22,9 @@ fn main() { println!("[{}]({})", title, url); //~ ERROR cannot find value `title` in this scope //~^ NOTE not found in this scope } + + let x = Foo::Bar { a: 1 }; + if let Foo::Bar { .. } = x { //~ NOTE this pattern + println!("{a}"); //~ ERROR cannot find value `a` in this scope + } } diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr index 80fcd714400d6..b985b771754ee 100644 --- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr +++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr @@ -1,5 +1,5 @@ error: expected `,` - --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:12:31 + --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:16:31 | LL | if let Website { url, Some(title) } = website { | ------- ^ @@ -7,13 +7,21 @@ LL | if let Website { url, Some(title) } = website { | while parsing the fields for this pattern error[E0425]: cannot find value `title` in this scope - --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:18:30 + --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:22:30 | LL | if let Website { url, .. } = website { | ------------------- this pattern doesn't include `title`, which is available in `Website` LL | println!("[{}]({})", title, url); | ^^^^^ not found in this scope -error: aborting due to 2 previous errors +error[E0425]: cannot find value `a` in this scope + --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:28:20 + | +LL | if let Foo::Bar { .. } = x { + | --------------- this pattern doesn't include `a`, which is available in `Bar` +LL | println!("{a}"); + | ^ help: a local variable with a similar name exists: `x` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0425`. From f264675a806800e568df09eefd0b7efda80e961b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 8 Jan 2025 00:13:43 +0000 Subject: [PATCH 03/11] modify test to side-step platform-dependent stderr output (cherry picked from commit 592f2c90da6a6e1b25b3b9c2f13a2e0cfb83dcfc) --- ...uct-pattern-on-non-struct-resolve-error.rs | 5 ++- ...pattern-on-non-struct-resolve-error.stderr | 40 +++++++++++-------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs index c74c77fea60f4..17a5bad0e6c0f 100644 --- a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs +++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs @@ -1,7 +1,10 @@ // Regression test for #135209. // We ensure that we don't try to access fields on a non-struct pattern type. fn main() { - if let Iterator::Item { .. } = 1 { //~ ERROR E0223 + if let as Iterator>::Item { .. } = 1 { + //~^ ERROR E0658 + //~| ERROR E0071 + //~| ERROR E0277 x //~ ERROR E0425 } } diff --git a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr index e31b19ab6bcbf..793c2d1e97fc0 100644 --- a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr +++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr @@ -1,28 +1,34 @@ error[E0425]: cannot find value `x` in this scope - --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:5:9 + --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:8:9 | LL | x | ^ not found in this scope -error[E0223]: ambiguous associated type +error[E0658]: usage of qualified paths in this context is experimental --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12 | -LL | if let Iterator::Item { .. } = 1 { - | ^^^^^^^^^^^^^^ +LL | if let as Iterator>::Item { .. } = 1 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: use fully-qualified syntax + = note: see issue #86935 for more information + = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0071]: expected struct, variant or union type, found inferred type + --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12 + | +LL | if let as Iterator>::Item { .. } = 1 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a struct + +error[E0277]: `Vec<()>` is not an iterator + --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12 + | +LL | if let as Iterator>::Item { .. } = 1 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Vec<()>` is not an iterator | -LL | if let as Iterator>::Item { .. } = 1 { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LL | if let ::Item { .. } = 1 { - | ~~~~~~~~~~~~~~~~~~~~~~~~ -LL | if let ::Item { .. } = 1 { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ -LL | if let as Iterator>::Item { .. } = 1 { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - and 71 other candidates + = help: the trait `Iterator` is not implemented for `Vec<()>` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0223, E0425. -For more information about an error, try `rustc --explain E0223`. +Some errors have detailed explanations: E0071, E0277, E0425, E0658. +For more information about an error, try `rustc --explain E0071`. From 13c3f9b9498013837782b46120085ea19ca75518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 17 Jan 2025 23:01:48 +0100 Subject: [PATCH 04/11] Do not include GCC source code in source tarballs The licensing story is unclear, it makes the archive much larger, and we should not need it for building anything in the tarballs (yet). (cherry picked from commit f854f34a502c358b0f6826ea3ebf40fb7f146de1) --- src/bootstrap/src/core/build_steps/dist.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index aa664998f979e..34e6a1e1d35fb 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -995,7 +995,18 @@ impl Step for PlainSourceTarball { ]; let src_dirs = ["src", "compiler", "library", "tests"]; - copy_src_dirs(builder, &builder.src, &src_dirs, &[], plain_dst_src); + copy_src_dirs( + builder, + &builder.src, + &src_dirs, + &[ + // We don't currently use the GCC source code for building any official components, + // it is very big, and has unclear licensing implications due to being GPL licensed. + // We thus exclude it from the source tarball from now. + "src/gcc", + ], + plain_dst_src, + ); // Copy the files normally for item in &src_files { From 7302b302d08e3d884d75a688a5a38c53be78bd87 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 05/11] 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 c6063d45b7f9a4a4c33dd5f832b464b468ca32a1 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 06/11] 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 197b416baf683a01f98cf31fce706943e30a6b3c 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 07/11] 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 940548094b669fa05ed1a3015945cc567790d9f4 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 08/11] 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 741fa9e39f5eb0e70fbb08176602c30538e404d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 31 Jan 2025 13:05:10 +0100 Subject: [PATCH 09/11] ensure sufficient stack in tail call check (cherry picked from commit 2c778c1e4ca8053e787998c9b18bb57222719a3d) --- compiler/rustc_mir_build/src/check_tail_calls.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index 0659e3ea314bb..921205428dbd4 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -1,4 +1,5 @@ use rustc_abi::ExternAbi; +use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::Applicability; use rustc_hir::LangItem; use rustc_hir::def::DefKind; @@ -344,12 +345,14 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for TailCallCkVisitor<'a, 'tcx> { } fn visit_expr(&mut self, expr: &'a Expr<'tcx>) { - if let ExprKind::Become { value } = expr.kind { - let call = &self.thir[value]; - self.check_tail_call(call, expr); - } + ensure_sufficient_stack(|| { + if let ExprKind::Become { value } = expr.kind { + let call = &self.thir[value]; + self.check_tail_call(call, expr); + } - visit::walk_expr(self, expr); + visit::walk_expr(self, expr); + }); } } From 01283c450e2297cda35ea763b64064170985d4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 31 Jan 2025 13:05:38 +0100 Subject: [PATCH 10/11] ensure sufficient stack in unsafety check (cherry picked from commit 94562ee1eae83d6cc80bda4d57b43bcdb7a842b5) --- compiler/rustc_mir_build/src/check_unsafety.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index f7071eb139f35..967e523a49c36 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::mem; use std::ops::Bound; +use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::DiagArgValue; use rustc_hir::def::DefKind; use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability}; @@ -473,7 +474,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { ExprKind::Scope { value, lint_level: LintLevel::Explicit(hir_id), region_scope: _ } => { let prev_id = self.hir_context; self.hir_context = hir_id; - self.visit_expr(&self.thir[value]); + ensure_sufficient_stack(|| { + self.visit_expr(&self.thir[value]); + }); self.hir_context = prev_id; return; // don't visit the whole expression } From bf24cade3ef2aae66a5047f762d66b70d2b4b92f Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 22 Jan 2025 14:07:43 -0800 Subject: [PATCH 11/11] Enable kernel sanitizers for aarch64-unknown-none-softfloat We want kernels to be able to use this bare metal target, so let's enable the sanitizers that kernels want to use. (cherry picked from commit 6b06aa619297c198e923e1d406a5bb0534260fef) --- .../src/spec/targets/aarch64_unknown_none_softfloat.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs index d6b77ffd091a9..3b719ebaf07e8 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs @@ -7,7 +7,8 @@ // For example, `-C target-cpu=cortex-a53`. use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, StackProbeType, Target, TargetOptions, + Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -19,6 +20,7 @@ pub(crate) fn target() -> Target { relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128), + supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS, stack_probes: StackProbeType::Inline, panic_strategy: PanicStrategy::Abort, ..Default::default()