diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_borrowck/src/type_check/mod.rs | 99 | ||||
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/base.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/constant.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/cast.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/check.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/validate.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/syntax.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/cast.rs | 26 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_rvalue.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_mir_dataflow/src/elaborate_drops.rs | 3 |
12 files changed, 168 insertions, 40 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index d03f0369648..a423569dd0f 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2209,25 +2209,104 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } } - - CastKind::Misc => { + CastKind::IntToInt => { let ty_from = op.ty(body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); - // Misc casts are either between floats and ints, or one ptr type to another. match (cast_ty_from, cast_ty_to) { - ( - Some(CastTy::Int(_) | CastTy::Float), - Some(CastTy::Int(_) | CastTy::Float), - ) - | (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Ptr(_))) => (), + (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => (), _ => { span_mirbug!( self, rvalue, - "Invalid Misc cast {:?} -> {:?}", + "Invalid IntToInt cast {:?} -> {:?}", ty_from, - ty, + ty + ) + } + } + } + CastKind::IntToFloat => { + let ty_from = op.ty(body, tcx); + let cast_ty_from = CastTy::from_ty(ty_from); + let cast_ty_to = CastTy::from_ty(*ty); + match (cast_ty_from, cast_ty_to) { + (Some(CastTy::Int(_)), Some(CastTy::Float)) => (), + _ => { + span_mirbug!( + self, + rvalue, + "Invalid IntToFloat cast {:?} -> {:?}", + ty_from, + ty + ) + } + } + } + CastKind::FloatToInt => { + let ty_from = op.ty(body, tcx); + let cast_ty_from = CastTy::from_ty(ty_from); + let cast_ty_to = CastTy::from_ty(*ty); + match (cast_ty_from, cast_ty_to) { + (Some(CastTy::Float), Some(CastTy::Int(_))) => (), + _ => { + span_mirbug!( + self, + rvalue, + "Invalid FloatToInt cast {:?} -> {:?}", + ty_from, + ty + ) + } + } + } + CastKind::FloatToFloat => { + let ty_from = op.ty(body, tcx); + let cast_ty_from = CastTy::from_ty(ty_from); + let cast_ty_to = CastTy::from_ty(*ty); + match (cast_ty_from, cast_ty_to) { + (Some(CastTy::Float), Some(CastTy::Float)) => (), + _ => { + span_mirbug!( + self, + rvalue, + "Invalid FloatToFloat cast {:?} -> {:?}", + ty_from, + ty + ) + } + } + } + CastKind::FnPtrToPtr => { + let ty_from = op.ty(body, tcx); + let cast_ty_from = CastTy::from_ty(ty_from); + let cast_ty_to = CastTy::from_ty(*ty); + match (cast_ty_from, cast_ty_to) { + (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => (), + _ => { + span_mirbug!( + self, + rvalue, + "Invalid FnPtrToPtr cast {:?} -> {:?}", + ty_from, + ty + ) + } + } + } + CastKind::PtrToPtr => { + let ty_from = op.ty(body, tcx); + let cast_ty_from = CastTy::from_ty(ty_from); + let cast_ty_to = CastTy::from_ty(*ty); + match (cast_ty_from, cast_ty_to) { + (Some(CastTy::Ptr(_)), Some(CastTy::Ptr(_))) => (), + _ => { + span_mirbug!( + self, + rvalue, + "Invalid PtrToPtr cast {:?} -> {:?}", + ty_from, + ty ) } } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 11540d80081..4303d63fe21 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -633,7 +633,12 @@ fn codegen_stmt<'tcx>( lval.write_cvalue(fx, operand.cast_pointer_to(to_layout)); } Rvalue::Cast( - CastKind::Misc + CastKind::IntToInt + | CastKind::FloatToFloat + | CastKind::FloatToInt + | CastKind::IntToFloat + | CastKind::FnPtrToPtr + | CastKind::PtrToPtr | CastKind::PointerExposeAddress | CastKind::PointerFromExposedAddress, ref operand, diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index e12805b093c..c5f44bb8479 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -490,7 +490,16 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( match &stmt.kind { StatementKind::Assign(local_and_rvalue) if &local_and_rvalue.0 == place => { match &local_and_rvalue.1 { - Rvalue::Cast(CastKind::Misc, operand, ty) => { + Rvalue::Cast( + CastKind::IntToInt + | CastKind::FloatToFloat + | CastKind::FloatToInt + | CastKind::IntToFloat + | CastKind::FnPtrToPtr + | CastKind::PtrToPtr, + operand, + ty, + ) => { if computed_const_val.is_some() { return None; // local assigned twice } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 56852b0fcc8..abf3c9a363f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -250,7 +250,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Pair(lldata, llextra) } mir::CastKind::Pointer(PointerCast::MutToConstPointer) - | mir::CastKind::Misc + | mir::CastKind::PtrToPtr if bx.cx().is_backend_scalar_pair(operand.layout) => { if let OperandValue::Pair(data_ptr, meta) = operand.val { @@ -290,7 +290,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::CastKind::Pointer( PointerCast::MutToConstPointer | PointerCast::ArrayToPointer, ) - | mir::CastKind::Misc + | mir::CastKind::IntToInt + | mir::CastKind::FloatToInt + | mir::CastKind::FloatToFloat + | mir::CastKind::IntToFloat + | mir::CastKind::PtrToPtr + | mir::CastKind::FnPtrToPtr + // Since int2ptr can have arbitrary integer types as input (so we have to do // sign extension and all that), it is currently best handled in the same code // path as the other integer-to-X casts. diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index cbe98548025..764224fd007 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -42,8 +42,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let res = self.pointer_from_exposed_address_cast(&src, cast_ty)?; self.write_immediate(res, dest)?; } - - Misc => { + // FIXME: We shouldn't use `misc_cast` for these but handle them separately. + IntToInt | FloatToInt | FloatToFloat | IntToFloat | FnPtrToPtr | PtrToPtr => { let src = self.read_immediate(src)?; let res = self.misc_cast(&src, cast_ty)?; self.write_immediate(res, dest)?; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index b0dcbf76b01..c42553b39e5 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -553,7 +553,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { unimplemented!() } - Rvalue::Cast(CastKind::Misc, _, _) => {} + Rvalue::Cast(_, _, _) => {} Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {} Rvalue::ShallowInitBox(_, _) => {} diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 9c95ffca19b..8abf767f89f 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -557,7 +557,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } Rvalue::Cast(kind, operand, target_type) => { match kind { - CastKind::Misc => { + CastKind::DynStar => { + // FIXME(dyn-star): make sure nothing needs to be done here. + } + // Nothing to check here + CastKind::PointerFromExposedAddress + | CastKind::PointerExposeAddress + | CastKind::Pointer(_) => {} + _ => { let op_ty = operand.ty(self.body, self.tcx); if op_ty.is_enum() { self.fail( @@ -568,13 +575,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } - CastKind::DynStar => { - // FIXME(dyn-star): make sure nothing needs to be done here. - } - // Nothing to check here - CastKind::PointerFromExposedAddress - | CastKind::PointerExposeAddress - | CastKind::Pointer(_) => {} } } Rvalue::Repeat(_, _) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 78a16788815..45d361803ea 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1834,7 +1834,14 @@ impl<'tcx> Rvalue<'tcx> { | Rvalue::AddressOf(_, _) | Rvalue::Len(_) | Rvalue::Cast( - CastKind::Misc | CastKind::Pointer(_) | CastKind::PointerFromExposedAddress, + CastKind::IntToInt + | CastKind::FloatToInt + | CastKind::FloatToFloat + | CastKind::IntToFloat + | CastKind::FnPtrToPtr + | CastKind::PtrToPtr + | CastKind::Pointer(_) + | CastKind::PointerFromExposedAddress, _, _, ) diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index ee8377d1987..9a22a12b93b 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1149,8 +1149,12 @@ pub enum CastKind { Pointer(PointerCast), /// Cast into a dyn* object. DynStar, - /// Remaining unclassified casts. - Misc, + IntToInt, + FloatToInt, + FloatToFloat, + IntToFloat, + PtrToPtr, + FnPtrToPtr, } #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index 2de27102bcc..e6558595519 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -2,6 +2,7 @@ // typeck and codegen. use crate::ty::{self, Ty}; +use rustc_middle::mir; use rustc_macros::HashStable; @@ -75,3 +76,28 @@ impl<'tcx> CastTy<'tcx> { } } } + +/// Returns `mir::CastKind` from the given parameters. +pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKind { + let from = CastTy::from_ty(from_ty); + let cast = CastTy::from_ty(cast_ty); + let cast_kind = match (from, cast) { + (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => { + mir::CastKind::PointerExposeAddress + } + (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerFromExposedAddress, + (_, Some(CastTy::DynStar)) => mir::CastKind::DynStar, + (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt, + (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr, + + (Some(CastTy::Float), Some(CastTy::Int(_))) => mir::CastKind::FloatToInt, + (Some(CastTy::Int(_)), Some(CastTy::Float)) => mir::CastKind::IntToFloat, + (Some(CastTy::Float), Some(CastTy::Float)) => mir::CastKind::FloatToFloat, + (Some(CastTy::Ptr(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PtrToPtr, + + (_, _) => { + bug!("Attempting to cast non-castable types {:?} and {:?}", from_ty, cast_ty) + } + }; + cast_kind +} diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 16295b1b19a..35a00da8d38 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -12,7 +12,7 @@ use rustc_middle::mir::AssertKind; use rustc_middle::mir::Place; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::ty::cast::CastTy; +use rustc_middle::ty::cast::{mir_cast_kind, CastTy}; use rustc_middle::ty::{self, Ty, UpvarSubsts}; use rustc_span::Span; @@ -217,16 +217,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let from_ty = CastTy::from_ty(ty); let cast_ty = CastTy::from_ty(expr.ty); debug!("ExprKind::Cast from_ty={from_ty:?}, cast_ty={:?}/{cast_ty:?}", expr.ty,); - let cast_kind = match (from_ty, cast_ty) { - (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => { - CastKind::PointerExposeAddress - } - (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => { - CastKind::PointerFromExposedAddress - } - (_, Some(CastTy::DynStar)) => CastKind::DynStar, - (_, _) => CastKind::Misc, - }; + let cast_kind = mir_cast_kind(ty, expr.ty); block.and(Rvalue::Cast(cast_kind, source, expr.ty)) } ExprKind::Pointer { cast, source } => { diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 702ca2eaf5c..23403628c53 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -823,9 +823,10 @@ where // tmp = &raw mut P; // cur = tmp as *mut T; // end = Offset(cur, len); + let mir_cast_kind = ty::cast::mir_cast_kind(iter_ty, tmp_ty); vec