Expand description
ShiftSpans impls for every type reachable from a Directive.
The discipline introduced in round 18 lifted span shifting out of
the parser (monolithic shift_directive_inner_spans with per-
variant named-field destructure) and into the type system. Round
19 closes the residual hole: enum-variant payloads are now bound
BY NAME and dispatched via value.shift_spans(shift) rather than
via a wildcard Self::Variant(_) arm. A future payload type
change (e.g., wrapping a leaf String payload in Spanned<String>)
routes through the wrapper’s ShiftSpans impl automatically —
no edit to this file required, no silent discipline gap.
Each type that appears anywhere inside a Directive payload
either:
-
Carries no spans — implements
ShiftSpansas a no-op via theimpl_shift_spans_noop!macro (for foreign leaf types likeDecimal,NaiveDate) or via an explicit empty body with exhaustive structural destructure (for variant enums whose payloads currently have no spans, likePriceKind). -
Has structural payloads — implements
ShiftSpansby destructuring every field/variant BY NAME and dispatching into the binding’s own impl. Compound shapes (Vec,Option,Box,Spanned,HashMap) are handled by blanket impls incrate::spanand below.
All impls live here (not next to each type) so the discipline is reviewable in one place; a contributor adding a new directive- payload type can use the existing impls as a template.