unify dyn* coercions with other pointer coercions
This commit is contained in:
parent
67bb749c2e
commit
46ecb23198
23 changed files with 70 additions and 55 deletions
|
@ -2139,7 +2139,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
CastKind::DynStar => {
|
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
|
||||||
// get the constraints from the target type (`dyn* Clone`)
|
// get the constraints from the target type (`dyn* Clone`)
|
||||||
//
|
//
|
||||||
// apply them to prove that the source type `Foo` implements `Clone` etc
|
// apply them to prove that the source type `Foo` implements `Clone` etc
|
||||||
|
|
|
@ -770,7 +770,11 @@ fn codegen_stmt<'tcx>(
|
||||||
let operand = codegen_operand(fx, operand);
|
let operand = codegen_operand(fx, operand);
|
||||||
crate::unsize::coerce_unsized_into(fx, operand, lval);
|
crate::unsize::coerce_unsized_into(fx, operand, lval);
|
||||||
}
|
}
|
||||||
Rvalue::Cast(CastKind::DynStar, ref operand, _) => {
|
Rvalue::Cast(
|
||||||
|
CastKind::PointerCoercion(PointerCoercion::DynStar),
|
||||||
|
ref operand,
|
||||||
|
_,
|
||||||
|
) => {
|
||||||
let operand = codegen_operand(fx, operand);
|
let operand = codegen_operand(fx, operand);
|
||||||
crate::unsize::coerce_dyn_star(fx, operand, lval);
|
crate::unsize::coerce_dyn_star(fx, operand, lval);
|
||||||
}
|
}
|
||||||
|
|
|
@ -526,7 +526,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
bug!("unexpected non-pair operand");
|
bug!("unexpected non-pair operand");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::CastKind::DynStar => {
|
mir::CastKind::PointerCoercion(PointerCoercion::DynStar) => {
|
||||||
let (lldata, llextra) = operand.val.pointer_parts();
|
let (lldata, llextra) = operand.val.pointer_parts();
|
||||||
let (lldata, llextra) =
|
let (lldata, llextra) =
|
||||||
base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra);
|
base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra);
|
||||||
|
|
|
@ -447,8 +447,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
// These are all okay; they only change the type, not the data.
|
// These are all okay; they only change the type, not the data.
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), _, _) => {
|
Rvalue::Cast(
|
||||||
// Unsizing is implemented for CTFE.
|
CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar),
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
) => {
|
||||||
|
// Unsizing and `dyn*` coercions are implemented for CTFE.
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
|
Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
|
||||||
|
@ -458,10 +462,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
// Since no pointer can ever get exposed (rejected above), this is easy to support.
|
// Since no pointer can ever get exposed (rejected above), this is easy to support.
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::Cast(CastKind::DynStar, _, _) => {
|
|
||||||
// `dyn*` coercion is implemented for CTFE.
|
|
||||||
}
|
|
||||||
|
|
||||||
Rvalue::Cast(_, _, _) => {}
|
Rvalue::Cast(_, _, _) => {}
|
||||||
|
|
||||||
Rvalue::NullaryOp(
|
Rvalue::NullaryOp(
|
||||||
|
|
|
@ -125,7 +125,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CastKind::DynStar => {
|
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
|
||||||
if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() {
|
if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() {
|
||||||
// Initial cast from sized to dyn trait
|
// Initial cast from sized to dyn trait
|
||||||
let vtable = self.get_vtable_ptr(src.layout.ty, data)?;
|
let vtable = self.get_vtable_ptr(src.layout.ty, data)?;
|
||||||
|
|
|
@ -33,12 +33,12 @@ use rustc_errors::codes::*;
|
||||||
use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
|
use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
|
||||||
use rustc_hir::{self as hir, ExprKind};
|
use rustc_hir::{self as hir, ExprKind};
|
||||||
use rustc_macros::{TypeFoldable, TypeVisitable};
|
use rustc_macros::{TypeFoldable, TypeVisitable};
|
||||||
use rustc_middle::bug;
|
|
||||||
use rustc_middle::mir::Mutability;
|
use rustc_middle::mir::Mutability;
|
||||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||||
use rustc_middle::ty::cast::{CastKind, CastTy};
|
use rustc_middle::ty::cast::{CastKind, CastTy};
|
||||||
use rustc_middle::ty::error::TypeError;
|
use rustc_middle::ty::error::TypeError;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef};
|
||||||
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_span::def_id::LOCAL_CRATE;
|
use rustc_span::def_id::LOCAL_CRATE;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
@ -674,6 +674,16 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
use rustc_middle::ty::cast::CastTy::*;
|
use rustc_middle::ty::cast::CastTy::*;
|
||||||
use rustc_middle::ty::cast::IntTy::*;
|
use rustc_middle::ty::cast::IntTy::*;
|
||||||
|
|
||||||
|
if self.cast_ty.is_dyn_star() {
|
||||||
|
if fcx.tcx.features().dyn_star {
|
||||||
|
span_bug!(self.span, "should be handled by `coerce`");
|
||||||
|
} else {
|
||||||
|
// Report "casting is invalid" rather than "non-primitive cast"
|
||||||
|
// if the feature is not enabled.
|
||||||
|
return Err(CastError::IllegalCast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty))
|
let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty))
|
||||||
{
|
{
|
||||||
(Some(t_from), Some(t_cast)) => (t_from, t_cast),
|
(Some(t_from), Some(t_cast)) => (t_from, t_cast),
|
||||||
|
@ -780,16 +790,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
(Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),
|
(Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),
|
||||||
|
|
||||||
(Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
|
(Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
|
||||||
|
|
||||||
(_, DynStar) => {
|
|
||||||
if fcx.tcx.features().dyn_star {
|
|
||||||
bug!("should be handled by `coerce`")
|
|
||||||
} else {
|
|
||||||
Err(CastError::IllegalCast)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(DynStar, _) => Err(CastError::IllegalCast),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -769,7 +769,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(InferOk {
|
Ok(InferOk {
|
||||||
value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b),
|
value: (
|
||||||
|
vec![Adjustment { kind: Adjust::Pointer(PointerCoercion::DynStar), target: b }],
|
||||||
|
b,
|
||||||
|
),
|
||||||
obligations,
|
obligations,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -759,9 +759,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
||||||
for adjustment in adjustments {
|
for adjustment in adjustments {
|
||||||
debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment);
|
debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment);
|
||||||
match adjustment.kind {
|
match adjustment.kind {
|
||||||
adjustment::Adjust::NeverToAny
|
adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) => {
|
||||||
| adjustment::Adjust::Pointer(_)
|
|
||||||
| adjustment::Adjust::DynStar => {
|
|
||||||
// Creating a closure/fn-pointer or unsizing consumes
|
// Creating a closure/fn-pointer or unsizing consumes
|
||||||
// the input and stores it into the resulting rvalue.
|
// the input and stores it into the resulting rvalue.
|
||||||
self.consume_or_copy(&place_with_id, place_with_id.hir_id);
|
self.consume_or_copy(&place_with_id, place_with_id.hir_id);
|
||||||
|
@ -1296,8 +1294,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
||||||
adjustment::Adjust::NeverToAny
|
adjustment::Adjust::NeverToAny
|
||||||
| adjustment::Adjust::Pointer(_)
|
| adjustment::Adjust::Pointer(_)
|
||||||
| adjustment::Adjust::Borrow(_)
|
| adjustment::Adjust::Borrow(_)
|
||||||
| adjustment::Adjust::ReborrowPin(..)
|
| adjustment::Adjust::ReborrowPin(..) => {
|
||||||
| adjustment::Adjust::DynStar => {
|
|
||||||
// Result is an rvalue.
|
// Result is an rvalue.
|
||||||
Ok(self.cat_rvalue(expr.hir_id, target))
|
Ok(self.cat_rvalue(expr.hir_id, target))
|
||||||
}
|
}
|
||||||
|
|
|
@ -434,7 +434,6 @@ impl<'tcx> Rvalue<'tcx> {
|
||||||
| CastKind::PtrToPtr
|
| CastKind::PtrToPtr
|
||||||
| CastKind::PointerCoercion(_)
|
| CastKind::PointerCoercion(_)
|
||||||
| CastKind::PointerWithExposedProvenance
|
| CastKind::PointerWithExposedProvenance
|
||||||
| CastKind::DynStar
|
|
||||||
| CastKind::Transmute,
|
| CastKind::Transmute,
|
||||||
_,
|
_,
|
||||||
_,
|
_,
|
||||||
|
|
|
@ -1404,8 +1404,6 @@ pub enum CastKind {
|
||||||
///
|
///
|
||||||
/// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR.
|
/// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR.
|
||||||
PointerCoercion(PointerCoercion),
|
PointerCoercion(PointerCoercion),
|
||||||
/// Cast into a dyn* object.
|
|
||||||
DynStar,
|
|
||||||
IntToInt,
|
IntToInt,
|
||||||
FloatToInt,
|
FloatToInt,
|
||||||
FloatToFloat,
|
FloatToFloat,
|
||||||
|
|
|
@ -35,6 +35,9 @@ pub enum PointerCoercion {
|
||||||
/// type. Codegen backends and miri figure out what has to be done
|
/// type. Codegen backends and miri figure out what has to be done
|
||||||
/// based on the precise source/target type at hand.
|
/// based on the precise source/target type at hand.
|
||||||
Unsize,
|
Unsize,
|
||||||
|
|
||||||
|
/// Go from a pointer-like type to a `dyn*` object.
|
||||||
|
DynStar,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents coercing a value to a different type of value.
|
/// Represents coercing a value to a different type of value.
|
||||||
|
@ -102,9 +105,6 @@ pub enum Adjust<'tcx> {
|
||||||
|
|
||||||
Pointer(PointerCoercion),
|
Pointer(PointerCoercion),
|
||||||
|
|
||||||
/// Cast into a dyn* object.
|
|
||||||
DynStar,
|
|
||||||
|
|
||||||
/// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`.
|
/// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`.
|
||||||
ReborrowPin(ty::Region<'tcx>, hir::Mutability),
|
ReborrowPin(ty::Region<'tcx>, hir::Mutability),
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,15 +34,12 @@ pub enum CastTy<'tcx> {
|
||||||
FnPtr,
|
FnPtr,
|
||||||
/// Raw pointers.
|
/// Raw pointers.
|
||||||
Ptr(ty::TypeAndMut<'tcx>),
|
Ptr(ty::TypeAndMut<'tcx>),
|
||||||
/// Casting into a `dyn*` value.
|
|
||||||
DynStar,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cast Kind. See [RFC 401](https://rust-lang.github.io/rfcs/0401-coercions.html)
|
/// Cast Kind. See [RFC 401](https://rust-lang.github.io/rfcs/0401-coercions.html)
|
||||||
/// (or rustc_hir_analysis/check/cast.rs).
|
/// (or rustc_hir_analysis/check/cast.rs).
|
||||||
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||||
pub enum CastKind {
|
pub enum CastKind {
|
||||||
CoercionCast,
|
|
||||||
PtrPtrCast,
|
PtrPtrCast,
|
||||||
PtrAddrCast,
|
PtrAddrCast,
|
||||||
AddrPtrCast,
|
AddrPtrCast,
|
||||||
|
@ -53,7 +50,6 @@ pub enum CastKind {
|
||||||
ArrayPtrCast,
|
ArrayPtrCast,
|
||||||
FnPtrPtrCast,
|
FnPtrPtrCast,
|
||||||
FnPtrAddrCast,
|
FnPtrAddrCast,
|
||||||
DynStarCast,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> CastTy<'tcx> {
|
impl<'tcx> CastTy<'tcx> {
|
||||||
|
@ -71,7 +67,6 @@ impl<'tcx> CastTy<'tcx> {
|
||||||
ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)),
|
ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)),
|
||||||
ty::RawPtr(ty, mutbl) => Some(CastTy::Ptr(ty::TypeAndMut { ty, mutbl })),
|
ty::RawPtr(ty, mutbl) => Some(CastTy::Ptr(ty::TypeAndMut { ty, mutbl })),
|
||||||
ty::FnPtr(..) => Some(CastTy::FnPtr),
|
ty::FnPtr(..) => Some(CastTy::FnPtr),
|
||||||
ty::Dynamic(_, _, ty::DynStar) => Some(CastTy::DynStar),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +81,6 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin
|
||||||
mir::CastKind::PointerExposeProvenance
|
mir::CastKind::PointerExposeProvenance
|
||||||
}
|
}
|
||||||
(Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance,
|
(Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance,
|
||||||
(_, Some(CastTy::DynStar)) => mir::CastKind::DynStar,
|
|
||||||
(Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt,
|
(Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt,
|
||||||
(Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr,
|
(Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr,
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,6 @@ impl<'tcx> Cx<'tcx> {
|
||||||
Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
|
Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
|
||||||
ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
|
ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
|
||||||
}
|
}
|
||||||
Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) },
|
|
||||||
Adjust::ReborrowPin(region, mutbl) => {
|
Adjust::ReborrowPin(region, mutbl) => {
|
||||||
debug!("apply ReborrowPin adjustment");
|
debug!("apply ReborrowPin adjustment");
|
||||||
// Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }`
|
// Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }`
|
||||||
|
|
|
@ -70,11 +70,11 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> {
|
||||||
match *rvalue {
|
match *rvalue {
|
||||||
// We need to detect unsizing casts that required vtables.
|
// We need to detect unsizing casts that required vtables.
|
||||||
mir::Rvalue::Cast(
|
mir::Rvalue::Cast(
|
||||||
mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
|
mir::CastKind::PointerCoercion(PointerCoercion::Unsize)
|
||||||
|
| mir::CastKind::PointerCoercion(PointerCoercion::DynStar),
|
||||||
ref operand,
|
ref operand,
|
||||||
target_ty,
|
target_ty,
|
||||||
)
|
) => {
|
||||||
| mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => {
|
|
||||||
// This isn't monomorphized yet so we can't tell what the actual types are -- just
|
// This isn't monomorphized yet so we can't tell what the actual types are -- just
|
||||||
// add everything that may involve a vtable.
|
// add everything that may involve a vtable.
|
||||||
let source_ty = operand.ty(self.body, self.tcx);
|
let source_ty = operand.ty(self.body, self.tcx);
|
||||||
|
|
|
@ -1128,9 +1128,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
Rvalue::Cast(kind, operand, target_type) => {
|
Rvalue::Cast(kind, operand, target_type) => {
|
||||||
let op_ty = operand.ty(self.body, self.tcx);
|
let op_ty = operand.ty(self.body, self.tcx);
|
||||||
match kind {
|
match kind {
|
||||||
CastKind::DynStar => {
|
|
||||||
// FIXME(dyn-star): make sure nothing needs to be done here.
|
|
||||||
}
|
|
||||||
// FIXME: Add Checks for these
|
// FIXME: Add Checks for these
|
||||||
CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {}
|
CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {}
|
||||||
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
|
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
|
||||||
|
@ -1208,6 +1205,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
// This is used for all `CoerceUnsized` types,
|
// This is used for all `CoerceUnsized` types,
|
||||||
// not just pointers/references, so is hard to check.
|
// not just pointers/references, so is hard to check.
|
||||||
}
|
}
|
||||||
|
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
|
||||||
|
// FIXME(dyn-star): make sure nothing needs to be done here.
|
||||||
|
}
|
||||||
CastKind::IntToInt | CastKind::IntToFloat => {
|
CastKind::IntToInt | CastKind::IntToFloat => {
|
||||||
let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
|
let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
|
||||||
let target_valid = target_type.is_numeric() || target_type.is_char();
|
let target_valid = target_type.is_numeric() || target_type.is_char();
|
||||||
|
|
|
@ -665,11 +665,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
|
||||||
// have to instantiate all methods of the trait being cast to, so we
|
// have to instantiate all methods of the trait being cast to, so we
|
||||||
// can build the appropriate vtable.
|
// can build the appropriate vtable.
|
||||||
mir::Rvalue::Cast(
|
mir::Rvalue::Cast(
|
||||||
mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
|
mir::CastKind::PointerCoercion(PointerCoercion::Unsize)
|
||||||
|
| mir::CastKind::PointerCoercion(PointerCoercion::DynStar),
|
||||||
ref operand,
|
ref operand,
|
||||||
target_ty,
|
target_ty,
|
||||||
)
|
) => {
|
||||||
| mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => {
|
|
||||||
let source_ty = operand.ty(self.body, self.tcx);
|
let source_ty = operand.ty(self.body, self.tcx);
|
||||||
// *Before* monomorphizing, record that we already handled this mention.
|
// *Before* monomorphizing, record that we already handled this mention.
|
||||||
self.used_mentioned_items
|
self.used_mentioned_items
|
||||||
|
|
|
@ -282,11 +282,12 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
|
||||||
type T = stable_mir::mir::CastKind;
|
type T = stable_mir::mir::CastKind;
|
||||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||||
use rustc_middle::mir::CastKind::*;
|
use rustc_middle::mir::CastKind::*;
|
||||||
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
match self {
|
match self {
|
||||||
PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress,
|
PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress,
|
||||||
PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance,
|
PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance,
|
||||||
|
PointerCoercion(PointerCoercion::DynStar) => stable_mir::mir::CastKind::DynStar,
|
||||||
PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
|
PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
|
||||||
DynStar => stable_mir::mir::CastKind::DynStar,
|
|
||||||
IntToInt => stable_mir::mir::CastKind::IntToInt,
|
IntToInt => stable_mir::mir::CastKind::IntToInt,
|
||||||
FloatToInt => stable_mir::mir::CastKind::FloatToInt,
|
FloatToInt => stable_mir::mir::CastKind::FloatToInt,
|
||||||
FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,
|
FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,
|
||||||
|
|
|
@ -119,6 +119,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion {
|
||||||
}
|
}
|
||||||
PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer,
|
PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer,
|
||||||
PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize,
|
PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize,
|
||||||
|
PointerCoercion::DynStar => unreachable!("represented as `CastKind::DynStar` in smir"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -960,6 +960,7 @@ pub enum CastKind {
|
||||||
PointerExposeAddress,
|
PointerExposeAddress,
|
||||||
PointerWithExposedProvenance,
|
PointerWithExposedProvenance,
|
||||||
PointerCoercion(PointerCoercion),
|
PointerCoercion(PointerCoercion),
|
||||||
|
// FIXME(smir-rename): change this to PointerCoercion(DynStar)
|
||||||
DynStar,
|
DynStar,
|
||||||
IntToInt,
|
IntToInt,
|
||||||
FloatToInt,
|
FloatToInt,
|
||||||
|
|
|
@ -154,7 +154,7 @@ fn check_rvalue<'tcx>(
|
||||||
Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
|
Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
|
||||||
Err((span, "casting pointers to ints is unstable in const fn".into()))
|
Err((span, "casting pointers to ints is unstable in const fn".into()))
|
||||||
},
|
},
|
||||||
Rvalue::Cast(CastKind::DynStar, _, _) => {
|
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::DynStar), _, _) => {
|
||||||
// FIXME(dyn-star)
|
// FIXME(dyn-star)
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,7 +5,7 @@ trait Tr {}
|
||||||
|
|
||||||
fn f(x: dyn* Tr) -> usize {
|
fn f(x: dyn* Tr) -> usize {
|
||||||
x as usize
|
x as usize
|
||||||
//~^ ERROR casting `(dyn* Tr + 'static)` as `usize` is invalid
|
//~^ ERROR non-primitive cast: `(dyn* Tr + 'static)` as `usize`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
error[E0606]: casting `(dyn* Tr + 'static)` as `usize` is invalid
|
error[E0605]: non-primitive cast: `(dyn* Tr + 'static)` as `usize`
|
||||||
--> $DIR/dyn-to-rigid.rs:7:5
|
--> $DIR/dyn-to-rigid.rs:7:5
|
||||||
|
|
|
|
||||||
LL | x as usize
|
LL | x as usize
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0606`.
|
For more information about this error, try `rustc --explain E0605`.
|
||||||
|
|
18
tests/ui/dyn-star/enum-cast.rs
Normal file
18
tests/ui/dyn-star/enum-cast.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// This used to ICE, because the compiler confused a pointer-like to dyn* coercion
|
||||||
|
// with a c-like enum to integer cast.
|
||||||
|
|
||||||
|
#![feature(dyn_star)]
|
||||||
|
#![expect(incomplete_features)]
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
Num(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Trait {}
|
||||||
|
impl Trait for E {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = E::Num(42) as dyn* Trait;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue