diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index c8abc2689ff7f..047f85b35d653 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -543,7 +543,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { // we'll use this to check whether it was originally from an overloaded // operator. match self.move_data.rev_lookup.find(deref_base) { - LookupResult::Exact(mpi) | LookupResult::Parent(Some(mpi)) => { + LookupResult::Exact(mpi) | LookupResult::Parent { mpi, .. } => { debug!("borrowed_content_source: mpi={:?}", mpi); for i in &self.move_data.init_path_map[mpi] { @@ -580,7 +580,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { } } // Base is a `static` so won't be from an overloaded operator - _ => (), + LookupResult::None => (), }; // If we didn't find an overloaded deref or index, then assume it's a diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index aa62d6aaa0751..0e4d963374845 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -188,7 +188,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { match self.move_data.rev_lookup.find(match_place.as_ref()) { // Error with the match place - LookupResult::Parent(_) => { + LookupResult::Parent { .. } | LookupResult::None => { for ge in &mut *grouped_errors { if let GroupedMoveError::MovesFromPlace { span, binds_to, .. } = ge && match_span == *span @@ -218,7 +218,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { } // Error with the pattern LookupResult::Exact(_) => { - let LookupResult::Parent(Some(mpi)) = + let LookupResult::Parent { mpi, .. } = self.move_data.rev_lookup.find(move_from.as_ref()) else { // move_from should be a projection from match_place. diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index f3667ac63de30..d9dfb6f9bdebc 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2075,15 +2075,42 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { // This code covers scenarios 1, 2, and 3. debug!("check_if_full_path_is_moved place: {:?}", place_span.0); - let (prefix, mpi) = self.move_path_closest_to(place_span.0); - if maybe_uninits.contains(mpi) { + + let uninit_mpi = match self.move_data.rev_lookup.find(place_span.0) { + // Index projections arbitrarily overlap sibling move paths, so we need to check all descendents of the parent + // Subslice and ConstantIndex projections of slices also overlap siblings, + // but the parent slice will never have a move path + // Subslice projections of arrays are specifically checked in `check_if_subslice_element_is_moved` + LookupResult::Parent { mpi, next_elem: ProjectionKind::Index(..) } => self + .move_data + .find_in_move_path_or_its_descendants(mpi, |mpi| maybe_uninits.contains(mpi)), + + LookupResult::Exact(mpi) + | LookupResult::Parent { + mpi, + next_elem: + ProjectionKind::Deref + | ProjectionKind::Field(..) + | ProjectionKind::ConstantIndex { .. } + | ProjectionKind::Subslice { .. } + | ProjectionKind::Downcast(..) + | ProjectionKind::OpaqueCast(..) + | ProjectionKind::UnwrapUnsafeBinder(..), + } => maybe_uninits.contains(mpi).then_some(mpi), + + LookupResult::None => bug!("should have move path for every Local"), + }; + + if let Some(mpi) = uninit_mpi { self.report_use_of_moved_or_uninitialized( location, desired_action, - (prefix, place_span.0, place_span.1), + (self.move_data.move_paths[mpi].place.as_ref(), place_span.0, place_span.1), mpi, ); - } // Only query longest prefix with a MovePath, not further + } + + // Only query longest prefix with a MovePath, not further // ancestors; dataflow recurs on children when parents // move (to support partial (re)inits). // @@ -2205,32 +2232,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { } } - /// Currently MoveData does not store entries for all places in - /// the input MIR. For example it will currently filter out - /// places that are Copy; thus we do not track places of shared - /// reference type. This routine will walk up a place along its - /// prefixes, searching for a foundational place that *is* - /// tracked in the MoveData. - /// - /// An Err result includes a tag indicated why the search failed. - /// Currently this can only occur if the place is built off of a - /// static variable, as we do not track those in the MoveData. - fn move_path_closest_to(&mut self, place: PlaceRef<'tcx>) -> (PlaceRef<'tcx>, MovePathIndex) { - match self.move_data.rev_lookup.find(place) { - LookupResult::Parent(Some(mpi)) | LookupResult::Exact(mpi) => { - (self.move_data.move_paths[mpi].place.as_ref(), mpi) - } - LookupResult::Parent(None) => panic!("should have move path for every Local"), - } - } - fn move_path_for_place(&mut self, place: PlaceRef<'tcx>) -> Option { // If returns None, then there is no move path corresponding // to a direct owner of `place` (which means there is nothing // that borrowck tracks for its analysis). match self.move_data.rev_lookup.find(place) { - LookupResult::Parent(_) => None, + LookupResult::Parent { .. } | LookupResult::None => None, LookupResult::Exact(mpi) => Some(mpi), } } diff --git a/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs b/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs index dc174775af2e5..49858232b3563 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs @@ -67,7 +67,7 @@ impl<'a, 'tcx> Visitor<'tcx> for AccessFactsExtractor<'a, 'tcx> { match context { PlaceContext::NonMutatingUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Borrow) => { - let (LookupResult::Exact(path) | LookupResult::Parent(Some(path))) = + let (LookupResult::Exact(path) | LookupResult::Parent { mpi: path, .. }) = self.move_data.rev_lookup.find(place.as_ref()) else { // There's no path access to emit. diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 9e37205f230ac..b26798219a5fb 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -127,7 +127,7 @@ unsafe fn configure_llvm(sess: &EarlySession) { } } - if wants_wasm_eh(&sess.target) { + if get_version() < (24, 0, 0) && wants_wasm_eh(&sess.target) { add("-wasm-enable-eh", false); } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 01549c3e3fd53..243ad73e3dfb8 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2190,7 +2190,7 @@ impl<'tcx> Ty<'tcx> { def.flags().contains(AdtFlags::IS_MAYBE_DANGLING) || def.flags().contains(AdtFlags::IS_MANUALLY_DROP) } - ty::Coroutine(..) | ty::CoroutineClosure(..) => true, + ty::Coroutine(..) => true, _ => false, } } diff --git a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs index 7d7491dd643b0..262992e817b35 100644 --- a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs +++ b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs @@ -55,7 +55,7 @@ pub fn on_lookup_result_bits<'tcx, F>( F: FnMut(MovePathIndex), { match lookup_result { - LookupResult::Parent(..) => { + LookupResult::Parent { .. } | LookupResult::None => { // access to untracked value - do not touch children } LookupResult::Exact(e) => on_all_children_bits(move_data, e, each_child), diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index b6565588ae3f1..5c111d722a990 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -344,11 +344,18 @@ pub enum LookupResult { /// This exact thing has a move path. E.g. we looked up `x` or `x.m` and it has been moved. Exact(MovePathIndex), - /// - If the field is `None`, neither the exact thing nor any ancestor of it has a move path. - /// E.g. we looked up `x.m` and neither it nor `x` have a move path. - /// - If the field is `Some`, the exact thing has no move path, but an ancestor does. E.g. we - /// looked up `x.m` which has no move path but `x` has one. Not possible for locals. - Parent(Option), + /// The exact thing has no move path, but an ancestor does. + /// E.g. we looked up `x.m` which has no move path but `x` has one. Not possible for locals. + Parent { + mpi: MovePathIndex, + + /// The projection in the place immediately projecting from the parent move path. + next_elem: ProjectionKind, + }, + + /// Neither the exact thing nor any ancestor of it has a move path. + /// E.g. we looked up `x.m` and neither it nor `x` have a move path. + None, } impl<'tcx> MovePathLookup<'tcx> { @@ -359,7 +366,7 @@ impl<'tcx> MovePathLookup<'tcx> { pub fn find(&self, place: PlaceRef<'tcx>) -> LookupResult { // Look first in the locals (roots). let Some(mut result) = self.find_local(place.local) else { - return LookupResult::Parent(None); + return LookupResult::None; }; // Look for a projection through the found local. @@ -372,7 +379,7 @@ impl<'tcx> MovePathLookup<'tcx> { }; let Some(&subpath) = subpath else { - return LookupResult::Parent(Some(result)); + return LookupResult::Parent { mpi: result, next_elem: elem.kind() }; }; result = subpath; } diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index 0e14d1f830492..f59aba3b30463 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -223,7 +223,7 @@ where } } - LookupResult::Parent(..) => { + LookupResult::Parent { .. } | LookupResult::None => { tcx.dcx().emit_err(PeekArgumentUntracked { span: call.span }); } } diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index a19ae86542d25..87193c580fabe 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -314,8 +314,8 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { } }); } - LookupResult::Parent(None) => {} - LookupResult::Parent(Some(parent)) => { + LookupResult::None => {} + LookupResult::Parent { mpi: parent, .. } => { if self.body.local_decls[place.local].is_deref_temp() { continue; } @@ -387,8 +387,8 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { drop, ) } - LookupResult::Parent(None) => {} - LookupResult::Parent(Some(_)) => { + LookupResult::None => {} + LookupResult::Parent { .. } => { if !replace { self.tcx.dcx().span_bug( terminator.source_info.span, diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 7e91890a08cc2..44f297622dde9 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -75,7 +75,7 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> { } MovePathIndexAtBlock::Unknown => { if let TerminatorKind::Drop { place, .. } = &terminator.kind - && let LookupResult::Exact(idx) | LookupResult::Parent(Some(idx)) = + && let LookupResult::Exact(idx) | LookupResult::Parent { mpi: idx, .. } = self.move_data.rev_lookup.find(place.as_ref()) { // Since we are working with MIRs at a very early stage, observing a `drop` diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index daa816c276482..aac244ad6cf22 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -136,7 +136,7 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> { ast::UseTreeKind::Simple(Some(ident)) => { if ident.name == kw::Underscore && !matches!( - self.r.current_owner.import_res[&id].type_ns, + self.r.current_owner.import_res.get(&id).and_then(|res| res.type_ns), Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) ) { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7ee6eec3e1c44..484e0b3b428a2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -3082,16 +3082,16 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> { /// Invoked when the node with dfn `dfn` does not get a successful /// result. This will clear out any provisional cache entries - /// that were added since `dfn` was created. This is because the - /// provisional entries are things which must assume that the - /// things on the stack at the time of their creation succeeded -- - /// since the failing node is presently at the top of the stack, - /// these provisional entries must either depend on it or some - /// ancestor of it. + /// originating from nodes visited before this node (`from_dfn < dfn`). + /// This is because the provisional entries are things which must + /// assume that the things on the stack at the time of their creation + /// succeeded -- since the failing node is presently at the top of + /// the stack, these provisional entries must either depend on it or + /// some ancestor of it. fn on_failure(&self, dfn: usize) { debug!(?dfn, "on_failure"); self.map.borrow_mut().retain(|key, eval| { - if !eval.from_dfn >= dfn { + if eval.from_dfn < dfn { debug!("on_failure: removing {:?}", key); false } else { diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 68a1b479830e2..35f8897afd4c4 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -259,7 +259,9 @@ pub enum TyKind { /// `ClosureArgs` for more details. Closure(I::ClosureId, I::GenericArgs), - /// The anonymous type of a closure. Used to represent the type of `async |a| a`. + /// The anonymous type of an async closure. Used to represent the type of `async |a| a`. + /// + /// This type itself is not a coroutine, it just represents a closure that returns one. /// /// Coroutine-closure args contain both the - potentially instantiated - generic /// parameters of its parent and some synthetic parameters. See the documentation diff --git a/tests/assembly-llvm/simd-intrinsic-select.rs b/tests/assembly-llvm/simd-intrinsic-select.rs index ca942f82ba5a3..073372b9deb7a 100644 --- a/tests/assembly-llvm/simd-intrinsic-select.rs +++ b/tests/assembly-llvm/simd-intrinsic-select.rs @@ -1,11 +1,17 @@ +// ignore-tidy-file-linelength //@ add-minicore -//@ revisions: x86-avx2 x86-avx512 aarch64 +//@ revisions: x86-avx2 x86-avx-512-llvm23 x86-avx-512 aarch64 //@ [x86-avx2] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel //@ [x86-avx2] compile-flags: -C target-feature=+avx2 //@ [x86-avx2] needs-llvm-components: x86 -//@ [x86-avx512] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel -//@ [x86-avx512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq -//@ [x86-avx512] needs-llvm-components: x86 +//@ [x86-avx-512-llvm23] max-llvm-major-version: 23 +//@ [x86-avx-512-llvm23] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel +//@ [x86-avx-512-llvm23] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq +//@ [x86-avx-512-llvm23] needs-llvm-components: x86 +//@ [x86-avx-512] min-llvm-version: 24 +//@ [x86-avx-512] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel +//@ [x86-avx-512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq +//@ [x86-avx-512] needs-llvm-components: x86 //@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu //@ [aarch64] needs-llvm-components: aarch64 //@ assembly-output: emit-asm @@ -34,9 +40,13 @@ pub unsafe extern "C" fn select_i8x16(mask: m8x16, a: i8x16, b: i8x16) -> i8x16 // x86-avx2-NOT: vpsllw // x86-avx2: vpblendvb xmm0, xmm2, xmm1, xmm0 // - // x86-avx512-NOT: vpsllw - // x86-avx512: vpmovb2m k1, xmm0 - // x86-avx512-NEXT: vpblendmb xmm0 {k1}, xmm2, xmm1 + // x86-avx-512-llvm23-NOT: vpsllw + // x86-avx-512-llvm23: vpmovb2m k1, xmm0 + // x86-avx-512-llvm23-NEXT: vpblendmb xmm0 {k1}, xmm2, xmm1 + // + // x86-avx-512-NOT: vpsllw + // x86-avx-512: vpmovb2m k1, xmm0 + // x86-avx-512-NEXT: vpblendmb xmm0 {k1}, xmm2, xmm1 // // aarch64-NOT: shl // aarch64: cmlt v0.16b, v0.16b, #0 @@ -50,9 +60,12 @@ pub unsafe extern "C" fn select_f32x4(mask: m32x4, a: f32x4, b: f32x4) -> f32x4 // x86-avx2-NOT: vpslld // x86-avx2: vblendvps xmm0, xmm2, xmm1, xmm0 // - // x86-avx512-NOT: vpslld - // x86-avx512: vpmovd2m k1, xmm0 - // x86-avx512-NEXT: vblendmps xmm0 {k1}, xmm2, xmm1 + // x86-avx-512-llvm23-NOT: vpslld + // x86-avx-512-llvm23: vpmovd2m k1, xmm0 + // x86-avx-512-llvm23-NEXT: vblendmps xmm0 {k1}, xmm2, xmm1 + // + // x86-avx-512-NOT: vpslld + // x86-avx-512: vblendvps xmm0, xmm2, xmm1, xmm0 // // aarch64-NOT: shl // aarch64: cmlt v0.4s, v0.4s, #0 @@ -66,9 +79,12 @@ pub unsafe extern "C" fn select_f64x2(mask: m64x2, a: f64x2, b: f64x2) -> f64x2 // x86-avx2-NOT: vpsllq // x86-avx2: vblendvpd xmm0, xmm2, xmm1, xmm0 // - // x86-avx512-NOT: vpsllq - // x86-avx512: vpmovq2m k1, xmm0 - // x86-avx512-NEXT: vblendmpd xmm0 {k1}, xmm2, xmm1 + // x86-avx-512-llvm23-NOT: vpsllq + // x86-avx-512-llvm23: vpmovq2m k1, xmm0 + // x86-avx-512-llvm23-NEXT: vblendmpd xmm0 {k1}, xmm2, xmm1 + // + // x86-avx-512-NOT: vpsllq + // x86-avx-512: vblendvpd xmm0, xmm2, xmm1, xmm0 // // aarch64-NOT: shl // aarch64: cmlt v0.2d, v0.2d, #0 @@ -77,29 +93,38 @@ pub unsafe extern "C" fn select_f64x2(mask: m64x2, a: f64x2, b: f64x2) -> f64x2 } // x86-avx2-LABEL: select_f64x4 -// x86-avx512-LABEL: select_f64x4 +// x86-avx-512-llvm23-LABEL: select_f64x4 +// x86-avx-512-LABEL: select_f64x4 #[no_mangle] -#[cfg(any(x86_avx2, x86_avx512))] +#[cfg(any(x86_avx2, x86_avx_512, x86_avx_512_llvm23))] pub unsafe extern "C" fn select_f64x4(mask: m64x4, a: f64x4, b: f64x4) -> f64x4 { // The parameter is a 256 bit vector which in the C abi is only valid for avx targets. // // x86-avx2-NOT: vpsllq // x86-avx2: vblendvpd ymm0, ymm2, ymm1, ymm0 // - // x86-avx512-NOT: vpsllq - // x86-avx512: vpmovq2m k1, ymm0 - // x86-avx512-NEXT: vblendmpd ymm0 {k1}, ymm2, ymm1 + // x86-avx-512-llvm23-NOT: vpsllq + // x86-avx-512-llvm23: vpmovq2m k1, ymm0 + // x86-avx-512-llvm23-NEXT: vblendmpd ymm0 {k1}, ymm2, ymm1 + // + // x86-avx-512-NOT: vpsllq + // x86-avx-512: vblendvpd ymm0, ymm2, ymm1, ymm0 simd_select(mask, a, b) } -// x86-avx512-LABEL: select_f64x8 +// x86-avx-512-llvm23-LABEL: select_f64x8 +// x86-avx-512-LABEL: select_f64x8 #[no_mangle] -#[cfg(x86_avx512)] +#[cfg(any(x86_avx_512, x86_avx_512_llvm23))] pub unsafe extern "C" fn select_f64x8(mask: m64x8, a: f64x8, b: f64x8) -> f64x8 { // The parameter is a 256 bit vector which in the C abi is only valid for avx512 targets. // - // x86-avx512-NOT: vpsllq - // x86-avx512: vpmovq2m k1, zmm0 - // x86-avx512-NEXT: vblendmpd zmm0 {k1}, zmm2, zmm1 + // x86-avx-512-llvm23-NOT: vpsllq + // x86-avx-512-llvm23: vpmovq2m k1, zmm0 + // x86-avx-512-llvm23-NEXT: vblendmpd zmm0 {k1}, zmm2, zmm1 + // + // x86-avx-512-NOT: vpsllq + // x86-avx-512: vpmovq2m k1, zmm0 + // x86-avx-512-NEXT: vblendmpd zmm0 {k1}, zmm2, zmm1 simd_select(mask, a, b) } diff --git a/tests/run-make/wasm-exceptions-nostd/rmake.rs b/tests/run-make/wasm-exceptions-nostd/rmake.rs index e43d6bcd02b80..87eb5d501da44 100644 --- a/tests/run-make/wasm-exceptions-nostd/rmake.rs +++ b/tests/run-make/wasm-exceptions-nostd/rmake.rs @@ -10,7 +10,6 @@ fn main() { .input(Path::new("src").join("lib.rs")) .target("wasm32-unknown-unknown") .panic("unwind") - .arg("-Cllvm-args=-wasm-enable-eh") .arg("-Ctarget-feature=+exception-handling") .run(); diff --git a/tests/ui/borrowck/index-after-constantindex.rs b/tests/ui/borrowck/index-after-constantindex.rs new file mode 100644 index 0000000000000..5d78db4e411f5 --- /dev/null +++ b/tests/ui/borrowck/index-after-constantindex.rs @@ -0,0 +1,8 @@ +// test that an Index projection fails after a sibling ConstantIndex projection is moved out of +// regression test for #160525 + +fn main() { + let mut arr = [[Box::new(42)]]; + let alias = &mut arr[0][{ let [row] = arr; drop(row); 0 }]; //~ ERROR + println!("{}", **alias); // use-after-free of arr's dead stack slot +} diff --git a/tests/ui/borrowck/index-after-constantindex.stderr b/tests/ui/borrowck/index-after-constantindex.stderr new file mode 100644 index 0000000000000..d31a57df20a01 --- /dev/null +++ b/tests/ui/borrowck/index-after-constantindex.stderr @@ -0,0 +1,18 @@ +error[E0382]: borrow of moved value: `arr[..]` + --> $DIR/index-after-constantindex.rs:6:17 + | +LL | let alias = &mut arr[0][{ let [row] = arr; drop(row); 0 }]; + | ^^^^^^^^^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | value moved here + | value borrowed here after move + | + = note: move occurs because `arr[..]` has type `[Box; 1]`, which does not implement the `Copy` trait +help: borrow this binding in the pattern to avoid moving the value + | +LL | let alias = &mut arr[0][{ let [ref row] = arr; drop(row); 0 }]; + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/imports/unused-import-issue-163294.rs b/tests/ui/imports/unused-import-issue-163294.rs new file mode 100644 index 0000000000000..7793f1da760e2 --- /dev/null +++ b/tests/ui/imports/unused-import-issue-163294.rs @@ -0,0 +1,9 @@ +//@ edition: 2015 + +#![deny(unused_imports)] + +pub use core as _; +//~^ ERROR unresolved import `core` +//~^^ ERROR unused import: `core as _` + +fn main() {} diff --git a/tests/ui/imports/unused-import-issue-163294.stderr b/tests/ui/imports/unused-import-issue-163294.stderr new file mode 100644 index 0000000000000..ebb319562189a --- /dev/null +++ b/tests/ui/imports/unused-import-issue-163294.stderr @@ -0,0 +1,23 @@ +error[E0432]: unresolved import `core` + --> $DIR/unused-import-issue-163294.rs:5:9 + | +LL | pub use core as _; + | ----^^^^^ + | | + | no `core` in the root + +error: unused import: `core as _` + --> $DIR/unused-import-issue-163294.rs:5:9 + | +LL | pub use core as _; + | ^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-import-issue-163294.rs:3:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0432`.