Revert "Revert "Rollup merge of #98582 - oli-obk:unconstrained_opaque_type, r=estebank""
This reverts commit 4a742a691e
.
This commit is contained in:
parent
5d664f7a8f
commit
40e2de8c41
30 changed files with 250 additions and 37 deletions
|
@ -102,6 +102,8 @@ fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
|
|||
variant = Some(*idx);
|
||||
continue;
|
||||
}
|
||||
// These do not affect anything, they just make sure we know the right type.
|
||||
ProjectionElem::OpaqueCast(_) => continue,
|
||||
ProjectionElem::Index(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. } => {
|
||||
|
@ -168,7 +170,7 @@ fn find_capture_matching_projections<'a, 'tcx>(
|
|||
/// `PlaceBuilder` now starts from `PlaceBase::Local`.
|
||||
///
|
||||
/// Returns a Result with the error being the PlaceBuilder (`from_builder`) that was not found.
|
||||
#[instrument(level = "trace", skip(cx))]
|
||||
#[instrument(level = "trace", skip(cx), ret)]
|
||||
fn to_upvars_resolved_place_builder<'tcx>(
|
||||
from_builder: PlaceBuilder<'tcx>,
|
||||
cx: &Builder<'_, 'tcx>,
|
||||
|
@ -213,7 +215,6 @@ fn to_upvars_resolved_place_builder<'tcx>(
|
|||
&capture.captured_place.place.projections,
|
||||
);
|
||||
upvar_resolved_place_builder.projection.extend(remaining_projections);
|
||||
trace!(?upvar_resolved_place_builder);
|
||||
|
||||
Ok(upvar_resolved_place_builder)
|
||||
}
|
||||
|
@ -232,16 +233,21 @@ fn strip_prefix<'tcx>(
|
|||
prefix_projections: &[HirProjection<'tcx>],
|
||||
) -> impl Iterator<Item = PlaceElem<'tcx>> {
|
||||
let mut iter = projections.into_iter();
|
||||
let mut next = || match iter.next()? {
|
||||
// Filter out opaque casts, they are unnecessary in the prefix.
|
||||
ProjectionElem::OpaqueCast(..) => iter.next(),
|
||||
other => Some(other),
|
||||
};
|
||||
for projection in prefix_projections {
|
||||
match projection.kind {
|
||||
HirProjectionKind::Deref => {
|
||||
assert!(matches!(iter.next(), Some(ProjectionElem::Deref)));
|
||||
assert!(matches!(next(), Some(ProjectionElem::Deref)));
|
||||
}
|
||||
HirProjectionKind::Field(..) => {
|
||||
if base_ty.is_enum() {
|
||||
assert!(matches!(iter.next(), Some(ProjectionElem::Downcast(..))));
|
||||
assert!(matches!(next(), Some(ProjectionElem::Downcast(..))));
|
||||
}
|
||||
assert!(matches!(iter.next(), Some(ProjectionElem::Field(..))));
|
||||
assert!(matches!(next(), Some(ProjectionElem::Field(..))));
|
||||
}
|
||||
HirProjectionKind::Index | HirProjectionKind::Subslice => {
|
||||
bug!("unexpected projection kind: {:?}", projection);
|
||||
|
@ -711,6 +717,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}
|
||||
ProjectionElem::Field(..)
|
||||
| ProjectionElem::Downcast(..)
|
||||
| ProjectionElem::OpaqueCast(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. } => (),
|
||||
}
|
||||
|
|
|
@ -95,9 +95,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
|
||||
impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
pub(in crate::build) fn new(
|
||||
place: PlaceBuilder<'tcx>,
|
||||
mut place: PlaceBuilder<'tcx>,
|
||||
pattern: &'pat Pat<'tcx>,
|
||||
) -> MatchPair<'pat, 'tcx> {
|
||||
// Force the place type to the pattern's type.
|
||||
// FIXME(oli-obk): can we use this to simplify slice/array pattern hacks?
|
||||
// FIXME(oli-obk): only add this projection if `place` actually had an opaque
|
||||
// type before the projection.
|
||||
place = place.project(ProjectionElem::OpaqueCast(pattern.ty));
|
||||
MatchPair { place, pattern }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -842,7 +842,15 @@ fn is_useful<'p, 'tcx>(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
let ty = v.head().ty();
|
||||
let mut ty = v.head().ty();
|
||||
|
||||
// Opaque types can't get destructured/split, but the patterns can
|
||||
// actually hint at hidden types, so we use the patterns' types instead.
|
||||
if let ty::Opaque(..) = ty.kind() {
|
||||
if let Some(row) = rows.first() {
|
||||
ty = row.head().ty();
|
||||
}
|
||||
}
|
||||
let is_non_exhaustive = cx.is_foreign_non_exhaustive_enum(ty);
|
||||
debug!("v.head: {:?}, v.span: {:?}", v.head(), v.head().span());
|
||||
let pcx = &PatCtxt { cx, ty, span: v.head().span(), is_top_level, is_non_exhaustive };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue