fix(tvix/nix-compat-derive): Better errors for default
This adds a span to default handling so that any error message gives a more precise location as a hint for why the error occurred instead of just pointing to the type. Change-Id: I7bf6cf38e0284f9726d670ea50a94a6b1edd8a94 Reviewed-on: https://cl.tvl.fyi/c/depot/+/12728 Reviewed-by: Vladimir Kryachko <v.kryachko@gmail.com> Reviewed-by: flokli <flokli@flokli.de> Tested-by: BuildkiteCI Autosubmit: Brian Olsen <me@griff.name>
This commit is contained in:
parent
cae3afc758
commit
6582fa69f1
2 changed files with 13 additions and 7 deletions
|
@ -111,7 +111,9 @@ fn nix_deserialize_struct(style: Style, fields: &[Field<'_>]) -> TokenStream {
|
|||
};
|
||||
if let Some(version) = f.attrs.version.as_ref() {
|
||||
let default = match &f.attrs.default {
|
||||
Default::Default => quote_spanned!(ty.span()=>::std::default::Default::default),
|
||||
Default::Default(span) => {
|
||||
quote_spanned!(span.span()=>::std::default::Default::default)
|
||||
}
|
||||
Default::Path(path) => path.to_token_stream(),
|
||||
_ => panic!("No default for versioned field"),
|
||||
};
|
||||
|
@ -172,7 +174,9 @@ fn nix_deserialize_variant(variant: &Variant<'_>) -> TokenStream {
|
|||
};
|
||||
if let Some(version) = f.attrs.version.as_ref() {
|
||||
let default = match &f.attrs.default {
|
||||
Default::Default => quote_spanned!(ty.span()=>::std::default::Default::default),
|
||||
Default::Default(span) => {
|
||||
quote_spanned!(span.span()=>::std::default::Default::default)
|
||||
}
|
||||
Default::Path(path) => path.to_token_stream(),
|
||||
_ => panic!("No default for versioned field"),
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ use super::Context;
|
|||
pub enum Default {
|
||||
None,
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
Default,
|
||||
Default(syn::Path),
|
||||
Path(ExprPath),
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ pub struct Field {
|
|||
impl Field {
|
||||
pub fn from_ast(ctx: &Context, attrs: &Vec<Attribute>) -> Field {
|
||||
let mut version = None;
|
||||
let mut version_path = None;
|
||||
let mut default = Default::None;
|
||||
for attr in attrs {
|
||||
if attr.path() != NIX {
|
||||
|
@ -37,13 +38,14 @@ impl Field {
|
|||
if let Err(err) = attr.parse_nested_meta(|meta| {
|
||||
if meta.path == VERSION {
|
||||
version = parse_lit(ctx, &meta, VERSION)?;
|
||||
version_path = Some(meta.path);
|
||||
} else if meta.path == DEFAULT {
|
||||
if meta.input.peek(Token![=]) {
|
||||
if let Some(path) = parse_lit(ctx, &meta, DEFAULT)? {
|
||||
default = Default::Path(path);
|
||||
}
|
||||
} else {
|
||||
default = Default::Default;
|
||||
default = Default::Default(meta.path);
|
||||
}
|
||||
} else {
|
||||
let path = meta.path.to_token_stream().to_string();
|
||||
|
@ -56,7 +58,7 @@ impl Field {
|
|||
}
|
||||
}
|
||||
if version.is_some() && default.is_none() {
|
||||
default = Default::Default;
|
||||
default = Default::Default(version_path.unwrap());
|
||||
}
|
||||
|
||||
Field { default, version }
|
||||
|
@ -199,7 +201,7 @@ mod test {
|
|||
assert_eq!(
|
||||
field,
|
||||
Field {
|
||||
default: Default::Default,
|
||||
default: Default::Default(parse_quote!(version)),
|
||||
version: Some(parse_quote!(..34)),
|
||||
}
|
||||
);
|
||||
|
@ -214,7 +216,7 @@ mod test {
|
|||
assert_eq!(
|
||||
field,
|
||||
Field {
|
||||
default: Default::Default,
|
||||
default: Default::Default(parse_quote!(default)),
|
||||
version: None,
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue