let def = tcx.adt_def(def_id);
def.destructor(tcx); // force the destructor to be evaluated
check_representable(tcx, span, def_id);
-
+ check_transparent(tcx, span, def_id);
check_packed(tcx, span, def_id);
}
return;
}
+ if adt.is_enum() {
+ if !tcx.features().transparent_enums {
+ emit_feature_err(&tcx.sess.parse_sess,
+ sym::transparent_enums,
+ sp,
+ GateIssue::Language,
+ "transparent enums are unstable");
+ }
+ if adt.variants.len() != 1 {
+ let variant_spans: Vec<_> = adt.variants.iter().map(|variant| {
+ tcx.hir().span_if_local(variant.def_id).unwrap()
+ }).collect();
+ let mut err = struct_span_err!(tcx.sess, sp, E0731,
+ "transparent enum needs exactly one variant, but has {}",
+ adt.variants.len());
+ if !variant_spans.is_empty() {
+ err.span_note(variant_spans, &format!("the following variants exist on `{}`",
+ tcx.def_path_str(def_id)));
+ }
+ err.emit();
+ if adt.variants.is_empty() {
+ // Don't bother checking the fields. No variants (and thus no fields) exist.
+ return;
+ }
+ }
+ }
+
+ if adt.is_union() && !tcx.features().transparent_unions {
+ emit_feature_err(&tcx.sess.parse_sess,
+ sym::transparent_unions,
+ sp,
+ GateIssue::Language,
+ "transparent unions are unstable");
+ }
+
// For each field, figure out if it's known to be a ZST and align(1)
- let field_infos = adt.non_enum_variant().fields.iter().map(|field| {
+ let field_infos = adt.all_fields().map(|field| {
let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
let param_env = tcx.param_env(field.did);
let layout = tcx.layout_of(param_env.and(ty));
let non_zst_count = non_zst_fields.clone().count();
if non_zst_count != 1 {
let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| span).collect();
- struct_span_err!(tcx.sess, sp, E0690,
- "transparent struct needs exactly one non-zero-sized field, but has {}",
- non_zst_count)
- .span_note(field_spans, "non-zero-sized field")
- .emit();
+
+ let mut err = struct_span_err!(tcx.sess, sp, E0690,
+ "{}transparent {} needs exactly one non-zero-sized field, but has {}",
+ if adt.is_enum() { "the variant of a " } else { "" },
+ adt.descr(),
+ non_zst_count);
+ if !field_spans.is_empty() {
+ err.span_note(field_spans,
+ &format!("the following non-zero-sized fields exist on `{}`:",
+ tcx.def_path_str(def_id)));
+ }
+ err.emit();
}
for (span, zst, align1) in field_infos {
if zst && !align1 {
span_err!(tcx.sess, span, E0691,
- "zero-sized field in transparent struct has alignment larger than 1");
+ "zero-sized field in transparent {} has alignment larger than 1",
+ adt.descr());
}
}
}
}
check_representable(tcx, sp, def_id);
+ check_transparent(tcx, sp, def_id);
}
fn report_unexpected_variant_res<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,