Skip chained OpaqueCast when building captures.
This commit is contained in:
parent
8796e7a9cf
commit
e828ce53b9
3 changed files with 25 additions and 8 deletions
|
@ -17,6 +17,7 @@ use rustc_target::abi::VariantIdx;
|
||||||
|
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
|
|
||||||
|
use std::assert_matches::assert_matches;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
/// The "outermost" place that holds this value.
|
/// The "outermost" place that holds this value.
|
||||||
|
@ -232,22 +233,20 @@ fn strip_prefix<'tcx>(
|
||||||
projections: Vec<PlaceElem<'tcx>>,
|
projections: Vec<PlaceElem<'tcx>>,
|
||||||
prefix_projections: &[HirProjection<'tcx>],
|
prefix_projections: &[HirProjection<'tcx>],
|
||||||
) -> impl Iterator<Item = PlaceElem<'tcx>> {
|
) -> impl Iterator<Item = PlaceElem<'tcx>> {
|
||||||
let mut iter = projections.into_iter();
|
let mut iter = projections
|
||||||
let mut next = || match iter.next()? {
|
.into_iter()
|
||||||
// Filter out opaque casts, they are unnecessary in the prefix.
|
// Filter out opaque casts, they are unnecessary in the prefix.
|
||||||
ProjectionElem::OpaqueCast(..) => iter.next(),
|
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(..)));
|
||||||
other => Some(other),
|
|
||||||
};
|
|
||||||
for projection in prefix_projections {
|
for projection in prefix_projections {
|
||||||
match projection.kind {
|
match projection.kind {
|
||||||
HirProjectionKind::Deref => {
|
HirProjectionKind::Deref => {
|
||||||
assert!(matches!(next(), Some(ProjectionElem::Deref)));
|
assert_matches!(iter.next(), Some(ProjectionElem::Deref));
|
||||||
}
|
}
|
||||||
HirProjectionKind::Field(..) => {
|
HirProjectionKind::Field(..) => {
|
||||||
if base_ty.is_enum() {
|
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 => {
|
HirProjectionKind::Index | HirProjectionKind::Subslice => {
|
||||||
bug!("unexpected projection kind: {:?}", projection);
|
bug!("unexpected projection kind: {:?}", projection);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! This crate also contains the match exhaustiveness and usefulness checking.
|
//! This crate also contains the match exhaustiveness and usefulness checking.
|
||||||
#![allow(rustc::potential_query_instability)]
|
#![allow(rustc::potential_query_instability)]
|
||||||
|
#![feature(assert_matches)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
|
|
17
src/test/ui/closures/issue-102089-multiple-opaque-cast.rs
Normal file
17
src/test/ui/closures/issue-102089-multiple-opaque-cast.rs
Normal file
|
@ -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() {}
|
Loading…
Add table
Add a link
Reference in a new issue