Better error when deriving Deserialize for struct containing &str

This commit is contained in:
David Tolnay 2016-06-11 21:27:49 -07:00
parent 8a09f05644
commit c21bea8b30
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82

View File

@ -379,6 +379,7 @@ fn deserialize_tuple(
let nfields = fields.len();
let fields_with_attrs = try!(attr::fields_with_attrs(cx, fields));
try!(check_no_str(cx, &fields_with_attrs));
let visit_newtype_struct = if !is_enum && nfields == 1 {
Some(try!(deserialize_newtype_struct(
@ -576,6 +577,7 @@ fn deserialize_struct(
};
let fields_with_attrs = try!(attr::fields_with_attrs(cx, fields));
try!(check_no_str(cx, &fields_with_attrs));
let visit_seq_expr = try!(deserialize_seq(
cx,
@ -1242,3 +1244,32 @@ fn expr_is_missing(
}
}
}
fn check_no_str(
cx: &ExtCtxt,
fields: &[(ast::StructField, attr::FieldAttrs)],
) -> Result<(), Error> {
let fail = |field: &ast::StructField| {
cx.span_err(
field.span,
"Serde does not support deserializing fields of type &str; \
consider using String instead");
Err(Error)
};
for &(ref field, ref attrs) in fields {
if attrs.skip_deserializing_field()
|| attrs.deserialize_with().is_some() { continue }
if let ast::TyKind::Rptr(_, ref inner) = field.ty.node {
if let ast::TyKind::Path(_, ref path) = inner.ty.node {
if path.segments.len() == 1
&& path.segments[0].identifier.name.as_str() == "str"
{
return fail(field);
}
}
}
}
Ok(())
}