ProjectionElem::Subtype -> CastKind::Subtype
This commit is contained in:
@@ -3974,7 +3974,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
}
|
||||
ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Subtype(_)
|
||||
| ProjectionElem::Index(_)
|
||||
| ProjectionElem::UnwrapUnsafeBinder(_) => kind,
|
||||
},
|
||||
|
||||
@@ -402,7 +402,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
ProjectionElem::Downcast(..) if opt.including_downcast => return None,
|
||||
ProjectionElem::Downcast(..) => (),
|
||||
ProjectionElem::OpaqueCast(..) => (),
|
||||
ProjectionElem::Subtype(..) => (),
|
||||
ProjectionElem::UnwrapUnsafeBinder(_) => (),
|
||||
ProjectionElem::Field(field, _ty) => {
|
||||
// FIXME(project-rfc_2229#36): print capture precisely here.
|
||||
@@ -484,9 +483,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)
|
||||
| ProjectionElem::UnwrapUnsafeBinder(ty) => PlaceTy::from_ty(*ty),
|
||||
ProjectionElem::OpaqueCast(ty) | ProjectionElem::UnwrapUnsafeBinder(ty) => {
|
||||
PlaceTy::from_ty(*ty)
|
||||
}
|
||||
ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -192,7 +192,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
[
|
||||
..,
|
||||
ProjectionElem::Index(_)
|
||||
| ProjectionElem::Subtype(_)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::OpaqueCast { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
|
||||
@@ -1989,10 +1989,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
||||
},
|
||||
// `OpaqueCast`: only transmutes the type, so no moves there.
|
||||
// `Downcast` : only changes information about a `Place` without moving.
|
||||
// `Subtype` : only transmutes the type, so no moves.
|
||||
// So it's safe to skip these.
|
||||
ProjectionElem::OpaqueCast(_)
|
||||
| ProjectionElem::Subtype(_)
|
||||
| ProjectionElem::Downcast(_, _)
|
||||
| ProjectionElem::UnwrapUnsafeBinder(_) => (),
|
||||
}
|
||||
@@ -2218,7 +2216,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
||||
for (place_base, elem) in place.iter_projections().rev() {
|
||||
match elem {
|
||||
ProjectionElem::Index(_/*operand*/) |
|
||||
ProjectionElem::Subtype(_) |
|
||||
ProjectionElem::OpaqueCast(_) |
|
||||
ProjectionElem::ConstantIndex { .. } |
|
||||
// assigning to P[i] requires P to be valid.
|
||||
@@ -2610,7 +2607,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
||||
| ProjectionElem::Index(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Subtype(..)
|
||||
| ProjectionElem::OpaqueCast { .. }
|
||||
| ProjectionElem::Downcast(..)
|
||||
| ProjectionElem::UnwrapUnsafeBinder(_) => {
|
||||
|
||||
@@ -249,7 +249,6 @@ fn place_components_conflict<'tcx>(
|
||||
| (ProjectionElem::ConstantIndex { .. }, _, _)
|
||||
| (ProjectionElem::Subslice { .. }, _, _)
|
||||
| (ProjectionElem::OpaqueCast { .. }, _, _)
|
||||
| (ProjectionElem::Subtype(_), _, _)
|
||||
| (ProjectionElem::Downcast { .. }, _, _)
|
||||
| (ProjectionElem::UnwrapUnsafeBinder(_), _, _) => {
|
||||
// Recursive case. This can still be disjoint on a
|
||||
@@ -510,7 +509,6 @@ fn place_projection_conflict<'tcx>(
|
||||
| ProjectionElem::Field(..)
|
||||
| ProjectionElem::Index(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subtype(_)
|
||||
| ProjectionElem::OpaqueCast { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Downcast(..),
|
||||
|
||||
@@ -77,9 +77,6 @@ impl<'tcx> Iterator for Prefixes<'tcx> {
|
||||
| ProjectionElem::Index(_) => {
|
||||
cursor = cursor_base;
|
||||
}
|
||||
ProjectionElem::Subtype(..) => {
|
||||
panic!("Subtype projection is not allowed before borrow check")
|
||||
}
|
||||
ProjectionElem::Deref => {
|
||||
match self.kind {
|
||||
PrefixSet::Shallow => {
|
||||
|
||||
@@ -1558,6 +1558,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
),
|
||||
}
|
||||
}
|
||||
CastKind::Subtype => {
|
||||
bug!("CastKind::Subtype shouldn't exist in borrowck")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1882,9 +1885,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
ProjectionElem::Subtype(_) => {
|
||||
bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2412,9 +2412,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
| ProjectionElem::UnwrapUnsafeBinder(_) => {
|
||||
// other field access
|
||||
}
|
||||
ProjectionElem::Subtype(_) => {
|
||||
bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -789,7 +789,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
|
||||
let operand = codegen_operand(fx, operand);
|
||||
crate::unsize::coerce_unsized_into(fx, operand, lval);
|
||||
}
|
||||
Rvalue::Cast(CastKind::Transmute, ref operand, _to_ty) => {
|
||||
Rvalue::Cast(CastKind::Transmute | CastKind::Subtype, ref operand, _to_ty) => {
|
||||
let operand = codegen_operand(fx, operand);
|
||||
lval.write_cvalue_transmute(fx, operand);
|
||||
}
|
||||
@@ -996,7 +996,7 @@ pub(crate) fn codegen_place<'tcx>(
|
||||
cplace = cplace.place_deref(fx);
|
||||
}
|
||||
PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"),
|
||||
PlaceElem::Subtype(ty) | PlaceElem::UnwrapUnsafeBinder(ty) => {
|
||||
PlaceElem::UnwrapUnsafeBinder(ty) => {
|
||||
cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty));
|
||||
}
|
||||
PlaceElem::Field(field, _ty) => {
|
||||
|
||||
@@ -660,7 +660,7 @@ impl<'tcx> CPlace<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Used for `ProjectionElem::Subtype`, `ty` has to be monomorphized before
|
||||
/// Used for `ProjectionElem::UnwrapUnsafeBinder`, `ty` has to be monomorphized before
|
||||
/// passed on.
|
||||
pub(crate) fn place_transmute_type(
|
||||
self,
|
||||
|
||||
@@ -150,10 +150,6 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> LocalAnalyzer<'a, 'b, 'tcx, Bx>
|
||||
{
|
||||
layout.for_variant(self.fx.cx, vidx)
|
||||
}
|
||||
mir::PlaceElem::Subtype(subtype_ty) => {
|
||||
let subtype_ty = self.fx.monomorphize(subtype_ty);
|
||||
self.fx.cx.layout_of(subtype_ty)
|
||||
}
|
||||
_ => {
|
||||
self.locals[place_ref.local] = LocalKind::Memory;
|
||||
return;
|
||||
|
||||
@@ -956,11 +956,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let layout = o.layout.for_variant(bx.cx(), vidx);
|
||||
o = OperandRef { val: o.val, layout }
|
||||
}
|
||||
mir::PlaceElem::Subtype(subtype_ty) => {
|
||||
let subtype_ty = self.monomorphize(subtype_ty);
|
||||
let layout = self.cx.layout_of(subtype_ty);
|
||||
o = OperandRef { val: o.val, layout }
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +347,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
mir::ProjectionElem::OpaqueCast(ty) => {
|
||||
bug!("encountered OpaqueCast({ty}) in codegen")
|
||||
}
|
||||
mir::ProjectionElem::Subtype(ty) => cg_base.project_type(bx, self.monomorphize(ty)),
|
||||
mir::ProjectionElem::UnwrapUnsafeBinder(ty) => {
|
||||
cg_base.project_type(bx, self.monomorphize(ty))
|
||||
}
|
||||
|
||||
@@ -86,7 +86,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
}
|
||||
|
||||
mir::Rvalue::Cast(mir::CastKind::Transmute, ref operand, _ty) => {
|
||||
mir::Rvalue::Cast(
|
||||
mir::CastKind::Transmute | mir::CastKind::Subtype,
|
||||
ref operand,
|
||||
_ty,
|
||||
) => {
|
||||
let src = self.codegen_operand(bx, operand);
|
||||
self.codegen_transmute(bx, src, dest);
|
||||
}
|
||||
@@ -486,7 +490,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
bug!("Unsupported cast of {operand:?} to {cast:?}");
|
||||
})
|
||||
}
|
||||
mir::CastKind::Transmute => {
|
||||
mir::CastKind::Transmute | mir::CastKind::Subtype => {
|
||||
self.codegen_transmute_operand(bx, operand, cast)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -293,7 +293,6 @@ where
|
||||
ProjectionElem::Index(index) if in_local(index) => return true,
|
||||
|
||||
ProjectionElem::Deref
|
||||
| ProjectionElem::Subtype(_)
|
||||
| ProjectionElem::Field(_, _)
|
||||
| ProjectionElem::OpaqueCast(_)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
|
||||
@@ -133,7 +133,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
}
|
||||
}
|
||||
|
||||
CastKind::Transmute => {
|
||||
CastKind::Transmute | CastKind::Subtype => {
|
||||
assert!(src.layout.is_sized());
|
||||
assert!(dest.layout.is_sized());
|
||||
assert_eq!(cast_ty, dest.layout.ty); // we otherwise ignore `cast_ty` enirely...
|
||||
|
||||
@@ -395,8 +395,6 @@ where
|
||||
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)?,
|
||||
Downcast(_, variant) => self.project_downcast(base, variant)?,
|
||||
Deref => self.deref_pointer(&base.to_op(self)?)?.into(),
|
||||
|
||||
@@ -1274,7 +1274,6 @@ fn pre_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
|
||||
for &elem in projection.iter().rev() {
|
||||
match elem {
|
||||
ProjectionElem::OpaqueCast(_)
|
||||
| ProjectionElem::Subtype(_)
|
||||
| ProjectionElem::Downcast(_, _)
|
||||
| ProjectionElem::Field(_, _) => {
|
||||
write!(fmt, "(")?;
|
||||
@@ -1300,9 +1299,6 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
|
||||
ProjectionElem::OpaqueCast(ty) => {
|
||||
write!(fmt, " as {ty})")?;
|
||||
}
|
||||
ProjectionElem::Subtype(ty) => {
|
||||
write!(fmt, " as subtype {ty})")?;
|
||||
}
|
||||
ProjectionElem::Downcast(Some(name), _index) => {
|
||||
write!(fmt, " as {name})")?;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,6 @@ impl<'tcx> PlaceTy<'tcx> {
|
||||
fty,
|
||||
)),
|
||||
ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(handle_opaque_cast_and_subtype(ty)),
|
||||
ProjectionElem::Subtype(ty) => PlaceTy::from_ty(handle_opaque_cast_and_subtype(ty)),
|
||||
|
||||
// FIXME(unsafe_binders): Rename `handle_opaque_cast_and_subtype` to be more general.
|
||||
ProjectionElem::UnwrapUnsafeBinder(ty) => {
|
||||
@@ -244,7 +243,6 @@ impl<V, T> ProjectionElem<V, T> {
|
||||
Self::Field(_, _)
|
||||
| Self::Index(_)
|
||||
| Self::OpaqueCast(_)
|
||||
| Self::Subtype(_)
|
||||
| Self::ConstantIndex { .. }
|
||||
| Self::Subslice { .. }
|
||||
| Self::Downcast(_, _)
|
||||
@@ -259,7 +257,6 @@ impl<V, T> ProjectionElem<V, T> {
|
||||
Self::Deref | Self::Index(_) => false,
|
||||
Self::Field(_, _)
|
||||
| Self::OpaqueCast(_)
|
||||
| Self::Subtype(_)
|
||||
| Self::ConstantIndex { .. }
|
||||
| Self::Subslice { .. }
|
||||
| Self::Downcast(_, _)
|
||||
@@ -286,7 +283,6 @@ impl<V, T> ProjectionElem<V, T> {
|
||||
| Self::Field(_, _) => true,
|
||||
Self::ConstantIndex { from_end: true, .. }
|
||||
| Self::Index(_)
|
||||
| Self::Subtype(_)
|
||||
| Self::OpaqueCast(_)
|
||||
| Self::Subslice { .. } => false,
|
||||
|
||||
@@ -319,7 +315,6 @@ impl<V, T> ProjectionElem<V, T> {
|
||||
ProjectionElem::Subslice { from, to, from_end }
|
||||
}
|
||||
ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(t(ty)),
|
||||
ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(t(ty)),
|
||||
ProjectionElem::UnwrapUnsafeBinder(ty) => ProjectionElem::UnwrapUnsafeBinder(t(ty)),
|
||||
ProjectionElem::Index(val) => ProjectionElem::Index(v(val)?),
|
||||
})
|
||||
@@ -706,7 +701,8 @@ impl<'tcx> Rvalue<'tcx> {
|
||||
| CastKind::PtrToPtr
|
||||
| CastKind::PointerCoercion(_, _)
|
||||
| CastKind::PointerWithExposedProvenance
|
||||
| CastKind::Transmute,
|
||||
| CastKind::Transmute
|
||||
| CastKind::Subtype,
|
||||
_,
|
||||
_,
|
||||
)
|
||||
|
||||
@@ -1275,18 +1275,6 @@ pub enum ProjectionElem<V, 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.
|
||||
///
|
||||
/// This projection doesn't impact the runtime behavior of the program except for potentially changing
|
||||
/// some type metadata of the interpreter or codegen backend.
|
||||
///
|
||||
/// This goal is achieved with mir_transform pass `Subtyper`, which runs right after
|
||||
/// borrowchecker, as we only care about subtyping that can affect trait selection and
|
||||
/// `TypeId`.
|
||||
Subtype(T),
|
||||
}
|
||||
|
||||
/// Alias for projections as they appear in places, where the base is a place
|
||||
@@ -1513,6 +1501,18 @@ pub enum CastKind {
|
||||
/// MIR is well-formed if the input and output types have different sizes,
|
||||
/// but running a transmute between differently-sized types is UB.
|
||||
Transmute,
|
||||
|
||||
/// A `Subtype` cast 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.
|
||||
///
|
||||
/// This cast doesn't impact the runtime behavior of the program except for potentially changing
|
||||
/// some type metadata of the interpreter or codegen backend.
|
||||
///
|
||||
/// This goal is achieved with mir_transform pass `Subtyper`, which runs right after
|
||||
/// borrowchecker, as we only care about subtyping that can affect trait selection and
|
||||
/// `TypeId`.
|
||||
Subtype,
|
||||
}
|
||||
|
||||
/// Represents how a [`CastKind::PointerCoercion`] was constructed.
|
||||
|
||||
@@ -1166,11 +1166,6 @@ macro_rules! visit_place_fns {
|
||||
self.visit_ty(&mut new_ty, TyContext::Location(location));
|
||||
if ty != new_ty { Some(PlaceElem::OpaqueCast(new_ty)) } else { None }
|
||||
}
|
||||
PlaceElem::Subtype(ty) => {
|
||||
let mut new_ty = ty;
|
||||
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));
|
||||
@@ -1244,7 +1239,6 @@ macro_rules! visit_place_fns {
|
||||
) {
|
||||
match elem {
|
||||
ProjectionElem::OpaqueCast(ty)
|
||||
| ProjectionElem::Subtype(ty)
|
||||
| ProjectionElem::Field(_, ty)
|
||||
| ProjectionElem::UnwrapUnsafeBinder(ty) => {
|
||||
self.visit_ty(ty, TyContext::Location(location));
|
||||
|
||||
@@ -103,7 +103,7 @@ fn convert_to_hir_projections_and_truncate_for_capture(
|
||||
}
|
||||
ProjectionElem::UnwrapUnsafeBinder(_) => HirProjectionKind::UnwrapUnsafeBinder,
|
||||
// These do not affect anything, they just make sure we know the right type.
|
||||
ProjectionElem::OpaqueCast(_) | ProjectionElem::Subtype(..) => continue,
|
||||
ProjectionElem::OpaqueCast(_) => continue,
|
||||
ProjectionElem::Index(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. } => {
|
||||
@@ -802,7 +802,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
ProjectionElem::Field(..)
|
||||
| ProjectionElem::Downcast(..)
|
||||
| ProjectionElem::OpaqueCast(..)
|
||||
| ProjectionElem::Subtype(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::UnwrapUnsafeBinder(_) => (),
|
||||
|
||||
@@ -227,11 +227,8 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
|
||||
ProjectionElem::UnwrapUnsafeBinder(_) => {}
|
||||
// `OpaqueCast`:Only transmutes the type, so no moves there.
|
||||
// `Downcast` :Only changes information about a `Place` without moving.
|
||||
// `Subtype` :Only transmutes the type, so moves.
|
||||
// So it's safe to skip these.
|
||||
ProjectionElem::OpaqueCast(_)
|
||||
| ProjectionElem::Subtype(_)
|
||||
| ProjectionElem::Downcast(_, _) => (),
|
||||
ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (),
|
||||
}
|
||||
let elem_ty = PlaceTy::from_ty(place_ty).projection_ty(tcx, elem).ty;
|
||||
if !(self.filter)(elem_ty) {
|
||||
|
||||
@@ -40,8 +40,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
|
||||
.new_temp(rval_ty, self.local_decls[place.as_ref().local].source_info.span);
|
||||
let new_place = Place::from(temp);
|
||||
self.patcher.add_assign(location, new_place, rvalue.clone());
|
||||
let subtyped = new_place.project_deeper(&[ProjectionElem::Subtype(place_ty)], self.tcx);
|
||||
*rvalue = Rvalue::Use(Operand::Move(subtyped));
|
||||
*rvalue = Rvalue::Cast(CastKind::Subtype, Operand::Move(new_place), place_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
|
||||
FlatSet::Top => FlatSet::Top,
|
||||
}
|
||||
}
|
||||
Rvalue::Cast(CastKind::Transmute, operand, _) => {
|
||||
Rvalue::Cast(CastKind::Transmute | CastKind::Subtype, operand, _) => {
|
||||
match self.eval_operand(operand, state) {
|
||||
FlatSet::Elem(op) => self.wrap_immediate(*op),
|
||||
FlatSet::Bottom => FlatSet::Bottom,
|
||||
|
||||
@@ -656,7 +656,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||
let res = self.ecx.float_to_float_or_int(&value, ty).discard_err()?;
|
||||
res.into()
|
||||
}
|
||||
CastKind::Transmute => {
|
||||
CastKind::Transmute | CastKind::Subtype => {
|
||||
let value = self.evaluated[value].as_ref()?;
|
||||
// `offset` for immediates generally only supports projections that match the
|
||||
// type of the immediate. However, as a HACK, we exploit that it can also do
|
||||
@@ -788,7 +788,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||
ProjectionElem::Subslice { from, to, from_end }
|
||||
}
|
||||
ProjectionElem::OpaqueCast(_) => ProjectionElem::OpaqueCast(()),
|
||||
ProjectionElem::Subtype(_) => ProjectionElem::Subtype(()),
|
||||
ProjectionElem::UnwrapUnsafeBinder(_) => ProjectionElem::UnwrapUnsafeBinder(()),
|
||||
};
|
||||
|
||||
|
||||
@@ -637,7 +637,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
let res = self.ecx.float_to_float_or_int(&value, to).discard_err()?;
|
||||
res.into()
|
||||
}
|
||||
CastKind::Transmute => {
|
||||
CastKind::Transmute | CastKind::Subtype => {
|
||||
let value = self.eval_operand(value)?;
|
||||
let to = self.ecx.layout_of(to).ok()?;
|
||||
// `offset` for immediates only supports scalar/scalar-pair ABIs,
|
||||
|
||||
@@ -292,7 +292,6 @@ impl<'tcx> Validator<'_, 'tcx> {
|
||||
match elem {
|
||||
// Recurse directly.
|
||||
ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subtype(_)
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::UnwrapUnsafeBinder(_) => {}
|
||||
|
||||
|
||||
@@ -814,22 +814,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
ProjectionElem::Subtype(ty) => {
|
||||
if !util::sub_types(
|
||||
self.tcx,
|
||||
self.typing_env,
|
||||
ty,
|
||||
place_ref.ty(&self.body.local_decls, self.tcx).ty,
|
||||
) {
|
||||
self.fail(
|
||||
location,
|
||||
format!(
|
||||
"Failed subtyping {ty} and {}",
|
||||
place_ref.ty(&self.body.local_decls, self.tcx).ty
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
ProjectionElem::UnwrapUnsafeBinder(unwrapped_ty) => {
|
||||
let binder_ty = place_ref.ty(&self.body.local_decls, self.tcx);
|
||||
let ty::UnsafeBinder(binder_ty) = *binder_ty.ty.kind() else {
|
||||
@@ -1331,6 +1315,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
}
|
||||
CastKind::Subtype => {
|
||||
if !util::sub_types(self.tcx, self.typing_env, op_ty, *target_type) {
|
||||
self.fail(
|
||||
location,
|
||||
format!("Failed subtyping {op_ty} and {target_type}"),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Rvalue::NullaryOp(NullOp::OffsetOf(indices), container) => {
|
||||
|
||||
@@ -836,14 +836,6 @@ pub enum ProjectionElem {
|
||||
/// Like an explicit cast from an opaque type to a concrete type, but without
|
||||
/// requiring an intermediate variable.
|
||||
OpaqueCast(Ty),
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// This projection doesn't impact the runtime behavior of the program except for potentially changing
|
||||
/// some type metadata of the interpreter or codegen backend.
|
||||
Subtype(Ty),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
@@ -1028,6 +1020,7 @@ pub enum CastKind {
|
||||
PtrToPtr,
|
||||
FnPtrToPtr,
|
||||
Transmute,
|
||||
Subtype,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
@@ -1089,7 +1082,7 @@ impl ProjectionElem {
|
||||
Self::subslice_ty(ty, *from, *to, *from_end)
|
||||
}
|
||||
ProjectionElem::Downcast(_) => Ok(ty),
|
||||
ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => Ok(*ty),
|
||||
ProjectionElem::OpaqueCast(ty) => Ok(*ty),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -471,7 +471,6 @@ macro_rules! visit_place_fns {
|
||||
ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {}
|
||||
ProjectionElem::Downcast(_idx) => {}
|
||||
ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location),
|
||||
ProjectionElem::Subtype(ty) => self.visit_ty(ty, location),
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -512,7 +511,6 @@ macro_rules! visit_place_fns {
|
||||
ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {}
|
||||
ProjectionElem::Downcast(_idx) => {}
|
||||
ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location),
|
||||
ProjectionElem::Subtype(ty) => self.visit_ty(ty, location),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -703,9 +703,6 @@ impl RustcInternal for ProjectionElem {
|
||||
ProjectionElem::OpaqueCast(ty) => {
|
||||
rustc_middle::mir::PlaceElem::OpaqueCast(ty.internal(tables, tcx))
|
||||
}
|
||||
ProjectionElem::Subtype(ty) => {
|
||||
rustc_middle::mir::PlaceElem::Subtype(ty.internal(tables, tcx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,6 +356,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
|
||||
PtrToPtr => crate::mir::CastKind::PtrToPtr,
|
||||
FnPtrToPtr => crate::mir::CastKind::FnPtrToPtr,
|
||||
Transmute => crate::mir::CastKind::Transmute,
|
||||
Subtype => crate::mir::CastKind::Subtype,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -453,7 +454,6 @@ 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)),
|
||||
Subtype(ty) => crate::mir::ProjectionElem::Subtype(ty.stable(tables, cx)),
|
||||
UnwrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user