Skip to content

Commit 4e17bf2

Browse files
authored
Rollup merge of rust-lang#102675 - ouz-a:mir-technical-debt, r=oli-obk
Remove `mir::CastKind::Misc` As discussed in rust-lang#97649 `mir::CastKind::Misc` is not clear, this PR addresses that by creating a new enum variant for every valid cast. r? ```@oli-obk```
2 parents 7ac690a + d59c7ff commit 4e17bf2

25 files changed

+190
-57
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+89-10
Original file line numberDiff line numberDiff line change
@@ -2209,25 +2209,104 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22092209
}
22102210
}
22112211
}
2212-
2213-
CastKind::Misc => {
2212+
CastKind::IntToInt => {
22142213
let ty_from = op.ty(body, tcx);
22152214
let cast_ty_from = CastTy::from_ty(ty_from);
22162215
let cast_ty_to = CastTy::from_ty(*ty);
2217-
// Misc casts are either between floats and ints, or one ptr type to another.
22182216
match (cast_ty_from, cast_ty_to) {
2219-
(
2220-
Some(CastTy::Int(_) | CastTy::Float),
2221-
Some(CastTy::Int(_) | CastTy::Float),
2222-
)
2223-
| (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Ptr(_))) => (),
2217+
(Some(CastTy::Int(_)), Some(CastTy::Int(_))) => (),
22242218
_ => {
22252219
span_mirbug!(
22262220
self,
22272221
rvalue,
2228-
"Invalid Misc cast {:?} -> {:?}",
2222+
"Invalid IntToInt cast {:?} -> {:?}",
22292223
ty_from,
2230-
ty,
2224+
ty
2225+
)
2226+
}
2227+
}
2228+
}
2229+
CastKind::IntToFloat => {
2230+
let ty_from = op.ty(body, tcx);
2231+
let cast_ty_from = CastTy::from_ty(ty_from);
2232+
let cast_ty_to = CastTy::from_ty(*ty);
2233+
match (cast_ty_from, cast_ty_to) {
2234+
(Some(CastTy::Int(_)), Some(CastTy::Float)) => (),
2235+
_ => {
2236+
span_mirbug!(
2237+
self,
2238+
rvalue,
2239+
"Invalid IntToFloat cast {:?} -> {:?}",
2240+
ty_from,
2241+
ty
2242+
)
2243+
}
2244+
}
2245+
}
2246+
CastKind::FloatToInt => {
2247+
let ty_from = op.ty(body, tcx);
2248+
let cast_ty_from = CastTy::from_ty(ty_from);
2249+
let cast_ty_to = CastTy::from_ty(*ty);
2250+
match (cast_ty_from, cast_ty_to) {
2251+
(Some(CastTy::Float), Some(CastTy::Int(_))) => (),
2252+
_ => {
2253+
span_mirbug!(
2254+
self,
2255+
rvalue,
2256+
"Invalid FloatToInt cast {:?} -> {:?}",
2257+
ty_from,
2258+
ty
2259+
)
2260+
}
2261+
}
2262+
}
2263+
CastKind::FloatToFloat => {
2264+
let ty_from = op.ty(body, tcx);
2265+
let cast_ty_from = CastTy::from_ty(ty_from);
2266+
let cast_ty_to = CastTy::from_ty(*ty);
2267+
match (cast_ty_from, cast_ty_to) {
2268+
(Some(CastTy::Float), Some(CastTy::Float)) => (),
2269+
_ => {
2270+
span_mirbug!(
2271+
self,
2272+
rvalue,
2273+
"Invalid FloatToFloat cast {:?} -> {:?}",
2274+
ty_from,
2275+
ty
2276+
)
2277+
}
2278+
}
2279+
}
2280+
CastKind::FnPtrToPtr => {
2281+
let ty_from = op.ty(body, tcx);
2282+
let cast_ty_from = CastTy::from_ty(ty_from);
2283+
let cast_ty_to = CastTy::from_ty(*ty);
2284+
match (cast_ty_from, cast_ty_to) {
2285+
(Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => (),
2286+
_ => {
2287+
span_mirbug!(
2288+
self,
2289+
rvalue,
2290+
"Invalid FnPtrToPtr cast {:?} -> {:?}",
2291+
ty_from,
2292+
ty
2293+
)
2294+
}
2295+
}
2296+
}
2297+
CastKind::PtrToPtr => {
2298+
let ty_from = op.ty(body, tcx);
2299+
let cast_ty_from = CastTy::from_ty(ty_from);
2300+
let cast_ty_to = CastTy::from_ty(*ty);
2301+
match (cast_ty_from, cast_ty_to) {
2302+
(Some(CastTy::Ptr(_)), Some(CastTy::Ptr(_))) => (),
2303+
_ => {
2304+
span_mirbug!(
2305+
self,
2306+
rvalue,
2307+
"Invalid PtrToPtr cast {:?} -> {:?}",
2308+
ty_from,
2309+
ty
22312310
)
22322311
}
22332312
}

compiler/rustc_codegen_cranelift/src/base.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,12 @@ fn codegen_stmt<'tcx>(
633633
lval.write_cvalue(fx, operand.cast_pointer_to(to_layout));
634634
}
635635
Rvalue::Cast(
636-
CastKind::Misc
636+
CastKind::IntToInt
637+
| CastKind::FloatToFloat
638+
| CastKind::FloatToInt
639+
| CastKind::IntToFloat
640+
| CastKind::FnPtrToPtr
641+
| CastKind::PtrToPtr
637642
| CastKind::PointerExposeAddress
638643
| CastKind::PointerFromExposedAddress,
639644
ref operand,

compiler/rustc_codegen_cranelift/src/constant.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,16 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
490490
match &stmt.kind {
491491
StatementKind::Assign(local_and_rvalue) if &local_and_rvalue.0 == place => {
492492
match &local_and_rvalue.1 {
493-
Rvalue::Cast(CastKind::Misc, operand, ty) => {
493+
Rvalue::Cast(
494+
CastKind::IntToInt
495+
| CastKind::FloatToFloat
496+
| CastKind::FloatToInt
497+
| CastKind::IntToFloat
498+
| CastKind::FnPtrToPtr
499+
| CastKind::PtrToPtr,
500+
operand,
501+
ty,
502+
) => {
494503
if computed_const_val.is_some() {
495504
return None; // local assigned twice
496505
}

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
250250
OperandValue::Pair(lldata, llextra)
251251
}
252252
mir::CastKind::Pointer(PointerCast::MutToConstPointer)
253-
| mir::CastKind::Misc
253+
| mir::CastKind::PtrToPtr
254254
if bx.cx().is_backend_scalar_pair(operand.layout) =>
255255
{
256256
if let OperandValue::Pair(data_ptr, meta) = operand.val {
@@ -290,7 +290,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
290290
mir::CastKind::Pointer(
291291
PointerCast::MutToConstPointer | PointerCast::ArrayToPointer,
292292
)
293-
| mir::CastKind::Misc
293+
| mir::CastKind::IntToInt
294+
| mir::CastKind::FloatToInt
295+
| mir::CastKind::FloatToFloat
296+
| mir::CastKind::IntToFloat
297+
| mir::CastKind::PtrToPtr
298+
| mir::CastKind::FnPtrToPtr
299+
294300
// Since int2ptr can have arbitrary integer types as input (so we have to do
295301
// sign extension and all that), it is currently best handled in the same code
296302
// path as the other integer-to-X casts.

compiler/rustc_const_eval/src/interpret/cast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
4242
let res = self.pointer_from_exposed_address_cast(&src, cast_ty)?;
4343
self.write_immediate(res, dest)?;
4444
}
45-
46-
Misc => {
45+
// FIXME: We shouldn't use `misc_cast` for these but handle them separately.
46+
IntToInt | FloatToInt | FloatToFloat | IntToFloat | FnPtrToPtr | PtrToPtr => {
4747
let src = self.read_immediate(src)?;
4848
let res = self.misc_cast(&src, cast_ty)?;
4949
self.write_immediate(res, dest)?;

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
553553
unimplemented!()
554554
}
555555

556-
Rvalue::Cast(CastKind::Misc, _, _) => {}
556+
Rvalue::Cast(_, _, _) => {}
557557

558558
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
559559
Rvalue::ShallowInitBox(_, _) => {}

compiler/rustc_const_eval/src/transform/validate.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
557557
}
558558
Rvalue::Cast(kind, operand, target_type) => {
559559
match kind {
560-
CastKind::Misc => {
560+
CastKind::DynStar => {
561+
// FIXME(dyn-star): make sure nothing needs to be done here.
562+
}
563+
// Nothing to check here
564+
CastKind::PointerFromExposedAddress
565+
| CastKind::PointerExposeAddress
566+
| CastKind::Pointer(_) => {}
567+
_ => {
561568
let op_ty = operand.ty(self.body, self.tcx);
562569
if op_ty.is_enum() {
563570
self.fail(
@@ -568,13 +575,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
568575
);
569576
}
570577
}
571-
CastKind::DynStar => {
572-
// FIXME(dyn-star): make sure nothing needs to be done here.
573-
}
574-
// Nothing to check here
575-
CastKind::PointerFromExposedAddress
576-
| CastKind::PointerExposeAddress
577-
| CastKind::Pointer(_) => {}
578578
}
579579
}
580580
Rvalue::Repeat(_, _)

compiler/rustc_middle/src/mir/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1834,7 +1834,14 @@ impl<'tcx> Rvalue<'tcx> {
18341834
| Rvalue::AddressOf(_, _)
18351835
| Rvalue::Len(_)
18361836
| Rvalue::Cast(
1837-
CastKind::Misc | CastKind::Pointer(_) | CastKind::PointerFromExposedAddress,
1837+
CastKind::IntToInt
1838+
| CastKind::FloatToInt
1839+
| CastKind::FloatToFloat
1840+
| CastKind::IntToFloat
1841+
| CastKind::FnPtrToPtr
1842+
| CastKind::PtrToPtr
1843+
| CastKind::Pointer(_)
1844+
| CastKind::PointerFromExposedAddress,
18381845
_,
18391846
_,
18401847
)

compiler/rustc_middle/src/mir/syntax.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1149,8 +1149,12 @@ pub enum CastKind {
11491149
Pointer(PointerCast),
11501150
/// Cast into a dyn* object.
11511151
DynStar,
1152-
/// Remaining unclassified casts.
1153-
Misc,
1152+
IntToInt,
1153+
FloatToInt,
1154+
FloatToFloat,
1155+
IntToFloat,
1156+
PtrToPtr,
1157+
FnPtrToPtr,
11541158
}
11551159

11561160
#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]

compiler/rustc_middle/src/ty/cast.rs

+26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// typeck and codegen.
33

44
use crate::ty::{self, Ty};
5+
use rustc_middle::mir;
56

67
use rustc_macros::HashStable;
78

@@ -75,3 +76,28 @@ impl<'tcx> CastTy<'tcx> {
7576
}
7677
}
7778
}
79+
80+
/// Returns `mir::CastKind` from the given parameters.
81+
pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKind {
82+
let from = CastTy::from_ty(from_ty);
83+
let cast = CastTy::from_ty(cast_ty);
84+
let cast_kind = match (from, cast) {
85+
(Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
86+
mir::CastKind::PointerExposeAddress
87+
}
88+
(Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerFromExposedAddress,
89+
(_, Some(CastTy::DynStar)) => mir::CastKind::DynStar,
90+
(Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt,
91+
(Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr,
92+
93+
(Some(CastTy::Float), Some(CastTy::Int(_))) => mir::CastKind::FloatToInt,
94+
(Some(CastTy::Int(_)), Some(CastTy::Float)) => mir::CastKind::IntToFloat,
95+
(Some(CastTy::Float), Some(CastTy::Float)) => mir::CastKind::FloatToFloat,
96+
(Some(CastTy::Ptr(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PtrToPtr,
97+
98+
(_, _) => {
99+
bug!("Attempting to cast non-castable types {:?} and {:?}", from_ty, cast_ty)
100+
}
101+
};
102+
cast_kind
103+
}

compiler/rustc_mir_build/src/build/expr/as_rvalue.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_middle::mir::AssertKind;
1212
use rustc_middle::mir::Place;
1313
use rustc_middle::mir::*;
1414
use rustc_middle::thir::*;
15-
use rustc_middle::ty::cast::CastTy;
15+
use rustc_middle::ty::cast::{mir_cast_kind, CastTy};
1616
use rustc_middle::ty::{self, Ty, UpvarSubsts};
1717
use rustc_span::Span;
1818

@@ -217,16 +217,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
217217
let from_ty = CastTy::from_ty(ty);
218218
let cast_ty = CastTy::from_ty(expr.ty);
219219
debug!("ExprKind::Cast from_ty={from_ty:?}, cast_ty={:?}/{cast_ty:?}", expr.ty,);
220-
let cast_kind = match (from_ty, cast_ty) {
221-
(Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
222-
CastKind::PointerExposeAddress
223-
}
224-
(Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => {
225-
CastKind::PointerFromExposedAddress
226-
}
227-
(_, Some(CastTy::DynStar)) => CastKind::DynStar,
228-
(_, _) => CastKind::Misc,
229-
};
220+
let cast_kind = mir_cast_kind(ty, expr.ty);
230221
block.and(Rvalue::Cast(cast_kind, source, expr.ty))
231222
}
232223
ExprKind::Pointer { cast, source } => {

compiler/rustc_mir_dataflow/src/elaborate_drops.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -823,9 +823,10 @@ where
823823
// tmp = &raw mut P;
824824
// cur = tmp as *mut T;
825825
// end = Offset(cur, len);
826+
let mir_cast_kind = ty::cast::mir_cast_kind(iter_ty, tmp_ty);
826827
vec![
827828
self.assign(tmp, Rvalue::AddressOf(Mutability::Mut, self.place)),
828-
self.assign(cur, Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty)),
829+
self.assign(cur, Rvalue::Cast(mir_cast_kind, Operand::Move(tmp), iter_ty)),
829830
self.assign(
830831
length_or_end,
831832
Rvalue::BinaryOp(

src/test/mir-opt/const_prop/cast.main.ConstProp.diff

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414

1515
bb0: {
1616
StorageLive(_1); // scope 0 at $DIR/cast.rs:+1:9: +1:10
17-
- _1 = const 42_u8 as u32 (Misc); // scope 0 at $DIR/cast.rs:+1:13: +1:24
17+
- _1 = const 42_u8 as u32 (IntToInt); // scope 0 at $DIR/cast.rs:+1:13: +1:24
1818
+ _1 = const 42_u32; // scope 0 at $DIR/cast.rs:+1:13: +1:24
1919
StorageLive(_2); // scope 1 at $DIR/cast.rs:+3:9: +3:10
20-
- _2 = const 42_u32 as u8 (Misc); // scope 1 at $DIR/cast.rs:+3:13: +3:24
20+
- _2 = const 42_u32 as u8 (IntToInt); // scope 1 at $DIR/cast.rs:+3:13: +3:24
2121
+ _2 = const 42_u8; // scope 1 at $DIR/cast.rs:+3:13: +3:24
2222
_0 = const (); // scope 0 at $DIR/cast.rs:+0:11: +4:2
2323
StorageDead(_2); // scope 1 at $DIR/cast.rs:+4:1: +4:2

src/test/mir-opt/const_prop/indirect.main.ConstProp.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
bb0: {
1414
StorageLive(_1); // scope 0 at $DIR/indirect.rs:+1:9: +1:10
1515
StorageLive(_2); // scope 0 at $DIR/indirect.rs:+1:13: +1:25
16-
- _2 = const 2_u32 as u8 (Misc); // scope 0 at $DIR/indirect.rs:+1:13: +1:25
16+
- _2 = const 2_u32 as u8 (IntToInt); // scope 0 at $DIR/indirect.rs:+1:13: +1:25
1717
- _3 = CheckedAdd(_2, const 1_u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29
1818
- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
1919
+ _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:25

src/test/mir-opt/enum_cast.bar.mir_map.0.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fn bar(_1: Bar) -> usize {
77

88
bb0: {
99
_2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
10-
_0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
10+
_0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
1111
return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
1212
}
1313
}

src/test/mir-opt/enum_cast.boo.mir_map.0.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fn boo(_1: Boo) -> usize {
77

88
bb0: {
99
_2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
10-
_0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
10+
_0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
1111
return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
1212
}
1313
}

src/test/mir-opt/enum_cast.droppy.mir_map.0.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn droppy() -> () {
2626
FakeRead(ForLet(None), _2); // scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
2727
StorageLive(_3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
2828
_4 = discriminant(_2); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
29-
_3 = move _4 as usize (Misc); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
29+
_3 = move _4 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
3030
FakeRead(ForLet(None), _3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
3131
_1 = const (); // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
3232
StorageDead(_3); // scope 1 at $DIR/enum_cast.rs:+6:5: +6:6

src/test/mir-opt/enum_cast.foo.mir_map.0.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fn foo(_1: Foo) -> usize {
77

88
bb0: {
99
_2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
10-
_0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
10+
_0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
1111
return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
1212
}
1313
}

src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
StorageLive(_15); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75
9292
StorageLive(_16); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:68
9393
_16 = _10; // scope 3 at $DIR/funky_arms.rs:+15:59: +15:68
94-
_15 = move _16 as u32 (Misc); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75
94+
_15 = move _16 as u32 (IntToInt); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75
9595
StorageDead(_16); // scope 3 at $DIR/funky_arms.rs:+15:74: +15:75
9696
_14 = Add(move _15, const 1_u32); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79
9797
StorageDead(_15); // scope 3 at $DIR/funky_arms.rs:+15:78: +15:79

0 commit comments

Comments
 (0)