Skip to content

fix(map): emit clear compile_error for invalid expr and nested-meta parse failures #108

@RAprogramm

Description

@RAprogramm

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions