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 field is at offset 0 and the sized
- // part makes no alignment constraints, we behave like the underlying
- // extern type.
+ // A field with extern type. If this field is at offset 0, we behave
+ // like the underlying extern type.
// FIXME: Once we have made decisions for how to handle size and alignment
// of `extern type`, this should be adapted. It is just a temporary hack
// to get some code to work that probably ought to work.
- if sized_size == Size::ZERO && sized_align.abi() == 1 {
+ if sized_size == Size::ZERO {
return Ok(None)
} else {
bug!("Fields cannot be extern types, unless they are at offset 0")
// Offset may need adjustment for unsized fields
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)?
- .map(|(_, align)| align)
- // If this is an extern type, we fall back to its static alignment.
- // FIXME: Once we have made decisions for how to handle size and alignment
- // of `extern type`, this should be adapted. It is just a temporary hack
- // to get some code to work that probably ought to work.
- .unwrap_or_else(|| base.layout.align);
+ let align = match self.size_and_align_of(base.meta, field_layout)? {
+ Some((_, align)) => align,
+ None if offset == Size::ZERO =>
+ // An extern type at offset 0, we fall back to its static alignment.
+ // FIXME: Once we have made decisions for how to handle size and alignment
+ // of `extern type`, this should be adapted. It is just a temporary hack
+ // to get some code to work that probably ought to work.
+ field_layout.align,
+ None =>
+ bug!("Cannot compute offset for extern type field at non-0 offset"),
+ };
(base.meta, offset.abi_align(align))
} else {
// base.meta could be present; we might be accessing a sized field of an unsized