Skip to content

Commit

Permalink
Error if attrs field is declared and forward_attrs is missing.
Browse files Browse the repository at this point in the history
Previously, this would result in a cryptic error due to an expect(...) failure if neither `attributes` nor `forward_attrs` were declared.

This change is technically breaking, as it was previously possible to declare this field without using `forward_attrs`; if `attributes` was used the `attrs` field would be initialized to an empty array.
That behavior was more likely to mask issues than be useful, but it's possible someone declared the field in order to manually populate it later.

Fixes #317
  • Loading branch information
TedDriggs committed Jan 17, 2025
1 parent b7a248f commit 6540a8b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
15 changes: 14 additions & 1 deletion core/src/options/outer_from.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use syn::spanned::Spanned;
use syn::{Field, Ident, Meta};

use crate::ast::Data;
use crate::codegen::ForwardAttrs;
use crate::options::{
Core, DefaultExpression, ForwardAttrsFilter, ForwardedField, ParseAttribute, ParseData,
};
use crate::util::PathList;
use crate::{FromField, FromMeta, Result};
use crate::{Error, FromField, FromMeta, Result};

/// Reusable base for `FromDeriveInput`, `FromVariant`, `FromField`, and other top-level
/// `From*` traits.
Expand Down Expand Up @@ -91,5 +92,17 @@ impl ParseData for OuterFrom {

fn validate_body(&self, errors: &mut crate::error::Accumulator) {
self.container.validate_body(errors);
if let Some(attrs) = &self.attrs {
if self.forward_attrs.is_none() {
let container_name = match &self.container.data {
Data::Enum(_) => "enum",
Data::Struct(_) => "struct",
};
errors.push(
Error::custom(format!("field will not be populated because `forward_attrs` is not set on the {container_name}"))
.with_span(&attrs.ident),
);
}
}
}
}
10 changes: 10 additions & 0 deletions tests/compile-fail/attrs_without_forward_attrs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use darling::FromDeriveInput;
use syn::{Attribute, Ident};

#[derive(FromDeriveInput)]
struct HelloArgs {
ident: Ident,
attrs: Vec<Attribute>,
}

fn main() {}
5 changes: 5 additions & 0 deletions tests/compile-fail/attrs_without_forward_attrs.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
error: field will not be populated because `forward_attrs` is not set on the struct
--> tests/compile-fail/attrs_without_forward_attrs.rs:7:5
|
7 | attrs: Vec<Attribute>,
| ^^^^^

0 comments on commit 6540a8b

Please sign in to comment.