Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 4136b59

Browse files
committed
Auto merge of rust-lang#99806 - oli-obk:unconstrained_opaque_type, r=estebank
Allow patterns to constrain the hidden type of opaque types fixes rust-lang#96572 reverts a revert as original PR was a perf regression that was fixed by reverting it: rust-lang#99368 (comment)) TODO: * check if rust-lang#99685 is avoided
2 parents 8fd6d03 + 1905f8c commit 4136b59

File tree

40 files changed

+384
-179
lines changed

40 files changed

+384
-179
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2146,7 +2146,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
21462146
}
21472147
StorageDeadOrDrop::Destructor(_) => kind,
21482148
},
2149-
ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => {
2149+
ProjectionElem::OpaqueCast { .. }
2150+
| ProjectionElem::Field(..)
2151+
| ProjectionElem::Downcast(..) => {
21502152
match place_ty.ty.kind() {
21512153
ty::Adt(def, _) if def.has_dtor(tcx) => {
21522154
// Report the outermost adt with a destructor

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
237237
}
238238
ProjectionElem::Downcast(..) if opt.including_downcast => return None,
239239
ProjectionElem::Downcast(..) => (),
240+
ProjectionElem::OpaqueCast(..) => (),
240241
ProjectionElem::Field(field, _ty) => {
241242
// FIXME(project-rfc_2229#36): print capture precisely here.
242243
if let Some(field) = self.is_upvar_field_projection(PlaceRef {
@@ -317,6 +318,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
317318
PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx)
318319
}
319320
ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx),
321+
ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(*ty),
320322
ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type),
321323
},
322324
};

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
169169
..,
170170
ProjectionElem::Index(_)
171171
| ProjectionElem::ConstantIndex { .. }
172+
| ProjectionElem::OpaqueCast { .. }
172173
| ProjectionElem::Subslice { .. }
173174
| ProjectionElem::Downcast(..),
174175
],

compiler/rustc_borrowck/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,6 +1781,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
17811781
for (place_base, elem) in place.iter_projections().rev() {
17821782
match elem {
17831783
ProjectionElem::Index(_/*operand*/) |
1784+
ProjectionElem::OpaqueCast(_) |
17841785
ProjectionElem::ConstantIndex { .. } |
17851786
// assigning to P[i] requires P to be valid.
17861787
ProjectionElem::Downcast(_/*adt_def*/, _/*variant_idx*/) =>
@@ -2172,6 +2173,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
21722173
| ProjectionElem::Index(..)
21732174
| ProjectionElem::ConstantIndex { .. }
21742175
| ProjectionElem::Subslice { .. }
2176+
| ProjectionElem::OpaqueCast { .. }
21752177
| ProjectionElem::Downcast(..) => {
21762178
let upvar_field_projection = self.is_upvar_field_projection(place);
21772179
if let Some(field) = upvar_field_projection {

compiler/rustc_borrowck/src/places_conflict.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ fn place_components_conflict<'tcx>(
250250
| (ProjectionElem::Index { .. }, _, _)
251251
| (ProjectionElem::ConstantIndex { .. }, _, _)
252252
| (ProjectionElem::Subslice { .. }, _, _)
253+
| (ProjectionElem::OpaqueCast { .. }, _, _)
253254
| (ProjectionElem::Downcast { .. }, _, _) => {
254255
// Recursive case. This can still be disjoint on a
255256
// further iteration if this a shallow access and
@@ -317,6 +318,17 @@ fn place_projection_conflict<'tcx>(
317318
debug!("place_element_conflict: DISJOINT-OR-EQ-DEREF");
318319
Overlap::EqualOrDisjoint
319320
}
321+
(ProjectionElem::OpaqueCast(v1), ProjectionElem::OpaqueCast(v2)) => {
322+
if v1 == v2 {
323+
// same type - recur.
324+
debug!("place_element_conflict: DISJOINT-OR-EQ-OPAQUE");
325+
Overlap::EqualOrDisjoint
326+
} else {
327+
// Different types. Disjoint!
328+
debug!("place_element_conflict: DISJOINT-OPAQUE");
329+
Overlap::Disjoint
330+
}
331+
}
320332
(ProjectionElem::Field(f1, _), ProjectionElem::Field(f2, _)) => {
321333
if f1 == f2 {
322334
// same field (e.g., `a.y` vs. `a.y`) - recur.
@@ -520,6 +532,7 @@ fn place_projection_conflict<'tcx>(
520532
| ProjectionElem::Field(..)
521533
| ProjectionElem::Index(..)
522534
| ProjectionElem::ConstantIndex { .. }
535+
| ProjectionElem::OpaqueCast { .. }
523536
| ProjectionElem::Subslice { .. }
524537
| ProjectionElem::Downcast(..),
525538
_,

compiler/rustc_borrowck/src/prefixes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
8181
}
8282
ProjectionElem::Downcast(..)
8383
| ProjectionElem::Subslice { .. }
84+
| ProjectionElem::OpaqueCast { .. }
8485
| ProjectionElem::ConstantIndex { .. }
8586
| ProjectionElem::Index(_) => {
8687
cursor = cursor_base;

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,19 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
764764
}
765765
PlaceTy::from_ty(fty)
766766
}
767+
ProjectionElem::OpaqueCast(ty) => {
768+
let ty = self.sanitize_type(place, ty);
769+
let ty = self.cx.normalize(ty, location);
770+
self.cx
771+
.eq_types(
772+
base.ty,
773+
ty,
774+
location.to_locations(),
775+
ConstraintCategory::TypeAnnotation,
776+
)
777+
.unwrap();
778+
PlaceTy::from_ty(ty)
779+
}
767780
}
768781
}
769782

@@ -1170,10 +1183,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11701183
tcx,
11711184
self.param_env,
11721185
proj,
1173-
|this, field, ()| {
1186+
|this, field, _| {
11741187
let ty = this.field_ty(tcx, field);
11751188
self.normalize(ty, locations)
11761189
},
1190+
|_, _| unreachable!(),
11771191
);
11781192
curr_projected_ty = projected_ty;
11791193
}
@@ -2503,6 +2517,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
25032517
}
25042518
ProjectionElem::Field(..)
25052519
| ProjectionElem::Downcast(..)
2520+
| ProjectionElem::OpaqueCast(..)
25062521
| ProjectionElem::Index(..)
25072522
| ProjectionElem::ConstantIndex { .. }
25082523
| ProjectionElem::Subslice { .. } => {

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,7 @@ pub(crate) fn codegen_place<'tcx>(
850850
PlaceElem::Deref => {
851851
cplace = cplace.place_deref(fx);
852852
}
853+
PlaceElem::OpaqueCast(ty) => cplace = cplace.place_opaque_cast(fx, ty),
853854
PlaceElem::Field(field, _ty) => {
854855
cplace = cplace.place_field(fx, field);
855856
}

compiler/rustc_codegen_cranelift/src/value_and_place.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,14 @@ impl<'tcx> CPlace<'tcx> {
621621
}
622622
}
623623

624+
pub(crate) fn place_opaque_cast(
625+
self,
626+
fx: &mut FunctionCx<'_, '_, 'tcx>,
627+
ty: Ty<'tcx>,
628+
) -> CPlace<'tcx> {
629+
CPlace { inner: self.inner, layout: fx.layout_of(ty) }
630+
}
631+
624632
pub(crate) fn place_field(
625633
self,
626634
fx: &mut FunctionCx<'_, '_, 'tcx>,

compiler/rustc_codegen_ssa/src/mir/place.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,21 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
400400
downcast
401401
}
402402

403+
pub fn project_type<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
404+
&self,
405+
bx: &mut Bx,
406+
ty: Ty<'tcx>,
407+
) -> Self {
408+
let mut downcast = *self;
409+
downcast.layout = bx.cx().layout_of(ty);
410+
411+
// Cast to the appropriate type.
412+
let variant_ty = bx.cx().backend_type(downcast.layout);
413+
downcast.llval = bx.pointercast(downcast.llval, bx.cx().type_ptr_to(variant_ty));
414+
415+
downcast
416+
}
417+
403418
pub fn storage_live<Bx: BuilderMethods<'a, 'tcx, Value = V>>(&self, bx: &mut Bx) {
404419
bx.lifetime_start(self.llval, self.layout.size);
405420
}
@@ -442,6 +457,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
442457
mir::ProjectionElem::Field(ref field, _) => {
443458
cg_base.project_field(bx, field.index())
444459
}
460+
mir::ProjectionElem::OpaqueCast(ty) => cg_base.project_type(bx, ty),
445461
mir::ProjectionElem::Index(index) => {
446462
let index = &mir::Operand::Copy(mir::Place::from(index));
447463
let index = self.codegen_operand(bx, index);

0 commit comments

Comments
 (0)