about summary refs log tree commit diff
path: root/tvix/nix-compat-derive/src
diff options
context:
space:
mode:
authorBrian Olsen <brian@maven-group.org>2024-11-03T19·37+0100
committerclbot <clbot@tvl.fyi>2024-11-04T15·33+0000
commit6582fa69f15c8337cb3a16e74062037a7278020f (patch)
tree716173befab4f707a129d5d22a582c415af3471c /tvix/nix-compat-derive/src
parentcae3afc758eb7c4a24a77e03aae924c210ab7ffe (diff)
fix(tvix/nix-compat-derive): Better errors for default r/8892
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>
Diffstat (limited to 'tvix/nix-compat-derive/src')
-rw-r--r--tvix/nix-compat-derive/src/de.rs8
-rw-r--r--tvix/nix-compat-derive/src/internal/attrs.rs12
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<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,
             }
         );