From 6582fa69f15c8337cb3a16e74062037a7278020f Mon Sep 17 00:00:00 2001 From: Brian Olsen Date: Sun, 3 Nov 2024 20:37:08 +0100 Subject: 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 Reviewed-by: flokli Tested-by: BuildkiteCI Autosubmit: Brian Olsen --- tvix/nix-compat-derive/src/de.rs | 8 ++++++-- tvix/nix-compat-derive/src/internal/attrs.rs | 12 +++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/tvix/nix-compat-derive/src/de.rs b/tvix/nix-compat-derive/src/de.rs index 8dac6964f612..2214254e2b32 100644 --- a/tvix/nix-compat-derive/src/de.rs +++ b/tvix/nix-compat-derive/src/de.rs @@ -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"), }; diff --git a/tvix/nix-compat-derive/src/internal/attrs.rs b/tvix/nix-compat-derive/src/internal/attrs.rs index dbc959d1e917..9ed84aaf8745 100644 --- a/tvix/nix-compat-derive/src/internal/attrs.rs +++ b/tvix/nix-compat-derive/src/internal/attrs.rs @@ -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) -> 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, } ); -- cgit 1.4.1