diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 4d9e9b7c4738d..396782d45d289 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -17,6 +17,7 @@ use rustc_target::abi::VariantIdx; use rustc_index::vec::Idx; +use std::assert_matches::assert_matches; use std::iter; /// The "outermost" place that holds this value. @@ -232,22 +233,20 @@ fn strip_prefix<'tcx>( projections: Vec>, prefix_projections: &[HirProjection<'tcx>], ) -> impl Iterator> { - let mut iter = projections.into_iter(); - let mut next = || match iter.next()? { + let mut iter = projections + .into_iter() // Filter out opaque casts, they are unnecessary in the prefix. - ProjectionElem::OpaqueCast(..) => iter.next(), - other => Some(other), - }; + .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(..))); for projection in prefix_projections { match projection.kind { HirProjectionKind::Deref => { - assert!(matches!(next(), Some(ProjectionElem::Deref))); + assert_matches!(iter.next(), Some(ProjectionElem::Deref)); } HirProjectionKind::Field(..) => { if base_ty.is_enum() { - assert!(matches!(next(), Some(ProjectionElem::Downcast(..)))); + assert_matches!(iter.next(), Some(ProjectionElem::Downcast(..))); } - assert!(matches!(next(), Some(ProjectionElem::Field(..)))); + assert_matches!(iter.next(), Some(ProjectionElem::Field(..))); } HirProjectionKind::Index | HirProjectionKind::Subslice => { bug!("unexpected projection kind: {:?}", projection); diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 8236b1528c0ec..b53bd3d0710a6 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -2,6 +2,7 @@ //! //! This crate also contains the match exhaustiveness and usefulness checking. #![allow(rustc::potential_query_instability)] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(if_let_guard)] diff --git a/src/test/ui/closures/issue-102089-multiple-opaque-cast.rs b/src/test/ui/closures/issue-102089-multiple-opaque-cast.rs new file mode 100644 index 0000000000000..043bf06a1f521 --- /dev/null +++ b/src/test/ui/closures/issue-102089-multiple-opaque-cast.rs @@ -0,0 +1,17 @@ +// edition:2021 +// check-pass + +pub struct Example<'a, T> { + a: T, + b: &'a T, +} + +impl<'a, T> Example<'a, T> { + pub fn error_trying_to_destructure_self_in_closure(self) { + let closure = || { + let Self { a, b } = self; + }; + } +} + +fn main() {}