about summary refs log tree commit diff
path: root/src/librustc_mir/interpret
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-11-04 11:23:34 +0100
committerRalf Jung <post@ralfj.de>2018-11-04 11:23:34 +0100
commite753d2105159397eff162aa3f1f7715f96b5772d (patch)
treeea9e25100dd93fc13f2065472731929298ffc038 /src/librustc_mir/interpret
parent6d69fe7a2fa31108ee7d23515cec7dd151d08331 (diff)
downloadrust-e753d2105159397eff162aa3f1f7715f96b5772d.tar.gz
rust-e753d2105159397eff162aa3f1f7715f96b5772d.zip
miri: accept extern types in structs if they are the only field
Diffstat (limited to 'src/librustc_mir/interpret')
-rw-r--r--src/librustc_mir/interpret/eval_context.rs15
-rw-r--r--src/librustc_mir/interpret/place.rs3
2 files changed, 15 insertions, 3 deletions
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index bc7ad16dc97..48a8d0bbe56 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -371,8 +371,19 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
                 // the last field).  Can't have foreign types here, how would we
                 // adjust alignment and size for them?
                 let field = layout.field(self, layout.fields.count() - 1)?;
-                let (unsized_size, unsized_align) = self.size_and_align_of(metadata, field)?
-                    .expect("Fields cannot be extern types");
+                let (unsized_size, unsized_align) = match self.size_and_align_of(metadata, field)? {
+                    Some(size_and_align) => size_and_align,
+                    None => {
+                        // A field with extern type.  If this is the only field,
+                        // we treat this struct just the same.  Else, this is an error
+                        // (for now).
+                        if layout.fields.count() == 1 {
+                            return Ok(None)
+                        } else {
+                            bug!("Fields cannot be extern types, unless they are the only field")
+                        }
+                    }
+                };
 
                 // FIXME (#26403, #27023): We should be adding padding
                 // to `sized_size` (to accommodate the `unsized_align`
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 3b104e2284f..8bd29aff841 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -354,7 +354,8 @@ where
         let (meta, offset) = if field_layout.is_unsized() {
             // re-use parent metadata to determine dynamic field layout
             let (_, align) = self.size_and_align_of(base.meta, field_layout)?
-                .expect("Fields cannot be extern types");
+                // If this is an extern type, we fall back to its static size and alignment.
+                .unwrap_or_else(|| base.layout.size_and_align());
             (base.meta, offset.abi_align(align))
         } else {
             // base.meta could be present; we might be accessing a sized field of an unsized