fix error for unsized packed struct field
This commit is contained in:
parent
afd0a2f249
commit
2fd2f9cfaf
5 changed files with 32 additions and 17 deletions
|
@ -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");
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue