@@ -4614,7 +4614,10 @@
46144614:: Restricted-number promotion considers written capitals only; if there
46154615:: are none, it skips the otherwise unnecessary environment traversal.
46164616:: Bare @ is a separate unrestricted atom type. A directional fit check
4617−:: permits concrete atoms to widen to it, never the reverse. A fit that
4617+:: permits concrete atoms to widen to it, never the reverse. A bare
4618+:: decimal is a @ud: its variable binds only @ud or @u, it fits @ and *,
4619+:: and +decimal-misfit names it where it meets another aura (S4); a
4620+:: ++ generic over its aura generalizes it to any aura. A fit that
46184621:: needs a not-yet-implemented constraint remains unsupported. Named unions
46194622:: retain origin and ordered arguments, including phantom arguments, apart
46204623:: from their display name. Generic cases must be disjoint for all arguments.
@@ -4845,7 +4848,8 @@
48454848:: +itype-unify: consistent substitutions, or ~ for a mismatch
48464849::
48474850:: Different concrete auras conflict. A variable may become an atom or
4848−:: a function, but cannot contain itself. Aura-only variables and faces
4851+:: a function, but cannot contain itself. A decimal's variable binds
4852+:: only @ud or @u (+decimal-aura). Aura-only variables and faces
48494853:: require further distinctions before this supports general Jibb.
48504854::
48514855++ itype-unify
@@ -4894,10 +4898,10 @@
48944898 ?: &(?=(%rnvar -.a) ?=(%avar -.b)) `[[id.b a] sub]
48954899 ?: &(?=(%avar -.a) ?=(%rnvar -.b)) `[[id.a b] sub]
48964900 ?: ?=(%rnvar -.a)
4897− ?. |(?=(%rnvar -.b) ?=(%atom -.b)) ~
4901+ ?. |(?=(%rnvar -.b) &(?=(%atom -.b) (decimal-aura aura.b))) ~
48984902 `[[id.a b] sub]
48994903 ?: ?=(%rnvar -.b)
4900− ?. ?=(%atom -.a) ~
4904+ ?. &(?=(%atom -.a) (decimal-aura aura.a)) ~
49014905 `[[id.b a] sub]
49024906 ?: &(?=(%avar -.a) ?=(%rvar -.b)) `[[id.a b] sub]
49034907 ?: &(?=(%rvar -.a) ?=(%avar -.b)) `[[id.b a] sub]
@@ -4908,14 +4912,15 @@
49084912 ?. ?=(%atom -.a) ~
49094913 `[[id.b a] sub]
49104914 :: The narrower decimal constraint survives a match with an atom
4911− :: variable; decimal syntax alone does not make it a loobean.
4915+ :: variable; decimal syntax alone does not make it a loobean. A
4916+ :: concrete aura takes a decimal only if it is @ud or @u.
49124917 ?: &(?=(%nvar -.a) ?=(%avar -.b)) `[[id.b a] sub]
49134918 ?: &(?=(%avar -.a) ?=(%nvar -.b)) `[[id.a b] sub]
49144919 ?: ?=(%nvar -.a)
4915− ?. |(?=(%nvar -.b) ?=(%atom -.b)) ~
4920+ ?. |(?=(%nvar -.b) &(?=(%atom -.b) (decimal-aura aura.b))) ~
49164921 `[[id.a b] sub]
49174922 ?: ?=(%nvar -.b)
4918− ?. ?=(%atom -.a) ~
4923+ ?. &(?=(%atom -.a) (decimal-aura aura.a)) ~
49194924 `[[id.b a] sub]
49204925 ?: ?=(%avar -.a)
49214926 ?. |(?=(%avar -.b) ?=(%atom -.b) ?=(%any-atom -.b) ?=(%flag -.b)) ~
@@ -5060,6 +5065,16 @@
50605065 ?. =(i.a i.b) |
50615066 $(a t.a, b t.b)
50625067::
5068+:: +decimal-aura: whether a bare decimal fits an atom of this aura
5069+::
5070+:: A decimal is a @ud, so as in Hoon it fits @ud and its ancestors
5071+:: @u and @; every other aura takes its own literal (S4).
5072+::
5073+++ decimal-aura
5074+ |= aura=@ta
5075+ ^- ?
5076+ (aura-prefix aura %ud)
5077+::
50635078:: Related auras in a structural unification need a common-type rule;
50645079:: until that rule is implemented, report an unknown rather than error.
50655080::
@@ -5795,6 +5810,24 @@
57955810 ["canonicalization should retain gate-free variables" problems]
57965811 =? problems !=((show-atom-constraint canonical-free) " where A contains no gates")
57975812 ["the printer should show gate-free constraints" problems]
5813+ =/ decimal=itype [%nvar 50]
5814+ =? problems ?=(~ (itype-unify decimal num ~))
5815+ ["a decimal should unify with @ud" problems]
5816+ =? problems ?=(~ (itype-unify [%atom %u] decimal ~))
5817+ ["a decimal should unify with @u" problems]
5818+ =? problems ?=(^ (itype-unify decimal [%atom %dr] ~))
5819+ ["a decimal should not unify with @dr" problems]
5820+ =? problems ?=(^ (itype-unify [%atom %ux] decimal ~))
5821+ ["a decimal should not unify with @ux" problems]
5822+ =/ restricted=(unit isub) (itype-unify decimal [%rvar 51] ~)
5823+ =? problems |(?=(~ restricted) ?=(^ (itype-unify [%rvar 51] [%atom %p] u.restricted)))
5824+ ["arithmetic should keep a decimal's aura rule" problems]
5825+ =/ decimal-any=ifit (itype-fit decimal [%any-atom ~] ~ 52)
5826+ =? problems !?=(%ok -.decimal-any)
5827+ ["a decimal should fit @" problems]
5828+ =/ decimal-noun=ifit (itype-fit decimal [%noun ~] ~ 52)
5829+ =? problems !?=(%ok -.decimal-noun)
5830+ ["a decimal should fit a noun" problems]
57985831 problems
57995832::
58005833:: The expression inference below is deliberately a fragment: bindings,
@@ -7810,6 +7843,8 @@
78107843 ?^ missing [%| u.missing]
78117844 =/ nested=(unit idiag) (nested-missing-tag e typ.p.value expected sub.state.p.value next.state.p.value context)
78127845 ?^ nested [%| u.nested]
7846+ =/ decimal=(unit idiag) (decimal-misfit e typ.p.value expected sub.state.p.value next.state.p.value)
7847+ ?^ decimal [%| u.decimal]
78137848 ?: &(?=(%collection -.expected) =(%list name.expected))
78147849 [%| ["branch arm does not fit its expected list" ~[[context "expected list"] [(span-of e) "branch arm"]]]]
78157850 ?: ?=(%flag -.expected)
@@ -7875,11 +7910,15 @@
78757910 =/ fit=ifit (itype-fit typ.p.tail target sub.state.p.tail next.state.p.tail)
78767911 ?: ?=(%unknown -.fit) [%| ["list tail constraint is not supported by partial inference" ~]]
78777912 ?: ?=(%bad -.fit)
7913+ =/ decimal=(unit idiag) (decimal-misfit val.i.t.items.e typ.p.tail target sub.state.p.tail next.state.p.tail)
7914+ ?^ decimal [%| u.decimal]
78787915 [%| ["list tail does not fit its expected type" ~[[context (site-type-note "expected list" target sub.state.p.tail)] [(span-of val.i.t.items.e) (site-type-note "list tail" typ.p.tail sub.state.p.tail)]]]]
78797916 [%& target state.p.tail(sub sub.fit, next next.fit)]
78807917::
7918+:: done holds the items already checked, the last first, so that a
7919+:: decimal among them can be blamed when a later item fixes its aura.
78817920++ infer-open-list-items
7882− |= [items=(list expr) expected=itype env=ienv state=istate context=span]
7921+ |= [items=(list expr) expected=itype env=ienv state=istate context=span done=(list expr)]
78837922 ^- iresult
78847923 ?~ items [%& expected state]
78857924 =/ target=itype (itype-walk expected sub.state)
@@ -7895,10 +7934,18 @@
78957934 ?: ?=(%bad -.fit)
78967935 ?: |((itype-family-related typ.p.value target sub.state.p.value) (itype-has-any-atom typ.p.value sub.state.p.value) (itype-has-any-atom target sub.state.p.value))
78977936 [%| ["list item widening is not supported by partial inference" ~]]
7937+ =/ decimal=(unit idiag) (decimal-misfit i.items typ.p.value target sub.state.p.value next.state.p.value)
7938+ ?^ decimal [%| u.decimal]
7939+ =/ earlier=(list expr) (flop done)
7940+ |- ^- iresult
7941+ ?^ earlier
7942+ =/ found=(unit idiag) (decimal-misfit-at i.earlier typ.p.value sub.state.p.value)
7943+ ?^ found [%| u.found]
7944+ $(earlier t.earlier)
78987945 [%| ["list items do not have compatible types" ~[[context (site-type-note "expected item" target sub.state.p.value)] [(span-of i.items) (site-type-note "list item" typ.p.value sub.state.p.value)]]]]
78997946 ?: (itype-has-tag (itype-normalize expected sub.fit))
79007947 [%| ["list item needs context in partial inference" ~]]
7901− $(items t.items, state state.p.value(sub sub.fit, next next.fit))
7948+ $(items t.items, state state.p.value(sub sub.fit, next next.fit), done [i.items done])
79027949::
79037950++ infer-list-items
79047951 |= [items=(list expr) expected=itype env=ienv state=istate context=span]
@@ -7919,6 +7966,8 @@
79197966 ?^ missing [%| u.missing]
79207967 =/ nested=(unit idiag) (nested-missing-tag i.items typ.p.value target sub.state.p.value next.state.p.value context)
79217968 ?^ nested [%| u.nested]
7969+ =/ decimal=(unit idiag) (decimal-misfit i.items typ.p.value target sub.state.p.value next.state.p.value)
7970+ ?^ decimal [%| u.decimal]
79227971 [%| ["list item does not fit its expected type" ~[[context (site-type-note "expected item" target sub.state.p.value)] [(span-of i.items) (site-type-note "list item" typ.p.value sub.state.p.value)]]]]
79237972 $(items t.items, state state.p.value(sub sub.fit, next next.fit))
79247973::
@@ -8284,6 +8333,8 @@
82848333 ^- (unit iresult)
82858334 ?> ?=(%branch -.e)
82868335 ?: ?=(%| -.subject) `subject
8336+ =/ decimal=(unit idiag) (decimal-arms-misfit arms.e typ.p.subject sub.state.p.subject)
8337+ ?^ decimal `[%| u.decimal]
82878338 =/ typ=itype (itype-normalize typ.p.subject sub.state.p.subject)
82888339 ?. ?=(%union -.typ) `[%| ["branch is not supported by partial inference" ~]]
82898340 =/ live=(unit (list itype)) (itype-live-cases cases.typ sub.state.p.subject caps.state.p.subject 4.096)
@@ -8322,6 +8373,8 @@
83228373 ^- (unit iresult)
83238374 ?> ?=(%branch -.e)
83248375 ?: ?=(%| -.subject) `subject
8376+ =/ decimal=(unit idiag) (decimal-arms-misfit arms.e typ.p.subject sub.state.p.subject)
8377+ ?^ decimal `[%| u.decimal]
83258378 =/ typ=itype (itype-normalize typ.p.subject sub.state.p.subject)
83268379 ?. ?=(%union -.typ) `[%| ["branch is not supported by partial inference" ~]]
83278380 =/ live=(unit (list itype)) (itype-live-cases cases.typ sub.state.p.subject caps.state.p.subject 4.096)
@@ -8712,6 +8765,8 @@
87128765 =/ fit=ifit (itype-fit typ.p.value expected sub.state.p.value next.state.p.value)
87138766 ?: ?=(%unknown -.fit) [%| ["change field constraint is not supported by partial inference" ~]]
87148767 ?: ?=(%bad -.fit)
8768+ =/ decimal=(unit idiag) (decimal-misfit val.entry typ.p.value expected sub.state.p.value next.state.p.value)
8769+ ?^ decimal [%| u.decimal]
87158770 [%| ["change field and replacement do not unify" ~[[at.entry (site-type-note "expected replacement" expected sub.state.p.value)] [(span-of val.entry) (site-type-note "replacement" typ.p.value sub.state.p.value)]]]]
87168771 $(edits t.edits, state state.p.value(sub sub.fit, next next.fit), seen [name.entry seen])
87178772::
@@ -8817,6 +8872,183 @@
88178872 ?. ?=(%ok -.first) ~
88188873 $(items t.items, actual tal.actual, expected tal.expected, sub sub.first, next next.first)
88198874::
8875+:: +decimal-misfit: a decimal's error where another aura is expected
8876+::
8877+:: A bare decimal is a @ud and fits only @ud, @u, @ and * (S4). After
8878+:: a value fails to fit, refit it with each decimal's variable widened
8879+:: to any aura (+decimal-relax), so that a gate's shared capital learns
8880+:: its aura from the other arguments, then walk the value's syntax
8881+:: beside the type it should fit. The first decimal whose place is an
8882+:: atom of another aura gets the error; otherwise ~, and the caller's
8883+:: own error stands.
8884+::
8885+++ decimal-misfit
8886+ |= [e=expr actual=itype expected=itype sub=isub next=@ud]
8887+ ^- (unit idiag)
8888+ =/ loose=isub (turn sub |=(b=ibinding b(val (decimal-relax val.b))))
8889+ =/ fit=ifit (itype-fit (decimal-relax actual) (decimal-relax expected) loose next)
8890+ (decimal-misfit-at e (decimal-relax expected) ?:(?=(%ok -.fit) sub.fit loose))
8891+::
8892+:: +decimal-relax: a type with each decimal's variable taking any aura
8893+::
8894+++ decimal-relax
8895+ |= t=itype
8896+ ^- itype
8897+ ?+ -.t t
8898+ %nvar [%avar id.t]
8899+ %rnvar [%rvar id.t]
8900+ %collection t(args (turn args.t |=(c=itype (decimal-relax c))))
8901+ %grec t(args (turn args.t |=(c=itype (decimal-relax c))))
8902+ %union t(cases (turn cases.t |=(c=itype (decimal-relax c))), args (turn args.t |=(c=itype (decimal-relax c))))
8903+ %face t(body $(t body.t))
8904+ %fn [%fn $(t sample.t) $(t product.t)]
8905+ %cell [%cell $(t hed.t) $(t tal.t)]
8906+ ==
8907+::
8908+:: +decimal-misfit-at: walk a value beside the type it should fit
8909+::
8910+:: Through groups, faces, tuples and term-headed pairs, the union case
8911+:: a tuple's head tag picks, units and list literals.
8912+::
8913+++ decimal-misfit-at
8914+ |= [e=expr expected=itype sub=isub]
8915+ ^- (unit idiag)
8916+ =. expected (itype-walk expected sub)
8917+ ?: ?=(%face -.expected) $(expected body.expected)
8918+ ?+ -.e ~
8919+ %lit (decimal-lit-misfit at.e lit.e expected |)
8920+ %group $(e inner.e)
8921+ %pair $(e (pair-as-cell e))
8922+ %tuple (decimal-misfit-items items.e expected sub)
8923+ %unit
8924+ ?. ?=(%collection -.expected) ~
8925+ ?. &(=(%unit name.expected) ?=([* ~] args.expected)) ~
8926+ $(e val.e, expected i.args.expected)
8927+ %list
8928+ ?. ?=(%collection -.expected) ~
8929+ ?. &(=(%list name.expected) ?=([* ~] args.expected)) ~
8930+ =/ items=(list expr) items.e
8931+ |-
8932+ ?~ items ~
8933+ =/ found=(unit idiag) ^$(e i.items, expected i.args.expected)
8934+ ?^ found found
8935+ $(items t.items)
8936+ ==
8937+::
8938+:: +decimal-misfit-items: a tuple's items beside a cell, the last its tail
8939+::
8940+++ decimal-misfit-items
8941+ |= [items=(list item) expected=itype sub=isub]
8942+ ^- (unit idiag)
8943+ ?~ items ~
8944+ ?~ t.items (decimal-misfit-at val.i.items expected sub)
8945+ =. expected (itype-walk expected sub)
8946+ ?: ?=(%face -.expected) $(expected body.expected)
8947+ ?: ?=(%union -.expected)
8948+ =/ head=expr val.i.items
8949+ ?. ?=(%lit -.head) ~
8950+ =/ case=(unit itype) (decimal-case val.lit.head cases.expected sub)
8951+ ?~ case ~
8952+ $(expected u.case)
8953+ ?. ?=(%cell -.expected) ~
8954+ =/ found=(unit idiag) (decimal-misfit-at val.i.items hed.expected sub)
8955+ ?^ found found
8956+ $(items t.items, expected tal.expected)
8957+::
8958+:: +decimal-pattern-misfit: a decimal pattern where another aura is matched
8959+::
8960+:: The subject's type is known, so no refit is needed. A cell pattern
8961+:: picks its union case by its head, as a tuple does.
8962+::
8963+++ decimal-pattern-misfit
8964+ |= [p=pattern expected=itype sub=isub]
8965+ ^- (unit idiag)
8966+ =. expected (itype-walk expected sub)
8967+ ?: ?=(%face -.expected) $(expected body.expected)
8968+ ?: ?=(%lit -.p) (decimal-lit-misfit at.p lit.p expected &)
8969+ ?. ?=(%cell -.p) ~
8970+ (decimal-pattern-items items.p expected sub)
8971+::
8972+:: +decimal-pattern-items: a cell pattern's items, as +decimal-misfit-items
8973+::
8974+++ decimal-pattern-items
8975+ |= [items=(list pattern) expected=itype sub=isub]
8976+ ^- (unit idiag)
8977+ ?~ items ~
8978+ ?~ t.items (decimal-pattern-misfit i.items expected sub)
8979+ =. expected (itype-walk expected sub)
8980+ ?: ?=(%face -.expected) $(expected body.expected)
8981+ ?: ?=(%union -.expected)
8982+ ?. ?=(%lit -.i.items) ~
8983+ =/ case=(unit itype) (decimal-case val.lit.i.items cases.expected sub)
8984+ ?~ case ~
8985+ $(expected u.case)
8986+ ?. ?=(%cell -.expected) ~
8987+ =/ found=(unit idiag) (decimal-pattern-misfit i.items hed.expected sub)
8988+ ?^ found found
8989+ $(items t.items, expected tal.expected)
8990+::
8991+:: +decimal-arms-misfit: the first arm whose pattern has a misplaced decimal
8992+::
8993+++ decimal-arms-misfit
8994+ |= [arms=(list arm) subject=itype sub=isub]
8995+ ^- (unit idiag)
8996+ ?~ arms ~
8997+ =/ found=(unit idiag) (decimal-pattern-misfit pat.i.arms subject sub)
8998+ ?^ found found
8999+ $(arms t.arms)
9000+::
9001+:: +decimal-case: the one union case whose head is the constant value
9002+::
9003+++ decimal-case
9004+ |= [value=@ cases=(list itype) sub=isub]
9005+ ^- (unit itype)
9006+ =/ hits=(list itype)
9007+ %+ skim cases
9008+ |= c=itype
9009+ =. c (itype-walk c sub)
9010+ ?. ?=(%cell -.c) |
9011+ =/ head=itype (itype-walk hed.c sub)
9012+ =? head ?=(%face -.head) (itype-walk body.head sub)
9013+ &(?=(%const -.head) =(value val.literal.head))
9014+ ?. ?=([* ~] hits) ~
9015+ `i.hits
9016+::
9017+:: +decimal-lit-misfit: the error for a decimal at a place of known type
9018+::
9019+++ decimal-lit-misfit
9020+ |= [at=span l=lit expected=itype pattern=?]
9021+ ^- (unit idiag)
9022+ ?. &(=(%number form.l) =(%ud aura.l)) ~
9023+ ?. ?=(%atom -.expected) ~
9024+ ?: (decimal-aura aura.expected) ~
9025+ `[(decimal-misfit-msg l aura.expected pattern) ~[[at "decimal"]]]
9026+::
9027+:: +decimal-misfit-msg: "`30` is a @ud, not a @dr; write ~s30"
9028+::
9029+:: The hint writes the value in the expected aura's own literal where
9030+:: that reads naturally: 30 seconds, the text "30", the ship ~syd; a
9031+:: date gets an example. Patterns take no dates, durations or knots,
9032+:: so in a pattern those auras get no hint.
9033+::
9034+++ decimal-misfit-msg
9035+ |= [l=lit aura=@ta pattern=?]
9036+ ^- tape
9037+ =/ what=tape "`{(trip txt.l)}` is a @ud, not a @{(trip aura)}"
9038+ =/ hint=tape
9039+ ?: &(pattern ?=(?(%da %dr %ta) aura)) ""
9040+ ?+ aura ""
9041+ %da "a date, as ~2026.1.1"
9042+ %dr (trip (scot %dr (mul val.l ~s1)))
9043+ %p (trip (scot %p val.l))
9044+ %t (show-quoted txt.l)
9045+ %ta "~.{(trip txt.l)}"
9046+ %ux (trip (scot %ux val.l))
9047+ %uv (trip (scot %uv val.l))
9048+ ==
9049+ ?~ hint what
9050+ "{what}; write {hint}"
9051+::
88209052:: A term-headed pair is the same noun as a two-item cell. Preserve the
88219053:: whole pair span for the synthetic head and the value's own span for
88229054:: the payload; unresolved term constraints follow ordinary cell inference.
@@ -8874,7 +9106,7 @@
88749106 ?. =(u.standard [[%collection %list ~[[%var 0]]] ~[0]])
88759107 [%| ["list literal needs the standard prelude in partial inference" ~]]
88769108 =/ element=itype [%var next.state]
8877− =/ result=iresult (infer-open-list-items items.e element env state(next +(next.state)) at.e)
9109+ =/ result=iresult (infer-open-list-items items.e element env state(next +(next.state)) at.e ~)
88789110 ?: ?=(%| -.result) result
88799111 [%& [%collection %list ~[element]] state.p.result]
88809112 %str (infer-string-pieces pieces.e env state)
@@ -9002,6 +9234,10 @@
90029234 [%| ["record branch matching is not supported by partial inference" ~]]
90039235 ?: |((itype-has-any-atom typ.p.left sub.state.p.right) (itype-has-any-atom typ.p.right sub.state.p.right) (itype-family-related typ.p.left typ.p.right sub.state.p.right))
90049236 [%| ["branch widening is not supported by partial inference" ~]]
9237+ =/ decimal-x=(unit idiag) (decimal-misfit val.x typ.p.left typ.p.right sub.state.p.right next.state.p.right)
9238+ ?^ decimal-x [%| u.decimal-x]
9239+ =/ decimal-y=(unit idiag) (decimal-misfit val.y typ.p.right typ.p.left sub.state.p.right next.state.p.right)
9240+ ?^ decimal-y [%| u.decimal-y]
90059241 [%| ["branch arms have incompatible types" ~[[(span-of val.x) (site-type-note "first arm" typ.p.left sub.state.p.right)] [(span-of val.y) (site-type-note "second arm" typ.p.right sub.state.p.right)]]]]
90069242 [%& typ.u.joined state.p.right(sub sub.u.joined)]
90079243 %cast
@@ -9023,6 +9259,8 @@
90239259 ?^ missing [%| u.missing]
90249260 =/ nested=(unit idiag) (nested-missing-tag val.e typ.p.value typ.u.target sub.state.p.value next.state.p.value at.shape.e)
90259261 ?^ nested [%| u.nested]
9262+ =/ decimal=(unit idiag) (decimal-misfit val.e typ.p.value typ.u.target sub.state.p.value next.state.p.value)
9263+ ?^ decimal [%| u.decimal]
90269264 [%| ["cast mold and expression type do not unify" ~[[at.shape.e (site-type-note "cast mold" typ.u.target sub.state.p.value)] [(span-of val.e) (site-type-note "expression" typ.p.value sub.state.p.value)]]]]
90279265 ?: &(?=(^ defer.state.p.value) !(dg-stable-fit typ.p.value typ.u.target sub.fit))
90289266 [%| ["deferred cast fit needs stable inference" ~]]
@@ -9346,11 +9584,17 @@
93469584 ?^ missing [%| u.missing]
93479585 =/ nested=(unit idiag) (nested-missing-tag i.args.e typ.p.arg sample.ht sub.st next.st (span-of head.e))
93489586 ?^ nested [%| u.nested]
9587+ =/ decimal=(unit idiag) (decimal-misfit i.args.e typ.p.arg sample.ht sub.st next.st)
9588+ ?^ decimal [%| u.decimal]
93499589 [%| ["call's sample and argument types do not unify" ~[[(span-of head.e) (site-type-note "called gate" ht sub.st)] [(span-of i.args.e) (site-type-note "argument" typ.p.arg sub.st)]]]]
93509590 =/ bad=(unit [at=span typ=itype])
93519591 (call-error-site args.e typ.p.arg sample.ht sub.st next.st)
93529592 =/ whole-args=span
93539593 [beg:(span-of i.args.e) end:(span-of (rear args.e))]
9594+ =/ decimal=(unit idiag)
9595+ =/ items=(list item) (turn args.e |=(a=expr [(span-of a) ~ a]))
9596+ (decimal-misfit [%tuple whole-args items] typ.p.arg sample.ht sub.st next.st)
9597+ ?^ decimal [%| u.decimal]
93549598 =/ arg-at=span ?~(bad whole-args at.u.bad)
93559599 =/ arg-type=itype ?~(bad typ.p.arg typ.u.bad)
93569600 [%| ["call's sample and argument types do not unify" ~[[(span-of head.e) (site-type-note "called gate" ht sub.st)] [arg-at (site-type-note "argument" arg-type sub.st)]]]]
@@ -9421,6 +9665,8 @@
94219665 ?^ missing [%| u.missing]
94229666 =/ nested=(unit idiag) (nested-missing-tag val.e typ.p.value payload sub.state.p.value next.state.p.value context)
94239667 ?^ nested [%| u.nested]
9668+ =/ decimal=(unit idiag) (decimal-misfit val.e typ.p.value payload sub.state.p.value next.state.p.value)
9669+ ?^ decimal [%| u.decimal]
94249670 [%| ["unit payload does not fit its expected type" ~[[context (site-type-note "expected unit payload" payload sub.state.p.value)] [(span-of val.e) (site-type-note "payload" typ.p.value sub.state.p.value)]]]]
94259671 [%& expected state.p.value(sub sub.fit, next next.fit)]
94269672::