Skip to content

Commit 1f4e210

Browse files
committed
Move the const casting code into its dedicated file
1 parent fb5b268 commit 1f4e210

File tree

2 files changed

+145
-131
lines changed

2 files changed

+145
-131
lines changed

src/librustc_mir/interpret/cast.rs

Lines changed: 143 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,153 @@
1-
use rustc::ty::Ty;
2-
use rustc::ty::layout::LayoutOf;
1+
use rustc::ty::{self, Ty};
2+
use rustc::ty::layout::{self, LayoutOf};
33
use syntax::ast::{FloatTy, IntTy, UintTy};
44

55
use rustc_apfloat::ieee::{Single, Double};
66
use super::{EvalContext, Machine};
7-
use rustc::mir::interpret::{Scalar, EvalResult, Pointer, PointerArithmetic};
7+
use rustc::mir::interpret::{Scalar, EvalResult, Pointer, PointerArithmetic, Value, EvalErrorKind};
8+
use rustc::mir::CastKind;
89
use rustc_apfloat::Float;
10+
use interpret::eval_context::ValTy;
11+
use interpret::Place;
912

1013
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
14+
crate fn cast(
15+
&mut self,
16+
src: ValTy<'tcx>,
17+
kind: CastKind,
18+
dest_ty: Ty<'tcx>,
19+
dest: Place,
20+
) -> EvalResult<'tcx> {
21+
use rustc::mir::CastKind::*;
22+
match kind {
23+
Unsize => {
24+
let src_layout = self.layout_of(src.ty)?;
25+
let dst_layout = self.layout_of(dest_ty)?;
26+
self.unsize_into(src.value, src_layout, dest, dst_layout)?;
27+
}
28+
29+
Misc => {
30+
if self.type_is_fat_ptr(src.ty) {
31+
match (src.value, self.type_is_fat_ptr(dest_ty)) {
32+
(Value::ByRef { .. }, _) |
33+
// pointers to extern types
34+
(Value::Scalar(_),_) |
35+
// slices and trait objects to other slices/trait objects
36+
(Value::ScalarPair(..), true) => {
37+
let valty = ValTy {
38+
value: src.value,
39+
ty: dest_ty,
40+
};
41+
self.write_value(valty, dest)?;
42+
}
43+
// slices and trait objects to thin pointers (dropping the metadata)
44+
(Value::ScalarPair(data, _), false) => {
45+
let valty = ValTy {
46+
value: Value::Scalar(data),
47+
ty: dest_ty,
48+
};
49+
self.write_value(valty, dest)?;
50+
}
51+
}
52+
} else {
53+
let src_layout = self.layout_of(src.ty)?;
54+
match src_layout.variants {
55+
layout::Variants::Single { index } => {
56+
if let Some(def) = src.ty.ty_adt_def() {
57+
let discr_val = def
58+
.discriminant_for_variant(*self.tcx, index)
59+
.val;
60+
let defined = self
61+
.layout_of(dest_ty)
62+
.unwrap()
63+
.size
64+
.bits() as u8;
65+
return self.write_scalar(
66+
dest,
67+
Scalar::Bits {
68+
bits: discr_val,
69+
defined,
70+
},
71+
dest_ty);
72+
}
73+
}
74+
layout::Variants::Tagged { .. } |
75+
layout::Variants::NicheFilling { .. } => {},
76+
}
77+
78+
let src_val = self.value_to_scalar(src)?;
79+
let dest_val = self.cast_scalar(src_val, src.ty, dest_ty)?;
80+
let valty = ValTy {
81+
value: Value::Scalar(dest_val),
82+
ty: dest_ty,
83+
};
84+
self.write_value(valty, dest)?;
85+
}
86+
}
87+
88+
ReifyFnPointer => {
89+
match src.ty.sty {
90+
ty::TyFnDef(def_id, substs) => {
91+
if self.tcx.has_attr(def_id, "rustc_args_required_const") {
92+
bug!("reifying a fn ptr that requires \
93+
const arguments");
94+
}
95+
let instance: EvalResult<'tcx, _> = ty::Instance::resolve(
96+
*self.tcx,
97+
self.param_env,
98+
def_id,
99+
substs,
100+
).ok_or_else(|| EvalErrorKind::TooGeneric.into());
101+
let fn_ptr = self.memory.create_fn_alloc(instance?);
102+
let valty = ValTy {
103+
value: Value::Scalar(fn_ptr.into()),
104+
ty: dest_ty,
105+
};
106+
self.write_value(valty, dest)?;
107+
}
108+
ref other => bug!("reify fn pointer on {:?}", other),
109+
}
110+
}
111+
112+
UnsafeFnPointer => {
113+
match dest_ty.sty {
114+
ty::TyFnPtr(_) => {
115+
let mut src = src;
116+
src.ty = dest_ty;
117+
self.write_value(src, dest)?;
118+
}
119+
ref other => bug!("fn to unsafe fn cast on {:?}", other),
120+
}
121+
}
122+
123+
ClosureFnPointer => {
124+
match src.ty.sty {
125+
ty::TyClosure(def_id, substs) => {
126+
let substs = self.tcx.subst_and_normalize_erasing_regions(
127+
self.substs(),
128+
ty::ParamEnv::reveal_all(),
129+
&substs,
130+
);
131+
let instance = ty::Instance::resolve_closure(
132+
*self.tcx,
133+
def_id,
134+
substs,
135+
ty::ClosureKind::FnOnce,
136+
);
137+
let fn_ptr = self.memory.create_fn_alloc(instance);
138+
let valty = ValTy {
139+
value: Value::Scalar(fn_ptr.into()),
140+
ty: dest_ty,
141+
};
142+
self.write_value(valty, dest)?;
143+
}
144+
ref other => bug!("closure fn pointer on {:?}", other),
145+
}
146+
}
147+
}
148+
Ok(())
149+
}
150+
11151
pub(super) fn cast_scalar(
12152
&self,
13153
val: Scalar,

src/librustc_mir/interpret/eval_context.rs

Lines changed: 2 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -770,134 +770,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
770770

771771
Cast(kind, ref operand, cast_ty) => {
772772
debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest_ty);
773-
use rustc::mir::CastKind::*;
774773
let src = self.eval_operand(operand)?;
775-
match kind {
776-
Unsize => {
777-
let src_layout = self.layout_of(src.ty)?;
778-
let dst_layout = self.layout_of(dest_ty)?;
779-
self.unsize_into(src.value, src_layout, dest, dst_layout)?;
780-
}
781-
782-
Misc => {
783-
if self.type_is_fat_ptr(src.ty) {
784-
match (src.value, self.type_is_fat_ptr(dest_ty)) {
785-
(Value::ByRef { .. }, _) |
786-
// pointers to extern types
787-
(Value::Scalar(_),_) |
788-
// slices and trait objects to other slices/trait objects
789-
(Value::ScalarPair(..), true) => {
790-
let valty = ValTy {
791-
value: src.value,
792-
ty: dest_ty,
793-
};
794-
self.write_value(valty, dest)?;
795-
}
796-
// slices and trait objects to thin pointers (dropping the metadata)
797-
(Value::ScalarPair(data, _), false) => {
798-
let valty = ValTy {
799-
value: Value::Scalar(data),
800-
ty: dest_ty,
801-
};
802-
self.write_value(valty, dest)?;
803-
}
804-
}
805-
} else {
806-
let src_layout = self.layout_of(src.ty)?;
807-
match src_layout.variants {
808-
layout::Variants::Single { index } => {
809-
if let Some(def) = src.ty.ty_adt_def() {
810-
let discr_val = def
811-
.discriminant_for_variant(*self.tcx, index)
812-
.val;
813-
let defined = self
814-
.layout_of(dest_ty)
815-
.unwrap()
816-
.size
817-
.bits() as u8;
818-
return self.write_scalar(
819-
dest,
820-
Scalar::Bits {
821-
bits: discr_val,
822-
defined,
823-
},
824-
dest_ty);
825-
}
826-
}
827-
layout::Variants::Tagged { .. } |
828-
layout::Variants::NicheFilling { .. } => {},
829-
}
830-
831-
let src_val = self.value_to_scalar(src)?;
832-
let dest_val = self.cast_scalar(src_val, src.ty, dest_ty)?;
833-
let valty = ValTy {
834-
value: Value::Scalar(dest_val),
835-
ty: dest_ty,
836-
};
837-
self.write_value(valty, dest)?;
838-
}
839-
}
840-
841-
ReifyFnPointer => {
842-
match src.ty.sty {
843-
ty::TyFnDef(def_id, substs) => {
844-
if self.tcx.has_attr(def_id, "rustc_args_required_const") {
845-
bug!("reifying a fn ptr that requires \
846-
const arguments");
847-
}
848-
let instance: EvalResult<'tcx, _> = ty::Instance::resolve(
849-
*self.tcx,
850-
self.param_env,
851-
def_id,
852-
substs,
853-
).ok_or_else(|| EvalErrorKind::TooGeneric.into());
854-
let fn_ptr = self.memory.create_fn_alloc(instance?);
855-
let valty = ValTy {
856-
value: Value::Scalar(fn_ptr.into()),
857-
ty: dest_ty,
858-
};
859-
self.write_value(valty, dest)?;
860-
}
861-
ref other => bug!("reify fn pointer on {:?}", other),
862-
}
863-
}
864-
865-
UnsafeFnPointer => {
866-
match dest_ty.sty {
867-
ty::TyFnPtr(_) => {
868-
let mut src = src;
869-
src.ty = dest_ty;
870-
self.write_value(src, dest)?;
871-
}
872-
ref other => bug!("fn to unsafe fn cast on {:?}", other),
873-
}
874-
}
875-
876-
ClosureFnPointer => {
877-
match src.ty.sty {
878-
ty::TyClosure(def_id, substs) => {
879-
let substs = self.tcx.subst_and_normalize_erasing_regions(
880-
self.substs(),
881-
ty::ParamEnv::reveal_all(),
882-
&substs,
883-
);
884-
let instance = ty::Instance::resolve_closure(
885-
*self.tcx,
886-
def_id,
887-
substs,
888-
ty::ClosureKind::FnOnce,
889-
);
890-
let fn_ptr = self.memory.create_fn_alloc(instance);
891-
let valty = ValTy {
892-
value: Value::Scalar(fn_ptr.into()),
893-
ty: dest_ty,
894-
};
895-
self.write_value(valty, dest)?;
896-
}
897-
ref other => bug!("closure fn pointer on {:?}", other),
898-
}
899-
}
900-
}
774+
self.cast(src, kind, dest_ty, dest)?;
901775
}
902776

903777
Discriminant(ref place) => {
@@ -1564,7 +1438,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
15641438
}
15651439
}
15661440

1567-
fn unsize_into(
1441+
crate fn unsize_into(
15681442
&mut self,
15691443
src: Value,
15701444
src_layout: TyLayout<'tcx>,

0 commit comments

Comments
 (0)