From 4428a375277993399889590425f31b5eae792e9d Mon Sep 17 00:00:00 2001 From: Sebastien Tardif Date: Tue, 23 Jun 2026 22:44:07 -0700 Subject: [PATCH] rustc_public: add MIR Wrap/UnwrapUnsafeBinder to SMIR Expose unsafe binder rvalue/projection in rustc_public MIR and implement stable/internal conversion, pretty-print, and visitor support. Removes todo! ICE when SMIR lowers feature-gated unsafe binder MIR. Signed-off-by: Sebastien Tardif --- compiler/rustc_public/src/mir/body.rs | 8 ++++++++ compiler/rustc_public/src/mir/pretty.rs | 3 +++ compiler/rustc_public/src/mir/visit.rs | 6 ++++++ compiler/rustc_public/src/unstable/convert/internal.rs | 3 +++ compiler/rustc_public/src/unstable/convert/stable/mir.rs | 9 +++++++-- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_public/src/mir/body.rs b/compiler/rustc_public/src/mir/body.rs index f9b5f9af951e5..7ff01c4502908 100644 --- a/compiler/rustc_public/src/mir/body.rs +++ b/compiler/rustc_public/src/mir/body.rs @@ -593,6 +593,9 @@ pub enum Rvalue { /// /// [`Rvalue::Reborrow`]: rustc_middle::mir::Rvalue::Reborrow Reborrow(Ty, Mutability, Place), + + /// Wraps a value in an `unsafe<>` binder type (feature `unsafe_binders`). + WrapUnsafeBinder(Operand, Ty), } impl Rvalue { @@ -650,6 +653,7 @@ impl Rvalue { AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)), }, Rvalue::CopyForDeref(place) => place.ty(locals), + Rvalue::WrapUnsafeBinder(_, ty) => Ok(*ty), } } } @@ -835,6 +839,9 @@ pub enum ProjectionElem { /// Like an explicit cast from an opaque type to a concrete type, but without /// requiring an intermediate variable. OpaqueCast(Ty), + + /// Unwraps an `unsafe<>` binder place to its inner type (feature `unsafe_binders`). + UnwrapUnsafeBinder(Ty), } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] @@ -1069,6 +1076,7 @@ impl ProjectionElem { } ProjectionElem::Downcast(_) => Ok(ty), ProjectionElem::OpaqueCast(ty) => Ok(*ty), + ProjectionElem::UnwrapUnsafeBinder(ty) => Ok(*ty), } } diff --git a/compiler/rustc_public/src/mir/pretty.rs b/compiler/rustc_public/src/mir/pretty.rs index dec4044fd260b..5a44dd4d105be 100644 --- a/compiler/rustc_public/src/mir/pretty.rs +++ b/compiler/rustc_public/src/mir/pretty.rs @@ -401,6 +401,9 @@ fn pretty_rvalue(writer: &mut W, rval: &Rvalue) -> io::Result<()> { if matches!(retag, crate::mir::WithRetag::No) { "no_retag " } else { "" }, pretty_operand(op) ), + Rvalue::WrapUnsafeBinder(op, ty) => { + write!(writer, "wrap_unsafe_binder({}, {})", pretty_operand(op), ty) + } } } diff --git a/compiler/rustc_public/src/mir/visit.rs b/compiler/rustc_public/src/mir/visit.rs index 5a3afc9937351..87d2bdde8f38d 100644 --- a/compiler/rustc_public/src/mir/visit.rs +++ b/compiler/rustc_public/src/mir/visit.rs @@ -285,6 +285,10 @@ macro_rules! make_mir_visitor { Rvalue::UnaryOp(_, op) | Rvalue::Use(op, _) => { self.visit_operand(op, location); } + Rvalue::WrapUnsafeBinder(op, ty) => { + self.visit_operand(op, location); + self.visit_ty(ty, location); + } } } @@ -468,6 +472,7 @@ macro_rules! visit_place_fns { ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} ProjectionElem::Downcast(_idx) => {} ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location), + ProjectionElem::UnwrapUnsafeBinder(ty) => self.visit_ty(ty, location), } } }; @@ -508,6 +513,7 @@ macro_rules! visit_place_fns { ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} ProjectionElem::Downcast(_idx) => {} ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location), + ProjectionElem::UnwrapUnsafeBinder(ty) => self.visit_ty(ty, location), } } }; diff --git a/compiler/rustc_public/src/unstable/convert/internal.rs b/compiler/rustc_public/src/unstable/convert/internal.rs index 81b32f4da10f6..880207d80e09d 100644 --- a/compiler/rustc_public/src/unstable/convert/internal.rs +++ b/compiler/rustc_public/src/unstable/convert/internal.rs @@ -738,6 +738,9 @@ impl RustcInternal for ProjectionElem { ProjectionElem::OpaqueCast(ty) => { rustc_middle::mir::PlaceElem::OpaqueCast(ty.internal(tables, tcx)) } + ProjectionElem::UnwrapUnsafeBinder(ty) => { + rustc_middle::mir::PlaceElem::UnwrapUnsafeBinder(ty.internal(tables, tcx)) + } } } } diff --git a/compiler/rustc_public/src/unstable/convert/stable/mir.rs b/compiler/rustc_public/src/unstable/convert/stable/mir.rs index d126304af8cde..d0b722a655198 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/mir.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/mir.rs @@ -245,7 +245,10 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { crate::mir::Rvalue::Aggregate(agg_kind.stable(tables, cx), operands) } CopyForDeref(place) => crate::mir::Rvalue::CopyForDeref(place.stable(tables, cx)), - WrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"), + WrapUnsafeBinder(op, ty) => crate::mir::Rvalue::WrapUnsafeBinder( + op.stable(tables, cx), + ty.stable(tables, cx), + ), } } } @@ -446,7 +449,9 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> { // found at https://github.com/rust-lang/rust/pull/117517#issuecomment-1811683486 Downcast(_, idx) => crate::mir::ProjectionElem::Downcast(idx.stable(tables, cx)), OpaqueCast(ty) => crate::mir::ProjectionElem::OpaqueCast(ty.stable(tables, cx)), - UnwrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"), + UnwrapUnsafeBinder(ty) => { + crate::mir::ProjectionElem::UnwrapUnsafeBinder(ty.stable(tables, cx)) + } } } }