Auto merge of #99806 - oli-obk:unconstrained_opaque_type, r=estebank
Allow patterns to constrain the hidden type of opaque types fixes #96572 reverts a revert as original PR was a perf regression that was fixed by reverting it: https://github.com/rust-lang/rust/pull/99368#issuecomment-1186587864) TODO: * check if https://github.com/rust-lang/rust/issues/99685 is avoided
This commit is contained in:
commit
4136b59b7d
40 changed files with 384 additions and 179 deletions
|
@ -2146,7 +2146,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
StorageDeadOrDrop::Destructor(_) => kind,
|
||||
},
|
||||
ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => {
|
||||
ProjectionElem::OpaqueCast { .. }
|
||||
| ProjectionElem::Field(..)
|
||||
| ProjectionElem::Downcast(..) => {
|
||||
match place_ty.ty.kind() {
|
||||
ty::Adt(def, _) if def.has_dtor(tcx) => {
|
||||
// Report the outermost adt with a destructor
|
||||
|
|
|
@ -237,6 +237,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
ProjectionElem::Downcast(..) if opt.including_downcast => return None,
|
||||
ProjectionElem::Downcast(..) => (),
|
||||
ProjectionElem::OpaqueCast(..) => (),
|
||||
ProjectionElem::Field(field, _ty) => {
|
||||
// FIXME(project-rfc_2229#36): print capture precisely here.
|
||||
if let Some(field) = self.is_upvar_field_projection(PlaceRef {
|
||||
|
@ -317,6 +318,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx)
|
||||
}
|
||||
ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx),
|
||||
ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(*ty),
|
||||
ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type),
|
||||
},
|
||||
};
|
||||
|
|
|
@ -169,6 +169,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
..,
|
||||
ProjectionElem::Index(_)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::OpaqueCast { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Downcast(..),
|
||||
],
|
||||
|
|
|
@ -1781,6 +1781,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
for (place_base, elem) in place.iter_projections().rev() {
|
||||
match elem {
|
||||
ProjectionElem::Index(_/*operand*/) |
|
||||
ProjectionElem::OpaqueCast(_) |
|
||||
ProjectionElem::ConstantIndex { .. } |
|
||||
// assigning to P[i] requires P to be valid.
|
||||
ProjectionElem::Downcast(_/*adt_def*/, _/*variant_idx*/) =>
|
||||
|
@ -2172,6 +2173,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
| ProjectionElem::Index(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::OpaqueCast { .. }
|
||||
| ProjectionElem::Downcast(..) => {
|
||||
let upvar_field_projection = self.is_upvar_field_projection(place);
|
||||
if let Some(field) = upvar_field_projection {
|
||||
|
|
|
@ -250,6 +250,7 @@ fn place_components_conflict<'tcx>(
|
|||
| (ProjectionElem::Index { .. }, _, _)
|
||||
| (ProjectionElem::ConstantIndex { .. }, _, _)
|
||||
| (ProjectionElem::Subslice { .. }, _, _)
|
||||
| (ProjectionElem::OpaqueCast { .. }, _, _)
|
||||
| (ProjectionElem::Downcast { .. }, _, _) => {
|
||||
// Recursive case. This can still be disjoint on a
|
||||
// further iteration if this a shallow access and
|
||||
|
@ -317,6 +318,17 @@ fn place_projection_conflict<'tcx>(
|
|||
debug!("place_element_conflict: DISJOINT-OR-EQ-DEREF");
|
||||
Overlap::EqualOrDisjoint
|
||||
}
|
||||
(ProjectionElem::OpaqueCast(v1), ProjectionElem::OpaqueCast(v2)) => {
|
||||
if v1 == v2 {
|
||||
// same type - recur.
|
||||
debug!("place_element_conflict: DISJOINT-OR-EQ-OPAQUE");
|
||||
Overlap::EqualOrDisjoint
|
||||
} else {
|
||||
// Different types. Disjoint!
|
||||
debug!("place_element_conflict: DISJOINT-OPAQUE");
|
||||
Overlap::Disjoint
|
||||
}
|
||||
}
|
||||
(ProjectionElem::Field(f1, _), ProjectionElem::Field(f2, _)) => {
|
||||
if f1 == f2 {
|
||||
// same field (e.g., `a.y` vs. `a.y`) - recur.
|
||||
|
@ -520,6 +532,7 @@ fn place_projection_conflict<'tcx>(
|
|||
| ProjectionElem::Field(..)
|
||||
| ProjectionElem::Index(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::OpaqueCast { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Downcast(..),
|
||||
_,
|
||||
|
|
|
@ -81,6 +81,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
|
|||
}
|
||||
ProjectionElem::Downcast(..)
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::OpaqueCast { .. }
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Index(_) => {
|
||||
cursor = cursor_base;
|
||||
|
|
|
@ -764,6 +764,19 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
|||
}
|
||||
PlaceTy::from_ty(fty)
|
||||
}
|
||||
ProjectionElem::OpaqueCast(ty) => {
|
||||
let ty = self.sanitize_type(place, ty);
|
||||
let ty = self.cx.normalize(ty, location);
|
||||
self.cx
|
||||
.eq_types(
|
||||
base.ty,
|
||||
ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::TypeAnnotation,
|
||||
)
|
||||
.unwrap();
|
||||
PlaceTy::from_ty(ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1170,10 +1183,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
tcx,
|
||||
self.param_env,
|
||||
proj,
|
||||
|this, field, ()| {
|
||||
|this, field, _| {
|
||||
let ty = this.field_ty(tcx, field);
|
||||
self.normalize(ty, locations)
|
||||
},
|
||||
|_, _| unreachable!(),
|
||||
);
|
||||
curr_projected_ty = projected_ty;
|
||||
}
|
||||
|
@ -2503,6 +2517,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
ProjectionElem::Field(..)
|
||||
| ProjectionElem::Downcast(..)
|
||||
| ProjectionElem::OpaqueCast(..)
|
||||
| ProjectionElem::Index(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. } => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue