diff options
| author | Michael Goulet <michael@errs.io> | 2025-01-31 01:24:37 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-01-31 17:19:53 +0000 |
| commit | fc1a9186dcdad111fd99ddd38bd961a8a205c380 (patch) | |
| tree | c60452a9af751853a3ccef6e8eefd0dc145685a5 /compiler/rustc_borrowck | |
| parent | 7f36543a48e52912ac6664a70c0a5b9d86509eaf (diff) | |
| download | rust-fc1a9186dcdad111fd99ddd38bd961a8a205c380.tar.gz rust-fc1a9186dcdad111fd99ddd38bd961a8a205c380.zip | |
Implement MIR, CTFE, and codegen for unsafe binders
Diffstat (limited to 'compiler/rustc_borrowck')
8 files changed, 78 insertions, 10 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 07dcbba019a..e51b1b42d09 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -3915,7 +3915,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } | ProjectionElem::Subtype(_) - | ProjectionElem::Index(_) => kind, + | ProjectionElem::Index(_) + | ProjectionElem::UnwrapUnsafeBinder(_) => kind, }, place_ty.projection_ty(tcx, elem), ) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index bd6f77156ca..6255ba4f5a1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -370,6 +370,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ProjectionElem::Downcast(..) => (), ProjectionElem::OpaqueCast(..) => (), ProjectionElem::Subtype(..) => (), + ProjectionElem::UnwrapUnsafeBinder(_) => (), ProjectionElem::Field(field, _ty) => { // FIXME(project-rfc_2229#36): print capture precisely here. if let Some(field) = self.is_upvar_field_projection(PlaceRef { @@ -450,9 +451,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx) } ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx), - ProjectionElem::Subtype(ty) | ProjectionElem::OpaqueCast(ty) => { - PlaceTy::from_ty(*ty) - } + ProjectionElem::Subtype(ty) + | ProjectionElem::OpaqueCast(ty) + | ProjectionElem::UnwrapUnsafeBinder(ty) => PlaceTy::from_ty(*ty), ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type), }, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index e841a5e4c94..706dd7135f7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -167,7 +167,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { | ProjectionElem::ConstantIndex { .. } | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Subslice { .. } - | ProjectionElem::Downcast(..), + | ProjectionElem::Downcast(..) + | ProjectionElem::UnwrapUnsafeBinder(_), ], } => bug!("Unexpected immutable place."), } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index decfab502bb..077d8f49df8 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1398,6 +1398,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { self.consume_operand(location, (operand, span), state); } } + + Rvalue::WrapUnsafeBinder(op, _) => { + self.consume_operand(location, (op, span), state); + } } } @@ -1770,7 +1774,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { // So it's safe to skip these. ProjectionElem::OpaqueCast(_) | ProjectionElem::Subtype(_) - | ProjectionElem::Downcast(_, _) => (), + | ProjectionElem::Downcast(_, _) + | ProjectionElem::UnwrapUnsafeBinder(_) => (), } place_ty = place_ty.projection_ty(tcx, elem); @@ -2004,6 +2009,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { // FIXME: is this true even if P is an adt with a dtor? { } + ProjectionElem::UnwrapUnsafeBinder(_) => { + check_parent_of_field(self, location, place_base, span, state); + } + // assigning to (*P) requires P to be initialized ProjectionElem::Deref => { self.check_if_full_path_is_moved( @@ -2384,7 +2393,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { | ProjectionElem::Subslice { .. } | ProjectionElem::Subtype(..) | ProjectionElem::OpaqueCast { .. } - | ProjectionElem::Downcast(..) => { + | ProjectionElem::Downcast(..) + | ProjectionElem::UnwrapUnsafeBinder(_) => { let upvar_field_projection = self.is_upvar_field_projection(place); if let Some(field) = upvar_field_projection { let upvar = &self.upvars[field.index()]; diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index 679e111caa9..cf3e82426e8 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -250,7 +250,8 @@ fn place_components_conflict<'tcx>( | (ProjectionElem::Subslice { .. }, _, _) | (ProjectionElem::OpaqueCast { .. }, _, _) | (ProjectionElem::Subtype(_), _, _) - | (ProjectionElem::Downcast { .. }, _, _) => { + | (ProjectionElem::Downcast { .. }, _, _) + | (ProjectionElem::UnwrapUnsafeBinder(_), _, _) => { // Recursive case. This can still be disjoint on a // further iteration if this a shallow access and // there's a deref later on, e.g., a borrow @@ -519,5 +520,9 @@ fn place_projection_conflict<'tcx>( pi1_elem, pi2_elem ), + + (ProjectionElem::UnwrapUnsafeBinder(_), _) => { + todo!() + } } } diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index f79bcf5af55..0d1d8642bca 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -325,6 +325,10 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> { self.consume_operand(location, operand); } } + + Rvalue::WrapUnsafeBinder(op, _) => { + self.consume_operand(location, op); + } } } diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index fc7e6e58641..83cca38a5c0 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -66,6 +66,10 @@ impl<'tcx> Iterator for Prefixes<'tcx> { self.next = Some(cursor_base); return Some(cursor); } + ProjectionElem::UnwrapUnsafeBinder(_) => { + self.next = Some(cursor_base); + return Some(cursor); + } ProjectionElem::Downcast(..) | ProjectionElem::Subslice { .. } | ProjectionElem::OpaqueCast { .. } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index a2ef5588f48..92492bfdb8d 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -302,6 +302,25 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { ) .unwrap(); } + ProjectionElem::UnwrapUnsafeBinder(ty) => { + let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else { + unreachable!(); + }; + let found_ty = self.typeck.infcx.instantiate_binder_with_fresh_vars( + self.body().source_info(location).span, + BoundRegionConversionTime::HigherRankedType, + binder_ty.into(), + ); + self.typeck + .relate_types( + ty, + context.ambient_variance(), + found_ty, + location.to_locations(), + ConstraintCategory::Boring, + ) + .unwrap(); + } ProjectionElem::Subtype(_) => { bug!("ProjectionElem::Subtype shouldn't exist in borrowck") } @@ -2233,6 +2252,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_operand(right, location); } + Rvalue::WrapUnsafeBinder(op, ty) => { + self.check_operand(op, location); + let operand_ty = op.ty(self.body, self.tcx()); + + let ty::UnsafeBinder(binder_ty) = *ty.kind() else { + unreachable!(); + }; + let expected_ty = self.infcx.instantiate_binder_with_fresh_vars( + self.body().source_info(location).span, + BoundRegionConversionTime::HigherRankedType, + binder_ty.into(), + ); + self.sub_types( + operand_ty, + expected_ty, + location.to_locations(), + ConstraintCategory::Boring, + ) + .unwrap(); + } + Rvalue::RawPtr(..) | Rvalue::ThreadLocalRef(..) | Rvalue::Len(..) @@ -2258,7 +2298,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | Rvalue::NullaryOp(..) | Rvalue::CopyForDeref(..) | Rvalue::UnaryOp(..) - | Rvalue::Discriminant(..) => None, + | Rvalue::Discriminant(..) + | Rvalue::WrapUnsafeBinder(..) => None, Rvalue::Aggregate(aggregate, _) => match **aggregate { AggregateKind::Adt(_, _, _, user_ty, _) => user_ty, @@ -2450,7 +2491,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | ProjectionElem::OpaqueCast(..) | ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } - | ProjectionElem::Subslice { .. } => { + | ProjectionElem::Subslice { .. } + | ProjectionElem::UnwrapUnsafeBinder(_) => { // other field access } ProjectionElem::Subtype(_) => { |
