diff options
| author | Ralf Jung <post@ralfj.de> | 2018-08-16 00:41:26 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2018-08-22 09:06:28 +0200 |
| commit | e314a4e75f18a77392ae3d316b777c1523908acf (patch) | |
| tree | e43803e55ee6dd1066e2acfe7cdc8b67daf96085 | |
| parent | 1e137a796685c149903fcaa52444ab0d6a949b00 (diff) | |
| download | rust-e314a4e75f18a77392ae3d316b777c1523908acf.tar.gz rust-e314a4e75f18a77392ae3d316b777c1523908acf.zip | |
fix accessing unsized fields
| -rw-r--r-- | src/librustc_mir/interpret/place.rs | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index b53aa4e2e65..e8321adb4fa 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -283,31 +283,32 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { }; // 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( |
