Problem
#[map(...)] attribute parsing in `crates/entity-derive-impl/src/entity/parse/field/map.rs` silently swallows errors, producing cryptic downstream failures instead of clear messages at the macro call site.
Two specific points
1. MapConfig::generate for Expr (lines 220–222):
```rust
Self::Expr(expr) => {
let expr_tokens: TokenStream = expr.parse().unwrap_or_default();
quote! { #expr_tokens }
}
```
If the user writes `#[map(expr = "invalid $$$ rust")]`, parse() fails, unwrap_or_default() returns an empty TokenStream, and the generated code references nothing. The compiler then complains about whatever surrounding expression was supposed to receive that value — far from the actual #[map(...)] site. The user has no clue the problem is in their attribute.
2. MapConfig::from_attr nested meta (lines 138–151):
```rust
let _ = meta_list.parse_nested_meta(|meta| {
if meta.path.is_ident("empty_to_none") { ... }
else if meta.path.is_ident("unwrap_default") { ... }
...
Ok(())
});
```
Errors from parse_nested_meta are bound to _ and dropped. If a nested item fails to parse (e.g. malformed expr =), the user sees MapConfig::None silently substituted.
Fix
- Replace
unwrap_or_default() in generate with explicit compile_error! token emission that includes the original parse error message and the user-supplied expr string.
- Propagate
parse_nested_meta errors instead of discarding them — surface them at the proc-macro level so they appear at the #[map(...)] span.
Tests
Add cases under crates/entity-derive/tests/cases/fail/:
map_expr_invalid.rs — #[map(expr = "garbage $$$")] must produce a clear compile error pointing at the attribute, mentioning expr.
map_nested_meta_invalid.rs — malformed nested item must produce a parse error at the attribute, not silently degrade to None.
Both verified via trybuild.
Problem
#[map(...)]attribute parsing in `crates/entity-derive-impl/src/entity/parse/field/map.rs` silently swallows errors, producing cryptic downstream failures instead of clear messages at the macro call site.Two specific points
1.
MapConfig::generateforExpr(lines 220–222):```rust
Self::Expr(expr) => {
let expr_tokens: TokenStream = expr.parse().unwrap_or_default();
quote! { #expr_tokens }
}
```
If the user writes `#[map(expr = "invalid $$$ rust")]`,
parse()fails,unwrap_or_default()returns an emptyTokenStream, and the generated code references nothing. The compiler then complains about whatever surrounding expression was supposed to receive that value — far from the actual#[map(...)]site. The user has no clue the problem is in their attribute.2.
MapConfig::from_attrnested meta (lines 138–151):```rust
let _ = meta_list.parse_nested_meta(|meta| {
if meta.path.is_ident("empty_to_none") { ... }
else if meta.path.is_ident("unwrap_default") { ... }
...
Ok(())
});
```
Errors from
parse_nested_metaare bound to_and dropped. If a nested item fails to parse (e.g. malformedexpr =), the user seesMapConfig::Nonesilently substituted.Fix
unwrap_or_default()ingeneratewith explicitcompile_error!token emission that includes the original parse error message and the user-suppliedexprstring.parse_nested_metaerrors instead of discarding them — surface them at the proc-macro level so they appear at the#[map(...)]span.Tests
Add cases under
crates/entity-derive/tests/cases/fail/:map_expr_invalid.rs—#[map(expr = "garbage $$$")]must produce a clear compile error pointing at the attribute, mentioningexpr.map_nested_meta_invalid.rs— malformed nested item must produce a parse error at the attribute, not silently degrade toNone.Both verified via trybuild.