Rollup merge of #130514 - compiler-errors:unsafe-binders, r=oli-obk
Implement MIR lowering for unsafe binders This is the final bit of the unsafe binders puzzle. It implements MIR, CTFE, and codegen for unsafe binders, and enforces that (for now) they are `Copy`. Later on, I'll introduce a new trait that relaxes this requirement to being "is `Copy` or `ManuallyDrop<T>`" which more closely models how we treat union fields. Namely, wrapping unsafe binders is now `Rvalue::WrapUnsafeBinder`, which acts much like an `Rvalue::Aggregate`. Unwrapping unsafe binders are implemented as a MIR projection `ProjectionElem::UnwrapUnsafeBinder`, which acts much like `ProjectionElem::Field`. Tracking: - https://github.com/rust-lang/rust/issues/130516
This commit is contained in:
commit
2fd3007cbc
56 changed files with 589 additions and 102 deletions
|
@ -728,6 +728,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
Rvalue::WrapUnsafeBinder(..) => {
|
||||
// Unsafe binders are always trivial to create.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -258,6 +258,8 @@ where
|
|||
in_place::<Q, _>(cx, in_local, place.as_ref())
|
||||
}
|
||||
|
||||
Rvalue::WrapUnsafeBinder(op, _) => in_operand::<Q, _>(cx, in_local, op),
|
||||
|
||||
Rvalue::Aggregate(kind, operands) => {
|
||||
// Return early if we know that the struct or enum being constructed is always
|
||||
// qualified.
|
||||
|
@ -297,7 +299,8 @@ where
|
|||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Downcast(_, _)
|
||||
| ProjectionElem::Index(_) => {}
|
||||
| ProjectionElem::Index(_)
|
||||
| ProjectionElem::UnwrapUnsafeBinder(_) => {}
|
||||
}
|
||||
|
||||
let base_ty = place_base.ty(cx.body, cx.tcx);
|
||||
|
|
|
@ -202,7 +202,8 @@ where
|
|||
| mir::Rvalue::NullaryOp(..)
|
||||
| mir::Rvalue::UnaryOp(..)
|
||||
| mir::Rvalue::Discriminant(..)
|
||||
| mir::Rvalue::Aggregate(..) => {}
|
||||
| mir::Rvalue::Aggregate(..)
|
||||
| mir::Rvalue::WrapUnsafeBinder(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -381,6 +381,7 @@ where
|
|||
OpaqueCast(ty) => {
|
||||
span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck")
|
||||
}
|
||||
UnwrapUnsafeBinder(target) => base.transmute(self.layout_of(target)?, self)?,
|
||||
// We don't want anything happening here, this is here as a dummy.
|
||||
Subtype(_) => base.transmute(base.layout(), self)?,
|
||||
Field(field, _) => self.project_field(base, field.index())?,
|
||||
|
|
|
@ -277,6 +277,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let discr = self.discriminant_for_variant(op.layout.ty, variant)?;
|
||||
self.write_immediate(*discr, &dest)?;
|
||||
}
|
||||
|
||||
WrapUnsafeBinder(ref op, _ty) => {
|
||||
// Constructing an unsafe binder acts like a transmute
|
||||
// since the operand's layout does not change.
|
||||
let op = self.eval_operand(op, None)?;
|
||||
self.copy_op_allow_transmute(&op, &dest)?;
|
||||
}
|
||||
}
|
||||
|
||||
trace!("{:?}", self.dump_place(&dest));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue