]> git.lizzy.rs Git - rust.git/commitdiff
fix accessing unsized fields
authorRalf Jung <post@ralfj.de>
Wed, 15 Aug 2018 22:41:26 +0000 (00:41 +0200)
committerRalf Jung <post@ralfj.de>
Wed, 22 Aug 2018 07:06:28 +0000 (09:06 +0200)
src/librustc_mir/interpret/place.rs

index b53aa4e2e65b8269bfbedec7ee5bfeae11d8879d..e8321adb4faf73531bb62bcbb7557b771d37def3 100644 (file)
@@ -283,31 +283,32 @@ pub fn mplace_field(
         };
         // the only way conversion can fail if is this is an array (otherwise we already panicked
         // above). In that case, all fields are equal.
-        let field = base.layout.field(self, usize::try_from(field).unwrap_or(0))?;
+        let field_layout = base.layout.field(self, usize::try_from(field).unwrap_or(0))?;
 
         // Adjust offset
-        let offset = if field.is_unsized() {
-            let vtable = match base.extra {
-                PlaceExtra::Vtable(tab) => tab,
-                _ => bug!("Unsized place with unsized field must come with vtable"),
-            };
-            let (_, align) = self.read_size_and_align_from_vtable(vtable)?;
-            offset.abi_align(align)
-        } else {
-            // No adjustment needed
-            offset
+        let offset = match base.extra {
+            PlaceExtra::Vtable(vtable) => {
+                let (_, align) = self.read_size_and_align_from_vtable(vtable)?;
+                // FIXME: Is this right? Should we always do this, or only when actually
+                // accessing the field to which the vtable applies?
+                offset.abi_align(align)
+            }
+            _ => {
+                // No adjustment needed
+                offset
+            }
         };
 
         let ptr = base.ptr.ptr_offset(offset, self)?;
-        let align = base.align.min(field.align);
-        let extra = if !field.is_unsized() {
+        let align = base.align.min(field_layout.align);
+        let extra = if !field_layout.is_unsized() {
             PlaceExtra::None
         } else {
             assert!(base.extra != PlaceExtra::None, "Expected fat ptr");
             base.extra
         };
 
-        Ok(MPlaceTy { mplace: MemPlace { ptr, align, extra }, layout: field })
+        Ok(MPlaceTy { mplace: MemPlace { ptr, align, extra }, layout: field_layout })
     }
 
     pub fn mplace_subslice(