@@ -38,7 +38,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
3838 dest : PlaceTy < ' tcx , M :: PointerTag > ,
3939 ) -> EvalResult < ' tcx > {
4040 let src_layout = src. layout ;
41- let dst_layout = dest. layout ;
4241 use rustc:: mir:: CastKind :: * ;
4342 match kind {
4443 Unsize => {
@@ -47,7 +46,19 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
4746
4847 Misc => {
4948 let src = self . read_value ( src) ?;
50- if self . type_is_fat_ptr ( src_layout. ty ) {
49+
50+ if src. layout . ty . is_region_ptr ( ) && dest. layout . ty . is_unsafe_ptr ( ) {
51+ // For the purpose of the "ptr tag hooks", treat this as creating
52+ // a new, raw reference.
53+ let place = self . ref_to_mplace ( src) ?;
54+ let _val = self . create_ref ( place, None ) ?;
55+ // FIXME: The blog post said we should now also erase the tag.
56+ // That would amount to using `_val` instead of `src` from here on.
57+ // However, do we really want to do that? `transmute` doesn't
58+ // do it either and we have to support that, somehow.
59+ }
60+
61+ if self . type_is_fat_ptr ( src. layout . ty ) {
5162 match ( * src, self . type_is_fat_ptr ( dest. layout . ty ) ) {
5263 // pointers to extern types
5364 ( Value :: Scalar ( _) , _) |
@@ -65,11 +76,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
6576 match src_layout. variants {
6677 layout:: Variants :: Single { index } => {
6778 if let Some ( def) = src_layout. ty . ty_adt_def ( ) {
79+ // Cast from a univariant enum
80+ assert ! ( src. layout. is_zst( ) ) ;
6881 let discr_val = def
6982 . discriminant_for_variant ( * self . tcx , index)
7083 . val ;
7184 return self . write_scalar (
72- Scalar :: from_uint ( discr_val, dst_layout . size ) ,
85+ Scalar :: from_uint ( discr_val, dest . layout . size ) ,
7386 dest) ;
7487 }
7588 }
@@ -85,7 +98,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
8598
8699 ReifyFnPointer => {
87100 // The src operand does not matter, just its type
88- match src_layout . ty . sty {
101+ match src . layout . ty . sty {
89102 ty:: FnDef ( def_id, substs) => {
90103 if self . tcx . has_attr ( def_id, "rustc_args_required_const" ) {
91104 bug ! ( "reifying a fn ptr that requires \
@@ -117,7 +130,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
117130
118131 ClosureFnPointer => {
119132 // The src operand does not matter, just its type
120- match src_layout . ty . sty {
133+ match src . layout . ty . sty {
121134 ty:: Closure ( def_id, substs) => {
122135 let substs = self . tcx . subst_and_normalize_erasing_regions (
123136 self . substs ( ) ,
0 commit comments