diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/mir/pretty.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/statement.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/syntax.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/tcx.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/type_foldable.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/visit.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/thir.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/thir/visit.rs | 3 |
8 files changed, 62 insertions, 4 deletions
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index a318bacb866..09d7e60e199 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1248,6 +1248,10 @@ impl<'tcx> Debug for Rvalue<'tcx> { ShallowInitBox(ref place, ref ty) => { with_no_trimmed_paths!(write!(fmt, "ShallowInitBox({place:?}, {ty})")) } + + WrapUnsafeBinder(ref op, ty) => { + with_no_trimmed_paths!(write!(fmt, "wrap_binder!({op:?}; {ty})")) + } } } } @@ -1308,6 +1312,9 @@ fn pre_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) -> ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {} + ProjectionElem::UnwrapUnsafeBinder(_) => { + write!(fmt, "unwrap_binder!(")?; + } } } @@ -1356,6 +1363,9 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) -> ProjectionElem::Subslice { from, to, from_end: false } => { write!(fmt, "[{from:?}..{to:?}]")?; } + ProjectionElem::UnwrapUnsafeBinder(ty) => { + write!(fmt, "; {ty})")?; + } } } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 609d5647d04..d345c99f902 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -62,7 +62,8 @@ impl<V, T> ProjectionElem<V, T> { | Self::Subtype(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } - | Self::Downcast(_, _) => false, + | Self::Downcast(_, _) + | Self::UnwrapUnsafeBinder(..) => false, } } @@ -76,7 +77,8 @@ impl<V, T> ProjectionElem<V, T> { | Self::Subtype(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } - | Self::Downcast(_, _) => true, + | Self::Downcast(_, _) + | Self::UnwrapUnsafeBinder(..) => true, } } @@ -102,6 +104,9 @@ impl<V, T> ProjectionElem<V, T> { | Self::Subtype(_) | Self::OpaqueCast(_) | Self::Subslice { .. } => false, + + // FIXME(unsafe_binders): Figure this out. + Self::UnwrapUnsafeBinder(..) => false, } } } @@ -443,7 +448,8 @@ impl<'tcx> Rvalue<'tcx> { | Rvalue::UnaryOp(_, _) | Rvalue::Discriminant(_) | Rvalue::Aggregate(_, _) - | Rvalue::ShallowInitBox(_, _) => true, + | Rvalue::ShallowInitBox(_, _) + | Rvalue::WrapUnsafeBinder(_, _) => true, } } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 5868b64f6b5..8afa9505724 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1275,6 +1275,10 @@ pub enum ProjectionElem<V, T> { /// requiring an intermediate variable. OpaqueCast(T), + /// A transmute from an unsafe binder to the type that it wraps. This is a projection + /// of a place, so it doesn't necessarily constitute a move out of the binder. + UnwrapUnsafeBinder(T), + /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping /// explicit during optimizations and codegen. @@ -1492,6 +1496,9 @@ pub enum Rvalue<'tcx> { /// optimizations and codegen backends that previously had to handle deref operations anywhere /// in a place. CopyForDeref(Place<'tcx>), + + /// Wraps a value in an unsafe binder. + WrapUnsafeBinder(Operand<'tcx>, Ty<'tcx>), } #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 4d11492e94d..49449426fa4 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -146,6 +146,11 @@ impl<'tcx> PlaceTy<'tcx> { ProjectionElem::Subtype(ty) => { PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) } + + // FIXME(unsafe_binders): Rename `handle_opaque_cast_and_subtype` to be more general. + ProjectionElem::UnwrapUnsafeBinder(ty) => { + PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) + } }; debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer); answer @@ -241,6 +246,7 @@ impl<'tcx> Rvalue<'tcx> { }, Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty), Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty, + Rvalue::WrapUnsafeBinder(_, ty) => ty, } } diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index b59b9e55fe8..9893dd0484c 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -1,6 +1,7 @@ //! `TypeFoldable` implementations for MIR types use rustc_ast::InlineAsmTemplatePiece; +use rustc_hir::UnsafeBinderCastKind; use rustc_hir::def_id::LocalDefId; use super::*; @@ -21,6 +22,7 @@ TrivialTypeTraversalImpls! { SwitchTargets, CoroutineKind, CoroutineSavedLocal, + UnsafeBinderCastKind, } TrivialTypeTraversalImpls! { diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 95de08ce9c8..e4c238b73fc 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -781,6 +781,11 @@ macro_rules! make_mir_visitor { self.visit_operand(operand, location); self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } + + Rvalue::WrapUnsafeBinder(op, ty) => { + self.visit_operand(op, location); + self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); + } } } @@ -1151,6 +1156,11 @@ macro_rules! visit_place_fns { self.visit_ty(&mut new_ty, TyContext::Location(location)); if ty != new_ty { Some(PlaceElem::Subtype(new_ty)) } else { None } } + PlaceElem::UnwrapUnsafeBinder(ty) => { + let mut new_ty = ty; + self.visit_ty(&mut new_ty, TyContext::Location(location)); + if ty != new_ty { Some(PlaceElem::UnwrapUnsafeBinder(new_ty)) } else { None } + } PlaceElem::Deref | PlaceElem::ConstantIndex { .. } | PlaceElem::Subslice { .. } @@ -1219,7 +1229,8 @@ macro_rules! visit_place_fns { match elem { ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) - | ProjectionElem::Field(_, ty) => { + | ProjectionElem::Field(_, ty) + | ProjectionElem::UnwrapUnsafeBinder(ty) => { self.visit_ty(ty, TyContext::Location(location)); } ProjectionElem::Index(local) => { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 86014c34b45..d56046136c7 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -489,6 +489,19 @@ pub enum ExprKind<'tcx> { user_ty: UserTy<'tcx>, user_ty_span: Span, }, + /// An unsafe binder cast on a place, e.g. `unwrap_binder!(*ptr)`. + PlaceUnwrapUnsafeBinder { + source: ExprId, + }, + /// An unsafe binder cast on a value, e.g. `unwrap_binder!(rvalue())`, + /// which makes a temporary. + ValueUnwrapUnsafeBinder { + source: ExprId, + }, + /// Construct an unsafe binder, e.g. `wrap_binder(&ref)`. + WrapUnsafeBinder { + source: ExprId, + }, /// A closure definition. Closure(Box<ClosureExpr<'tcx>>), /// A literal. diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 64bac12b266..2aeb13942a3 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -136,6 +136,9 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( | ValueTypeAscription { source, user_ty: _, user_ty_span: _ } => { visitor.visit_expr(&visitor.thir()[source]) } + PlaceUnwrapUnsafeBinder { source } + | ValueUnwrapUnsafeBinder { source } + | WrapUnsafeBinder { source } => visitor.visit_expr(&visitor.thir()[source]), Closure(box ClosureExpr { closure_id: _, args: _, |
