about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-11-17 09:08:30 +0100
committerRalf Jung <post@ralfj.de>2018-11-17 09:08:30 +0100
commita7b312f8255db978f0446cf62383402fee02bae3 (patch)
treea41d5ef0f21b10546aa795fb2f2bd21997b3256d /src
parente4d03f82b582824d2b6c3fb68420883d26598178 (diff)
downloadrust-a7b312f8255db978f0446cf62383402fee02bae3.tar.gz
rust-a7b312f8255db978f0446cf62383402fee02bae3.zip
erase the tag on casts involving (raw) pointers
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/interpret/cast.rs20
1 files changed, 13 insertions, 7 deletions
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index 118539fc58e..7d636b77ced 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -44,16 +44,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
             }
 
             Misc => {
+                let src_layout = src.layout;
                 let src = self.read_immediate(src)?;
 
-                if self.type_is_fat_ptr(src.layout.ty) {
-                    match (*src, self.type_is_fat_ptr(dest.layout.ty)) {
+                // There are no casts to references
+                assert!(!dest.layout.ty.is_region_ptr());
+                // Hence we make all casts erase the tag
+                let src = src.erase_tag().with_default_tag();
+
+                if self.type_is_fat_ptr(src_layout.ty) {
+                    match (src, self.type_is_fat_ptr(dest.layout.ty)) {
                         // pointers to extern types
                         (Immediate::Scalar(_),_) |
                         // slices and trait objects to other slices/trait objects
                         (Immediate::ScalarPair(..), true) => {
                             // No change to immediate
-                            self.write_immediate(*src, dest)?;
+                            self.write_immediate(src, dest)?;
                         }
                         // slices and trait objects to thin pointers (dropping the metadata)
                         (Immediate::ScalarPair(data, _), false) => {
@@ -61,11 +67,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                         }
                     }
                 } else {
-                    match src.layout.variants {
+                    match src_layout.variants {
                         layout::Variants::Single { index } => {
-                            if let Some(def) = src.layout.ty.ty_adt_def() {
+                            if let Some(def) = src_layout.ty.ty_adt_def() {
                                 // Cast from a univariant enum
-                                assert!(src.layout.is_zst());
+                                assert!(src_layout.is_zst());
                                 let discr_val = def
                                     .discriminant_for_variant(*self.tcx, index)
                                     .val;
@@ -78,7 +84,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                         layout::Variants::NicheFilling { .. } => {},
                     }
 
-                    let dest_val = self.cast_scalar(src.to_scalar()?, src.layout, dest.layout)?;
+                    let dest_val = self.cast_scalar(src.to_scalar()?, src_layout, dest.layout)?;
                     self.write_scalar(dest_val, dest)?;
                 }
             }