Skip to content

Commit

Permalink
Rollup merge of rust-lang#102853 - cjgillot:skip-opaque-cast, r=jackh726
Browse files Browse the repository at this point in the history
Skip chained OpaqueCast when building captures.

Fixes rust-lang#102089
  • Loading branch information
Dylan-DPC authored Oct 10, 2022
2 parents 302bf31 + e828ce5 commit 5a09b72
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
15 changes: 7 additions & 8 deletions compiler/rustc_mir_build/src/build/expr/as_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/closures/issue-102089-multiple-opaque-cast.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 5a09b72

Please sign in to comment.