1
Fork 0

fix error for unsized packed struct field

This commit is contained in:
Ralf Jung 2018-08-14 12:50:01 +02:00
parent afd0a2f249
commit 2fd2f9cfaf
5 changed files with 32 additions and 17 deletions

View file

@ -1472,11 +1472,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
ObligationCauseCode::StructInitializerSized => { ObligationCauseCode::StructInitializerSized => {
err.note("structs must have a statically known size to be initialized"); err.note("structs must have a statically known size to be initialized");
} }
ObligationCauseCode::FieldSized(ref item) => { ObligationCauseCode::FieldSized { adt_kind: ref item, last } => {
match *item { match *item {
AdtKind::Struct => { AdtKind::Struct => {
err.note("only the last field of a struct may have a dynamically \ if last {
sized type"); err.note("the last field of a packed struct may only have a \
dynamically sized type if it does not need drop to be run");
} else {
err.note("only the last field of a struct may have a dynamically \
sized type");
}
} }
AdtKind::Union => { AdtKind::Union => {
err.note("no field of a union may have a dynamically sized type"); err.note("no field of a union may have a dynamically sized type");

View file

@ -192,8 +192,8 @@ pub enum ObligationCauseCode<'tcx> {
/// [T,..n] --> T must be Copy /// [T,..n] --> T must be Copy
RepeatVec, RepeatVec,
/// Types of fields (other than the last) in a struct must be sized. /// Types of fields (other than the last, except for packed structs) in a struct must be sized.
FieldSized(AdtKind), FieldSized { adt_kind: AdtKind, last: bool },
/// Constant expressions must be sized. /// Constant expressions must be sized.
ConstSized, ConstSized,

View file

@ -206,7 +206,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
super::SizedReturnType => Some(super::SizedReturnType), super::SizedReturnType => Some(super::SizedReturnType),
super::SizedYieldType => Some(super::SizedYieldType), super::SizedYieldType => Some(super::SizedYieldType),
super::RepeatVec => Some(super::RepeatVec), super::RepeatVec => Some(super::RepeatVec),
super::FieldSized(item) => Some(super::FieldSized(item)), super::FieldSized { adt_kind, last } => Some(super::FieldSized { adt_kind, last }),
super::ConstSized => Some(super::ConstSized), super::ConstSized => Some(super::ConstSized),
super::SharedStatic => Some(super::SharedStatic), super::SharedStatic => Some(super::SharedStatic),
super::BuiltinDerivedObligation(ref cause) => { super::BuiltinDerivedObligation(ref cause) => {

View file

@ -258,25 +258,35 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id)) ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id))
} }
}; };
let unsized_len = if let all_sized =
all_sized || all_sized ||
variant.fields.is_empty() || variant.fields.is_empty() ||
needs_drop_copy() needs_drop_copy();
{ let unsized_len = if all_sized {
0 0
} else { } else {
1 1
}; };
for field in &variant.fields[..variant.fields.len() - unsized_len] { for (idx, field) in variant.fields[..variant.fields.len() - unsized_len]
.iter()
.enumerate()
{
let last = idx == variant.fields.len() - 1;
fcx.register_bound( fcx.register_bound(
field.ty, field.ty,
fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem), fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
traits::ObligationCause::new(field.span, traits::ObligationCause::new(
fcx.body_id, field.span,
traits::FieldSized(match item.node.adt_kind() { fcx.body_id,
Some(i) => i, traits::FieldSized {
None => bug!(), adt_kind: match item.node.adt_kind() {
}))); Some(i) => i,
None => bug!(),
},
last
}
)
);
} }
// All field types must be well-formed. // All field types must be well-formed.

View file

@ -7,7 +7,7 @@ LL | data: T, //~ ERROR the size for values of type
= help: the trait `std::marker::Sized` is not implemented for `T` = help: the trait `std::marker::Sized` is not implemented for `T`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait> = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where T: std::marker::Sized` bound = help: consider adding a `where T: std::marker::Sized` bound
= note: only the last field of a struct may have a dynamically sized type = note: the last field of a packed struct may only have a dynamically sized type if it does not need drop to be run
error: aborting due to previous error error: aborting due to previous error