Skip to content

fix(errlanes-derive): with = .. structs bind fields and emit source() - #298

Merged
bodymindarts merged 2 commits into
mainfrom
task/errlanes-classify-with-fields-01a18d2e
Oct 30, 2026
Merged

bodymindarts merged 2 commits into
mainfrom
task/errlanes-classify-with-fields-01a18d2e

Conversation

@bodymindarts

@bodymindarts bodymindarts commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

#[classify(with = .., lanes(..))] structs now bind fields in #[error(..)] and emit source() from #[source] / a source field / from, matching laned structs. Non-breaking.

Implements handoff es-entity-dev/handoff-errlanes-classify-with-binds-fields-and-source. Downstream (lana) sweep is out of scope.

CHANGELOG (release-generated, so not hand-edited): #[classify(with = ..)] structs now bind fields in #[error(..)] and emit source() from #[source] / source / from, matching laned structs. Non-breaking.

  • struct_display is shared by derive_laned_struct and the struct with path.
  • with = .. on enums (the handoff said struct-only; it is not) keeps its output via unit_display: unit Display, no source(). Pinned by enum_with_keeps_unit_display_and_no_source.
  • #[from] on a with struct field now errors (new trybuild case).

🤖 Generated with Claude Code


Note

Medium Risk
Changes proc-macro codegen for all with-classified structs (messages and error chains), though behavior is intended to align with laned structs and enums are pinned to prior semantics.

Overview
#[classify(with = .., lanes(..))] on structs now generates the same Display / Error / source() behavior as ordinary laned structs: #[error(..)] can interpolate fields, and causes come from #[source], a field named source, or type-level from. Logic is centralized in struct_display, shared with the non-with struct path; with_impl takes a display callback and merges its where-clause bounds into the Classify impl.

Enums using with = .. are unchanged: unit_display still emits type-level unit-style messages with no per-variant source() (covered by new tests).

#[from] on a field of a with struct is now a compile error (use from in #[classify(..)] or error = manual instead). Integration and trybuild tests lock in struct field binding, generics, error = manual, and enum behavior.

Reviewed by Cursor Bugbot for commit 87950ca. Bugbot is set up for automated code reviews on this repo. Configure here.

The `with = ..` branch of the Classify derive built its Display/Error
from a hard-coded unit shape with no source. An #[error("..")] on such
a struct could not name a field, and #[source], a field named
`source`, or `from` never produced a source() chain. Every
response-specific classifier downstream had to opt out with
`error = manual` and hand-write both impls.

Extract the field-binding Display/Error emission of the laned-struct
branch into `struct_display` and call it from both struct paths, so
they cannot drift. Emission bounds from it now flow into the Classify
impl's where clause, and `#[from]` on a field is rejected with the
same targeted diagnostic as laned structs.

`with = ..` on an enum is unchanged: it keeps the unit Display and no
source() through `unit_display`, pinned by a regression test.

Non-breaking: a with struct without field references or source
markers emits the same impls as before.
@bodymindarts
bodymindarts marked this pull request as ready for review October 30, 2026 17:55
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@bodymindarts
bodymindarts merged commit 0ccebe2 into main Oct 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant