diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2022-10-09 16:15:16 +0000 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2022-10-09 16:18:16 +0000 |
| commit | e828ce53b9c9fdcf40d78aed75caf866309a621e (patch) | |
| tree | c805b467b2e73950cf23e2ada98bca498a0a48c7 | |
| parent | 8796e7a9cfd4c5c4f1de15ec1c53994ddf288665 (diff) | |
| download | rust-e828ce53b9c9fdcf40d78aed75caf866309a621e.tar.gz rust-e828ce53b9c9fdcf40d78aed75caf866309a621e.zip | |
Skip chained OpaqueCast when building captures.
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_place.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/lib.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/closures/issue-102089-multiple-opaque-cast.rs | 17 |
3 files changed, 25 insertions, 8 deletions
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 4d9e9b7c473..396782d45d2 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<PlaceElem<'tcx>>, prefix_projections: &[HirProjection<'tcx>], ) -> impl Iterator<Item = PlaceElem<'tcx>> { - 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 8236b1528c0..b53bd3d0710 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 00000000000..043bf06a1f5 --- /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() {} |
