on master help sign in
Let a bare decimal fit only @ud and its ancestors

A decimal literal is a @ud, as in Hoon: its variable now binds only @ud or @u in +itype-unify (+decimal-aura), and it still fits @ and *. Every other aura needs its own literal, so ^- @dr 30, ^- @p 0, (text 5) and [%every 1 |=%tick] are type errors. A ++ generic over a decimal's aura still generalizes it, so (bump ~s1) checks. Where a fit fails, +decimal-misfit refits with each decimal widened to any aura, so a generic gate's capital learns its aura from the other arguments, then walks the value's syntax beside the expected type. The first decimal at an atom of another aura gets the error "`30` is a @ud, not a @dr; write ~s30", with the value in that aura's literal where Jibb has one. Casts, call arguments, change fields, list items and tails, unit payloads, branch joins and contextual arms use it, and a ?- over a known union or an atom checks its number patterns against the subject the same way. Goldens: new inline-decimal-fits, -generic, -aura-bad, -sites and -patterns. types-partial-aura casts to @u instead of @ux, and types-partial-aura-generalization likewise; types-local-error-order uses 0x1 beside 0x2 and types-prelude-like builds its tape with trip, keeping what each tested; types-list-open-constraints' ~[1 0x1f] is now the new error. jibb-arithmetic-guards binds the combined variable to @u and checks that @ux is refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U4FzmThon6Q3x1uL8yUKEY

commitc4e28d287d7364032e484cd16cbfe231a71a105e authorClaude <noreply@anthropic.com> dateTue 3 Nov 2026, 02:53 (4 hours ago) parentd4aed71
47 files changed+1410−54
jibb-dev/lib/jibb.hoon+256−10 tests/golden/inline-decimal-aura-bad/about.txt+4 tests/golden/inline-decimal-aura-bad/source.jibb+10 tests/golden/inline-decimal-aura-bad/tokens.txt+60 tests/golden/inline-decimal-aura-bad/tree.txt+21 tests/golden/inline-decimal-aura-bad/types.txt+41 tests/golden/inline-decimal-fits/about.txt+4 tests/golden/inline-decimal-fits/modules.txt+1 tests/golden/inline-decimal-fits/source.jibb+9 tests/golden/inline-decimal-fits/tokens.txt+64 tests/golden/inline-decimal-fits/tree.txt+23 tests/golden/inline-decimal-fits/types.txt+10 tests/golden/inline-decimal-generic/about.txt+4 tests/golden/inline-decimal-generic/modules.txt+1 tests/golden/inline-decimal-generic/source.jibb+5 tests/golden/inline-decimal-generic/tokens.txt+40 tests/golden/inline-decimal-generic/tree.txt+18 tests/golden/inline-decimal-generic/types.txt+6 tests/golden/inline-decimal-patterns/about.txt+4 tests/golden/inline-decimal-patterns/source.jibb+30 tests/golden/inline-decimal-patterns/tokens.txt+181 tests/golden/inline-decimal-patterns/tree.txt+82 tests/golden/inline-decimal-patterns/types.txt+28 tests/golden/inline-decimal-sites/about.txt+4 tests/golden/inline-decimal-sites/modules.txt+1 tests/golden/inline-decimal-sites/source.jibb+24 tests/golden/inline-decimal-sites/tokens.txt+258 tests/golden/inline-decimal-sites/tree.txt+103 tests/golden/inline-decimal-sites/types.txt+69 tests/golden/types-list-open-constraints/about.txt+1−1 tests/golden/types-list-open-constraints/types.txt+4−1 tests/golden/types-local-error-order/about.txt+1−1 tests/golden/types-local-error-order/source.jibb+3−3 tests/golden/types-local-error-order/tokens.txt+3−3 tests/golden/types-local-error-order/tree.txt+3−3 tests/golden/types-partial-aura-generalization/source.jibb+1−1 tests/golden/types-partial-aura-generalization/tokens.txt+8−8 tests/golden/types-partial-aura-generalization/tree.txt+5−5 tests/golden/types-partial-aura-generalization/types.txt+1−1 tests/golden/types-partial-aura/source.jibb+1−1 tests/golden/types-partial-aura/tokens.txt+2−2 tests/golden/types-partial-aura/tree.txt+1−1 tests/golden/types-partial-aura/types.txt+1−1 tests/golden/types-prelude-like/source.jibb+1−1 tests/golden/types-prelude-like/tokens.txt+7−7 tests/golden/types-prelude-like/tree.txt+2−1 tests/lib/jibb-arithmetic-guards.hoon+4−3
jibb-dev/lib/jibb.hoon+256−10
@@ -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::
tests/golden/inline-decimal-aura-bad/about.txtnew file+4
@@ -0,0 +1,4 @@
1+source: Grammar, Literals by context: "every other aura takes its own literal, as `~s30` for a `@dr`, `~2026.1.1` for a `@da`, `~zod` for a `@p`, `"5"` for a `@t` and `0x1` for a `@ux`. So `^- @dr 30`, `^- @p 0` … are errors, each naming the number and the aura it met".
2+tests: A decimal cast to an aura outside `@ud`'s family is an error at the decimal, naming it and the aura; the hint writes the same value in that aura's literal (~s30, ~zod, "5", ~.30, 0x1, 0vu), a date gets an example, and `@tas` and `@tD`, which have no literal of their own, get no hint.
3+expect: parses
4+expect-types: a partial inference report
tests/golden/inline-decimal-aura-bad/source.jibbnew file+10
@@ -0,0 +1,10 @@
1+++ duration ^- @dr 30
2+++ date ^- @da 30
3+++ ship ^- @p 0
4+++ cord ^- @t 5
5+++ grouped ^- @t 1.000
6+++ knot ^- @ta 30
7+++ hex ^- @ux 1
8+++ base32 ^- @uv 30
9+++ term ^- @tas 30
10+++ char ^- @tD 97
tests/golden/inline-decimal-aura-bad/tokens.txtnew file+60
@@ -0,0 +1,60 @@
1+1:1 glyph ++
2+1:4 name duration
3+1:13 glyph ^-
4+1:16 aura @dr
5+1:20 lit 30
6+2:1 NEWLINE
7+2:1 glyph ++
8+2:4 name date
9+2:9 glyph ^-
10+2:12 aura @da
11+2:16 lit 30
12+3:1 NEWLINE
13+3:1 glyph ++
14+3:4 name ship
15+3:9 glyph ^-
16+3:12 aura @p
17+3:15 lit 0
18+4:1 NEWLINE
19+4:1 glyph ++
20+4:4 name cord
21+4:9 glyph ^-
22+4:12 aura @t
23+4:15 lit 5
24+5:1 NEWLINE
25+5:1 glyph ++
26+5:4 name grouped
27+5:12 glyph ^-
28+5:15 aura @t
29+5:18 lit 1.000
30+6:1 NEWLINE
31+6:1 glyph ++
32+6:4 name knot
33+6:9 glyph ^-
34+6:12 aura @ta
35+6:16 lit 30
36+7:1 NEWLINE
37+7:1 glyph ++
38+7:4 name hex
39+7:8 glyph ^-
40+7:11 aura @ux
41+7:15 lit 1
42+8:1 NEWLINE
43+8:1 glyph ++
44+8:4 name base32
45+8:11 glyph ^-
46+8:14 aura @uv
47+8:18 lit 30
48+9:1 NEWLINE
49+9:1 glyph ++
50+9:4 name term
51+9:9 glyph ^-
52+9:12 aura @tas
53+9:17 lit 30
54+10:1 NEWLINE
55+10:1 glyph ++
56+10:4 name char
57+10:9 glyph ^-
58+10:12 aura @tD
59+10:16 lit 97
60+10:18 NEWLINE
tests/golden/inline-decimal-aura-bad/tree.txtnew file+21
@@ -0,0 +1,21 @@
1+(module
2+ (value 1:1 duration
3+ (cast 1:13 (aura 1:16 @dr) (lit 1:20 30)))
4+ (value 2:1 date
5+ (cast 2:9 (aura 2:12 @da) (lit 2:16 30)))
6+ (value 3:1 ship
7+ (cast 3:9 (aura 3:12 @p) (lit 3:15 0)))
8+ (value 4:1 cord
9+ (cast 4:9 (aura 4:12 @t) (lit 4:15 5)))
10+ (value 5:1 grouped
11+ (cast 5:12 (aura 5:15 @t) (lit 5:18 1.000)))
12+ (value 6:1 knot
13+ (cast 6:9 (aura 6:12 @ta) (lit 6:16 30)))
14+ (value 7:1 hex
15+ (cast 7:8 (aura 7:11 @ux) (lit 7:15 1)))
16+ (value 8:1 base32
17+ (cast 8:11 (aura 8:14 @uv) (lit 8:18 30)))
18+ (value 9:1 term
19+ (cast 9:9 (aura 9:12 @tas) (lit 9:17 30)))
20+ (value 10:1 char
21+ (cast 10:9 (aura 10:12 @tD) (lit 10:16 97))))
tests/golden/inline-decimal-aura-bad/types.txtnew file+41
@@ -0,0 +1,41 @@
1+partial inference; module not checked
2+++ duration: `30` is a @ud, not a @dr; write ~s30
3+/tests/golden/inline-decimal-aura-bad/source.jibb:1:20: decimal
4+++ duration ^- @dr 30
5+ ^
6+++ date: `30` is a @ud, not a @da; write a date, as ~2026.1.1
7+/tests/golden/inline-decimal-aura-bad/source.jibb:2:16: decimal
8+++ date ^- @da 30
9+ ^
10+++ ship: `0` is a @ud, not a @p; write ~zod
11+/tests/golden/inline-decimal-aura-bad/source.jibb:3:15: decimal
12+++ ship ^- @p 0
13+ ^
14+++ cord: `5` is a @ud, not a @t; write "5"
15+/tests/golden/inline-decimal-aura-bad/source.jibb:4:15: decimal
16+++ cord ^- @t 5
17+ ^
18+++ grouped: `1.000` is a @ud, not a @t; write "1.000"
19+/tests/golden/inline-decimal-aura-bad/source.jibb:5:18: decimal
20+++ grouped ^- @t 1.000
21+ ^
22+++ knot: `30` is a @ud, not a @ta; write ~.30
23+/tests/golden/inline-decimal-aura-bad/source.jibb:6:16: decimal
24+++ knot ^- @ta 30
25+ ^
26+++ hex: `1` is a @ud, not a @ux; write 0x1
27+/tests/golden/inline-decimal-aura-bad/source.jibb:7:15: decimal
28+++ hex ^- @ux 1
29+ ^
30+++ base32: `30` is a @ud, not a @uv; write 0vu
31+/tests/golden/inline-decimal-aura-bad/source.jibb:8:18: decimal
32+++ base32 ^- @uv 30
33+ ^
34+++ term: `30` is a @ud, not a @tas
35+/tests/golden/inline-decimal-aura-bad/source.jibb:9:17: decimal
36+++ term ^- @tas 30
37+ ^
38+++ char: `97` is a @ud, not a @tD
39+/tests/golden/inline-decimal-aura-bad/source.jibb:10:16: decimal
40+++ char ^- @tD 97
41+ ^
tests/golden/inline-decimal-fits/about.txtnew file+4
@@ -0,0 +1,4 @@
1+source: Grammar, Literals: a decimal is "`@ud`, which also fits `@u`, `@` and `*`"; Literals by context: "A number is a `@ud`, as in Hoon: a context can make it a `@u`, and it fits `@` and `*`".
2+tests: A decimal fits `@ud`, `@u`, bare `@` and the noun `*`, in casts, as an argument beside a `@u` and as list items; with nothing to fix it, it takes `@ud`. A hexadecimal fits `@ux`.
3+expect: parses
4+expect-types: a partial inference report
tests/golden/inline-decimal-fits/modules.txtnew file+1
@@ -0,0 +1 @@
1+# no module fixtures
tests/golden/inline-decimal-fits/source.jibbnew file+9
@@ -0,0 +1,9 @@
1+++ plain ^- @ud 30
2+++ unsigned ^- @u 30
3+++ atom ^- @ 30
4+++ noun ^- * 30
5+++ grouped ^- @ud 1.000
6+++ sum |= x=@u (add x 1)
7+++ counts ^- (list @u) ~[1 2]
8+++ count 7
9+++ hex ^- @ux 0x1e
tests/golden/inline-decimal-fits/tokens.txtnew file+64
@@ -0,0 +1,64 @@
1+1:1 glyph ++
2+1:4 name plain
3+1:10 glyph ^-
4+1:13 aura @ud
5+1:17 lit 30
6+2:1 NEWLINE
7+2:1 glyph ++
8+2:4 name unsigned
9+2:13 glyph ^-
10+2:16 aura @u
11+2:19 lit 30
12+3:1 NEWLINE
13+3:1 glyph ++
14+3:4 name atom
15+3:9 glyph ^-
16+3:12 aura @
17+3:14 lit 30
18+4:1 NEWLINE
19+4:1 glyph ++
20+4:4 name noun
21+4:9 glyph ^-
22+4:12 glyph *
23+4:14 lit 30
24+5:1 NEWLINE
25+5:1 glyph ++
26+5:4 name grouped
27+5:12 glyph ^-
28+5:15 aura @ud
29+5:19 lit 1.000
30+6:1 NEWLINE
31+6:1 glyph ++
32+6:4 name sum
33+6:8 glyph |=
34+6:11 name x
35+6:12 tight glyph =
36+6:13 tight aura @u
37+6:16 glyph (
38+6:17 tight name add
39+6:21 name x
40+6:23 lit 1
41+6:24 tight glyph )
42+7:1 NEWLINE
43+7:1 glyph ++
44+7:4 name counts
45+7:11 glyph ^-
46+7:14 glyph (
47+7:15 tight name list
48+7:20 aura @u
49+7:22 tight glyph )
50+7:24 glyph ~[
51+7:26 tight lit 1
52+7:28 lit 2
53+7:29 tight glyph ]
54+8:1 NEWLINE
55+8:1 glyph ++
56+8:4 name count
57+8:10 lit 7
58+9:1 NEWLINE
59+9:1 glyph ++
60+9:4 name hex
61+9:8 glyph ^-
62+9:11 aura @ux
63+9:15 lit 0x1e
64+9:19 NEWLINE
tests/golden/inline-decimal-fits/tree.txtnew file+23
@@ -0,0 +1,23 @@
1+(module
2+ (value 1:1 plain
3+ (cast 1:10 (aura 1:13 @ud) (lit 1:17 30)))
4+ (value 2:1 unsigned
5+ (cast 2:13 (aura 2:16 @u) (lit 2:19 30)))
6+ (value 3:1 atom
7+ (cast 3:9 (aura 3:12 @) (lit 3:14 30)))
8+ (value 4:1 noun
9+ (cast 4:9 (noun 4:12) (lit 4:14 30)))
10+ (value 5:1 grouped
11+ (cast 5:12 (aura 5:15 @ud) (lit 5:19 1.000)))
12+ (value 6:1 sum
13+ (gate 6:8
14+ (face 6:11 x (aura 6:13 @u))
15+ (group 6:16
16+ (call 6:17 (wing 6:17 add) (wing 6:21 x) (lit 6:23 1)))))
17+ (value 7:1 counts
18+ (cast 7:11
19+ (apply 7:14 list (aura 7:20 @u))
20+ (list 7:24 (lit 7:26 1) (lit 7:28 2))))
21+ (value 8:1 count (lit 8:10 7))
22+ (value 9:1 hex
23+ (cast 9:8 (aura 9:11 @ux) (lit 9:15 0x1e))))
tests/golden/inline-decimal-fits/types.txtnew file+10
@@ -0,0 +1,10 @@
1+partial inference; module not checked
2+++ plain: @ud
3+++ unsigned: @u
4+++ atom: @
5+++ noun: *
6+++ grouped: @ud
7+++ sum: $-(@u @u)
8+++ counts: (list @u)
9+++ count: @ud
10+++ hex: @ux
tests/golden/inline-decimal-generic/about.txtnew file+4
@@ -0,0 +1,4 @@
1+source: Grammar, Literals by context: "A number takes `@ud` only if nothing fixes its aura and its `++` isn't generic over it, so `++ inc |= n=A (add n 1)` stays generic, and `(inc ~s1)` is a `@dr`".
2+tests: A decimal inside a `++` that is generic over its aura stays generic: `bump` takes any atom but `?`, so a duration, a hexadecimal and a ship each keep their aura, and a decimal argument is a `@ud`.
3+expect: parses
4+expect-types: a partial inference report
tests/golden/inline-decimal-generic/modules.txtnew file+1
@@ -0,0 +1 @@
1+# no module fixtures
tests/golden/inline-decimal-generic/source.jibbnew file+5
@@ -0,0 +1,5 @@
1+++ bump |= x=A (add x 1)
2+++ later (bump ~s1)
3+++ hex (bump 0x1)
4+++ ship (bump ~zod)
5+++ count (bump 2)
tests/golden/inline-decimal-generic/tokens.txtnew file+40
@@ -0,0 +1,40 @@
1+1:1 glyph ++
2+1:4 name bump
3+1:9 glyph |=
4+1:12 name x
5+1:13 tight glyph =
6+1:14 tight tvar A
7+1:16 glyph (
8+1:17 tight name add
9+1:21 name x
10+1:23 lit 1
11+1:24 tight glyph )
12+2:1 NEWLINE
13+2:1 glyph ++
14+2:4 name later
15+2:10 glyph (
16+2:11 tight name bump
17+2:16 lit ~s1
18+2:19 tight glyph )
19+3:1 NEWLINE
20+3:1 glyph ++
21+3:4 name hex
22+3:8 glyph (
23+3:9 tight name bump
24+3:14 lit 0x1
25+3:17 tight glyph )
26+4:1 NEWLINE
27+4:1 glyph ++
28+4:4 name ship
29+4:9 glyph (
30+4:10 tight name bump
31+4:15 lit ~zod
32+4:19 tight glyph )
33+5:1 NEWLINE
34+5:1 glyph ++
35+5:4 name count
36+5:10 glyph (
37+5:11 tight name bump
38+5:16 lit 2
39+5:17 tight glyph )
40+5:18 NEWLINE
tests/golden/inline-decimal-generic/tree.txtnew file+18
@@ -0,0 +1,18 @@
1+(module
2+ (value 1:1 bump
3+ (gate 1:9
4+ (face 1:12 x (tvar 1:14 A))
5+ (group 1:16
6+ (call 1:17 (wing 1:17 add) (wing 1:21 x) (lit 1:23 1)))))
7+ (value 2:1 later
8+ (group 2:10
9+ (call 2:11 (wing 2:11 bump) (lit 2:16 ~s1))))
10+ (value 3:1 hex
11+ (group 3:8
12+ (call 3:9 (wing 3:9 bump) (lit 3:14 0x1))))
13+ (value 4:1 ship
14+ (group 4:9
15+ (call 4:10 (wing 4:10 bump) (lit 4:15 ~zod))))
16+ (value 5:1 count
17+ (group 5:10
18+ (call 5:11 (wing 5:11 bump) (lit 5:16 2)))))
tests/golden/inline-decimal-generic/types.txtnew file+6
@@ -0,0 +1,6 @@
1+partial inference; module not checked
2+++ bump: $-(A A) where A is an atom other than ?
3+++ later: @dr
4+++ hex: @ux
5+++ ship: @p
6+++ count: @ud
tests/golden/inline-decimal-patterns/about.txtnew file+4
@@ -0,0 +1,4 @@
1+source: Grammar, Patterns: "A number pattern is a `@ud` too, so `0` can't match a `@p` or a `@dr`: write `~zod`, or compare a duration with `eq`".
2+tests: A number pattern where the subject, a union case's field or a cell's item is a `@dr`, `@p`, `@t` or `@da` is an error at the first such pattern, with a hint only where patterns take that aura's literal. Number patterns on a `@ud` keep the checker's existing unsupported messages.
3+expect: parses
4+expect-types: a partial inference report
tests/golden/inline-decimal-patterns/source.jibbnew file+30
@@ -0,0 +1,30 @@
1++$ event
2+ [%gap d=@dr]
3+ [%count n=@ud]
4+++ on-gap |= d=@dr ?- d
5+ 0 %zero
6+ * %other
7+++ on-ship |= s=@p ?- s
8+ 0 %zod
9+ * %other
10+++ on-text |= t=@t ?- t
11+ 5 %five
12+ * %other
13+++ on-date |= d=@da ?- d
14+ 0 %epoch
15+ 1 %next
16+ * %other
17+++ on-event |= e=event ?- e
18+ [%gap 0] 1
19+ [%gap *] 2
20+ [%count 0] 3
21+ [%count *] 4
22+++ on-pair |= [d=@dr n=@ud] ?- [d n]
23+ [0 0] 1
24+ * 2
25+++ on-count |= n=@ud ?- n
26+ 0 %zero
27+ * %other
28+++ on-counts |= e=event ?- e
29+ [%count 0] 3
30+ * 4
tests/golden/inline-decimal-patterns/tokens.txtnew file+181
@@ -0,0 +1,181 @@
1+1:1 glyph +$
2+1:4 name event
3+2:3 INDENT
4+2:3 glyph [
5+2:4 tight lit %gap
6+2:9 name d
7+2:10 tight glyph =
8+2:11 tight aura @dr
9+2:14 tight glyph ]
10+3:3 NEWLINE
11+3:3 glyph [
12+3:4 tight lit %count
13+3:11 name n
14+3:12 tight glyph =
15+3:13 tight aura @ud
16+3:16 tight glyph ]
17+4:1 DEDENT
18+4:1 NEWLINE
19+4:1 glyph ++
20+4:4 name on-gap
21+4:11 glyph |=
22+4:14 name d
23+4:15 tight glyph =
24+4:16 tight aura @dr
25+4:20 glyph ?-
26+4:23 name d
27+5:3 INDENT
28+5:3 lit 0
29+5:5 lit %zero
30+6:3 NEWLINE
31+6:3 glyph *
32+6:5 lit %other
33+7:1 DEDENT
34+7:1 NEWLINE
35+7:1 glyph ++
36+7:4 name on-ship
37+7:12 glyph |=
38+7:15 name s
39+7:16 tight glyph =
40+7:17 tight aura @p
41+7:20 glyph ?-
42+7:23 name s
43+8:3 INDENT
44+8:3 lit 0
45+8:5 lit %zod
46+9:3 NEWLINE
47+9:3 glyph *
48+9:5 lit %other
49+10:1 DEDENT
50+10:1 NEWLINE
51+10:1 glyph ++
52+10:4 name on-text
53+10:12 glyph |=
54+10:15 name t
55+10:16 tight glyph =
56+10:17 tight aura @t
57+10:20 glyph ?-
58+10:23 name t
59+11:3 INDENT
60+11:3 lit 5
61+11:5 lit %five
62+12:3 NEWLINE
63+12:3 glyph *
64+12:5 lit %other
65+13:1 DEDENT
66+13:1 NEWLINE
67+13:1 glyph ++
68+13:4 name on-date
69+13:12 glyph |=
70+13:15 name d
71+13:16 tight glyph =
72+13:17 tight aura @da
73+13:21 glyph ?-
74+13:24 name d
75+14:3 INDENT
76+14:3 lit 0
77+14:5 lit %epoch
78+15:3 NEWLINE
79+15:3 lit 1
80+15:5 lit %next
81+16:3 NEWLINE
82+16:3 glyph *
83+16:5 lit %other
84+17:1 DEDENT
85+17:1 NEWLINE
86+17:1 glyph ++
87+17:4 name on-event
88+17:13 glyph |=
89+17:16 name e
90+17:17 tight glyph =
91+17:18 tight name event
92+17:24 glyph ?-
93+17:27 name e
94+18:3 INDENT
95+18:3 glyph [
96+18:4 tight lit %gap
97+18:9 lit 0
98+18:10 tight glyph ]
99+18:12 lit 1
100+19:3 NEWLINE
101+19:3 glyph [
102+19:4 tight lit %gap
103+19:9 glyph *
104+19:10 tight glyph ]
105+19:12 lit 2
106+20:3 NEWLINE
107+20:3 glyph [
108+20:4 tight lit %count
109+20:11 lit 0
110+20:12 tight glyph ]
111+20:14 lit 3
112+21:3 NEWLINE
113+21:3 glyph [
114+21:4 tight lit %count
115+21:11 glyph *
116+21:12 tight glyph ]
117+21:14 lit 4
118+22:1 DEDENT
119+22:1 NEWLINE
120+22:1 glyph ++
121+22:4 name on-pair
122+22:12 glyph |=
123+22:15 glyph [
124+22:16 tight name d
125+22:17 tight glyph =
126+22:18 tight aura @dr
127+22:22 name n
128+22:23 tight glyph =
129+22:24 tight aura @ud
130+22:27 tight glyph ]
131+22:29 glyph ?-
132+22:32 glyph [
133+22:33 tight name d
134+22:35 name n
135+22:36 tight glyph ]
136+23:3 INDENT
137+23:3 glyph [
138+23:4 tight lit 0
139+23:6 lit 0
140+23:7 tight glyph ]
141+23:9 lit 1
142+24:3 NEWLINE
143+24:3 glyph *
144+24:5 lit 2
145+25:1 DEDENT
146+25:1 NEWLINE
147+25:1 glyph ++
148+25:4 name on-count
149+25:13 glyph |=
150+25:16 name n
151+25:17 tight glyph =
152+25:18 tight aura @ud
153+25:22 glyph ?-
154+25:25 name n
155+26:3 INDENT
156+26:3 lit 0
157+26:5 lit %zero
158+27:3 NEWLINE
159+27:3 glyph *
160+27:5 lit %other
161+28:1 DEDENT
162+28:1 NEWLINE
163+28:1 glyph ++
164+28:4 name on-counts
165+28:14 glyph |=
166+28:17 name e
167+28:18 tight glyph =
168+28:19 tight name event
169+28:25 glyph ?-
170+28:28 name e
171+29:3 INDENT
172+29:3 glyph [
173+29:4 tight lit %count
174+29:11 lit 0
175+29:12 tight glyph ]
176+29:14 lit 3
177+30:3 NEWLINE
178+30:3 glyph *
179+30:5 lit 4
180+30:6 DEDENT
181+30:6 NEWLINE
tests/golden/inline-decimal-patterns/tree.txtnew file+82
@@ -0,0 +1,82 @@
1+(module
2+ (mold 1:1 event
3+ (union 2:3
4+ (cell 2:3
5+ (const 2:4 %gap)
6+ (face 2:9 d (aura 2:11 @dr)))
7+ (cell 3:3
8+ (const 3:4 %count)
9+ (face 3:11 n (aura 3:13 @ud)))))
10+ (value 4:1 on-gap
11+ (gate 4:11
12+ (face 4:14 d (aura 4:16 @dr))
13+ (branch 4:20
14+ (wing 4:23 d)
15+ (arm 5:3 (lit 5:3 0) (lit 5:5 %zero))
16+ (arm 6:3 (any 6:3) (lit 6:5 %other)))))
17+ (value 7:1 on-ship
18+ (gate 7:12
19+ (face 7:15 s (aura 7:17 @p))
20+ (branch 7:20
21+ (wing 7:23 s)
22+ (arm 8:3 (lit 8:3 0) (lit 8:5 %zod))
23+ (arm 9:3 (any 9:3) (lit 9:5 %other)))))
24+ (value 10:1 on-text
25+ (gate 10:12
26+ (face 10:15 t (aura 10:17 @t))
27+ (branch 10:20
28+ (wing 10:23 t)
29+ (arm 11:3 (lit 11:3 5) (lit 11:5 %five))
30+ (arm 12:3 (any 12:3) (lit 12:5 %other)))))
31+ (value 13:1 on-date
32+ (gate 13:12
33+ (face 13:15 d (aura 13:17 @da))
34+ (branch 13:21
35+ (wing 13:24 d)
36+ (arm 14:3 (lit 14:3 0) (lit 14:5 %epoch))
37+ (arm 15:3 (lit 15:3 1) (lit 15:5 %next))
38+ (arm 16:3 (any 16:3) (lit 16:5 %other)))))
39+ (value 17:1 on-event
40+ (gate 17:13
41+ (face 17:16 e (ref 17:18 event))
42+ (branch 17:24
43+ (wing 17:27 e)
44+ (arm 18:3
45+ (cell 18:3 (lit 18:4 %gap) (lit 18:9 0))
46+ (lit 18:12 1))
47+ (arm 19:3
48+ (cell 19:3 (lit 19:4 %gap) (any 19:9))
49+ (lit 19:12 2))
50+ (arm 20:3
51+ (cell 20:3 (lit 20:4 %count) (lit 20:11 0))
52+ (lit 20:14 3))
53+ (arm 21:3
54+ (cell 21:3 (lit 21:4 %count) (any 21:11))
55+ (lit 21:14 4)))))
56+ (value 22:1 on-pair
57+ (gate 22:12
58+ (cell 22:15
59+ (face 22:16 d (aura 22:18 @dr))
60+ (face 22:22 n (aura 22:24 @ud)))
61+ (branch 22:29
62+ (tuple 22:32 (wing 22:33 d) (wing 22:35 n))
63+ (arm 23:3
64+ (cell 23:3 (lit 23:4 0) (lit 23:6 0))
65+ (lit 23:9 1))
66+ (arm 24:3 (any 24:3) (lit 24:5 2)))))
67+ (value 25:1 on-count
68+ (gate 25:13
69+ (face 25:16 n (aura 25:18 @ud))
70+ (branch 25:22
71+ (wing 25:25 n)
72+ (arm 26:3 (lit 26:3 0) (lit 26:5 %zero))
73+ (arm 27:3 (any 27:3) (lit 27:5 %other)))))
74+ (value 28:1 on-counts
75+ (gate 28:14
76+ (face 28:17 e (ref 28:19 event))
77+ (branch 28:25
78+ (wing 28:28 e)
79+ (arm 29:3
80+ (cell 29:3 (lit 29:4 %count) (lit 29:11 0))
81+ (lit 29:14 3))
82+ (arm 30:3 (any 30:3) (lit 30:5 4))))))
tests/golden/inline-decimal-patterns/types.txtnew file+28
@@ -0,0 +1,28 @@
1+partial inference; module not checked
2++$ event: cases proven disjoint; mold not checked
3+++ on-gap: `0` is a @ud, not a @dr
4+/tests/golden/inline-decimal-patterns/source.jibb:5:3: decimal
5+ 0 %zero
6+ ^
7+++ on-ship: `0` is a @ud, not a @p; write ~zod
8+/tests/golden/inline-decimal-patterns/source.jibb:8:3: decimal
9+ 0 %zod
10+ ^
11+++ on-text: `5` is a @ud, not a @t; write "5"
12+/tests/golden/inline-decimal-patterns/source.jibb:11:3: decimal
13+ 5 %five
14+ ^
15+++ on-date: `0` is a @ud, not a @da
16+/tests/golden/inline-decimal-patterns/source.jibb:14:3: decimal
17+ 0 %epoch
18+ ^
19+++ on-event: `0` is a @ud, not a @dr
20+/tests/golden/inline-decimal-patterns/source.jibb:18:9: decimal
21+ [%gap 0] 1
22+ ^
23+++ on-pair: `0` is a @ud, not a @dr
24+/tests/golden/inline-decimal-patterns/source.jibb:23:4: decimal
25+ [0 0] 1
26+ ^
27+++ on-count: branch is not supported by partial inference
28+++ on-counts: partial union pattern is not supported by partial inference
tests/golden/inline-decimal-sites/about.txtnew file+4
@@ -0,0 +1,4 @@
1+source: Grammar, Literals by context: "So `^- @dr 30`, `^- @p 0`, `(add ~s1 1)` and `(text 5)` are errors, each naming the number and the aura it met"; syntax review S4: `[%every 1 |=%tick]` and `(text 5)`.
2+tests: Every place a decimal meets another aura gives the same error at the decimal: a call's argument, an argument of a generic gate whose other argument fixes the aura (either order), a record field, a change, a list item under a cast, an open list's later or earlier item, a unit payload, a branch arm, a union case picked by its tag inside a list or a cast, a term-headed pair, and `text`'s argument. The duration, text and element controls check.
3+expect: parses
4+expect-types: a partial inference report
tests/golden/inline-decimal-sites/modules.txtnew file+1
@@ -0,0 +1 @@
1+# no module fixtures
tests/golden/inline-decimal-sites/source.jibbnew file+24
@@ -0,0 +1,24 @@
1++$ msg
2+ [%tick at=@da]
3+ [%done n=@ud]
4+++ pause |= d=@dr d
5+++ arg (pause 30)
6+++ later |= d=@dr (add d 1)
7+++ sooner |= d=@dr (add 1 d)
8+++ zero |= d=@dr (eq d 0)
9+++ record ^- [gap=@dr n=@ud] [gap=30 n=1]
10+++ change |= m=[gap=@dr n=@ud] m(gap=30)
11+++ items ^- (list @dr) ~[~s1 2]
12+++ open ~[~s1 2]
13+++ open-first ~[2 ~s1]
14+++ payload ^- (unit @dr) `30
15+++ either |= b=? ?- b
16+ %.y ~s1
17+ %.n 2
18+++ every ^- (list (sub msg)) ~[[%every 1 |=%tick]]
19+++ every-ok ^- (list (sub msg)) ~[[%every ~s1 |=%tick]]
20+++ timer ^- (cmd msg) [%wait 30 [%done 1]]
21+++ timer-pair ^- (cmd msg) wait+[30 [%done 1]]
22+++ note (text 5)
23+++ note-ok (text "5")
24+++ shown ^- (element !!) (text 5)
tests/golden/inline-decimal-sites/tokens.txtnew file+258
@@ -0,0 +1,258 @@
1+1:1 glyph +$
2+1:4 name msg
3+2:3 INDENT
4+2:3 glyph [
5+2:4 tight lit %tick
6+2:10 name at
7+2:12 tight glyph =
8+2:13 tight aura @da
9+2:16 tight glyph ]
10+3:3 NEWLINE
11+3:3 glyph [
12+3:4 tight lit %done
13+3:10 name n
14+3:11 tight glyph =
15+3:12 tight aura @ud
16+3:15 tight glyph ]
17+4:1 DEDENT
18+4:1 NEWLINE
19+4:1 glyph ++
20+4:4 name pause
21+4:10 glyph |=
22+4:13 name d
23+4:14 tight glyph =
24+4:15 tight aura @dr
25+4:19 name d
26+5:1 NEWLINE
27+5:1 glyph ++
28+5:4 name arg
29+5:8 glyph (
30+5:9 tight name pause
31+5:15 lit 30
32+5:17 tight glyph )
33+6:1 NEWLINE
34+6:1 glyph ++
35+6:4 name later
36+6:10 glyph |=
37+6:13 name d
38+6:14 tight glyph =
39+6:15 tight aura @dr
40+6:19 glyph (
41+6:20 tight name add
42+6:24 name d
43+6:26 lit 1
44+6:27 tight glyph )
45+7:1 NEWLINE
46+7:1 glyph ++
47+7:4 name sooner
48+7:11 glyph |=
49+7:14 name d
50+7:15 tight glyph =
51+7:16 tight aura @dr
52+7:20 glyph (
53+7:21 tight name add
54+7:25 lit 1
55+7:27 name d
56+7:28 tight glyph )
57+8:1 NEWLINE
58+8:1 glyph ++
59+8:4 name zero
60+8:9 glyph |=
61+8:12 name d
62+8:13 tight glyph =
63+8:14 tight aura @dr
64+8:18 glyph (
65+8:19 tight name eq
66+8:22 name d
67+8:24 lit 0
68+8:25 tight glyph )
69+9:1 NEWLINE
70+9:1 glyph ++
71+9:4 name record
72+9:11 glyph ^-
73+9:14 glyph [
74+9:15 tight name gap
75+9:18 tight glyph =
76+9:19 tight aura @dr
77+9:23 name n
78+9:24 tight glyph =
79+9:25 tight aura @ud
80+9:28 tight glyph ]
81+9:30 glyph [
82+9:31 tight name gap
83+9:34 tight glyph =
84+9:35 tight lit 30
85+9:38 name n
86+9:39 tight glyph =
87+9:40 tight lit 1
88+9:41 tight glyph ]
89+10:1 NEWLINE
90+10:1 glyph ++
91+10:4 name change
92+10:11 glyph |=
93+10:14 name m
94+10:15 tight glyph =
95+10:16 tight glyph [
96+10:17 tight name gap
97+10:20 tight glyph =
98+10:21 tight aura @dr
99+10:25 name n
100+10:26 tight glyph =
101+10:27 tight aura @ud
102+10:30 tight glyph ]
103+10:32 name m
104+10:33 tight glyph (
105+10:34 tight name gap
106+10:37 tight glyph =
107+10:38 tight lit 30
108+10:40 tight glyph )
109+11:1 NEWLINE
110+11:1 glyph ++
111+11:4 name items
112+11:10 glyph ^-
113+11:13 glyph (
114+11:14 tight name list
115+11:19 aura @dr
116+11:22 tight glyph )
117+11:24 glyph ~[
118+11:26 tight lit ~s1
119+11:30 lit 2
120+11:31 tight glyph ]
121+12:1 NEWLINE
122+12:1 glyph ++
123+12:4 name open
124+12:9 glyph ~[
125+12:11 tight lit ~s1
126+12:15 lit 2
127+12:16 tight glyph ]
128+13:1 NEWLINE
129+13:1 glyph ++
130+13:4 name open-first
131+13:15 glyph ~[
132+13:17 tight lit 2
133+13:19 lit ~s1
134+13:22 tight glyph ]
135+14:1 NEWLINE
136+14:1 glyph ++
137+14:4 name payload
138+14:12 glyph ^-
139+14:15 glyph (
140+14:16 tight name unit
141+14:21 aura @dr
142+14:24 tight glyph )
143+14:26 glyph `
144+14:27 tight lit 30
145+15:1 NEWLINE
146+15:1 glyph ++
147+15:4 name either
148+15:11 glyph |=
149+15:14 name b
150+15:15 tight glyph =
151+15:16 tight glyph ?
152+15:18 glyph ?-
153+15:21 name b
154+16:3 INDENT
155+16:3 lit %.y
156+16:7 lit ~s1
157+17:3 NEWLINE
158+17:3 lit %.n
159+17:7 lit 2
160+18:1 DEDENT
161+18:1 NEWLINE
162+18:1 glyph ++
163+18:4 name every
164+18:10 glyph ^-
165+18:13 glyph (
166+18:14 tight name list
167+18:19 glyph (
168+18:20 tight name sub
169+18:24 name msg
170+18:27 tight glyph )
171+18:28 tight glyph )
172+18:30 glyph ~[
173+18:32 tight glyph [
174+18:33 tight lit %every
175+18:40 lit 1
176+18:42 glyph |=
177+18:44 tight lit %tick
178+18:49 tight glyph ]
179+18:50 tight glyph ]
180+19:1 NEWLINE
181+19:1 glyph ++
182+19:4 name every-ok
183+19:13 glyph ^-
184+19:16 glyph (
185+19:17 tight name list
186+19:22 glyph (
187+19:23 tight name sub
188+19:27 name msg
189+19:30 tight glyph )
190+19:31 tight glyph )
191+19:33 glyph ~[
192+19:35 tight glyph [
193+19:36 tight lit %every
194+19:43 lit ~s1
195+19:47 glyph |=
196+19:49 tight lit %tick
197+19:54 tight glyph ]
198+19:55 tight glyph ]
199+20:1 NEWLINE
200+20:1 glyph ++
201+20:4 name timer
202+20:10 glyph ^-
203+20:13 glyph (
204+20:14 tight name cmd
205+20:18 name msg
206+20:21 tight glyph )
207+20:23 glyph [
208+20:24 tight lit %wait
209+20:30 lit 30
210+20:33 glyph [
211+20:34 tight lit %done
212+20:40 lit 1
213+20:41 tight glyph ]
214+20:42 tight glyph ]
215+21:1 NEWLINE
216+21:1 glyph ++
217+21:4 name timer-pair
218+21:15 glyph ^-
219+21:18 glyph (
220+21:19 tight name cmd
221+21:23 name msg
222+21:26 tight glyph )
223+21:28 name wait
224+21:32 tight glyph +
225+21:33 tight glyph [
226+21:34 tight lit 30
227+21:37 glyph [
228+21:38 tight lit %done
229+21:44 lit 1
230+21:45 tight glyph ]
231+21:46 tight glyph ]
232+22:1 NEWLINE
233+22:1 glyph ++
234+22:4 name note
235+22:9 glyph (
236+22:10 tight name text
237+22:15 lit 5
238+22:16 tight glyph )
239+23:1 NEWLINE
240+23:1 glyph ++
241+23:4 name note-ok
242+23:12 glyph (
243+23:13 tight name text
244+23:18 str "5"
245+23:21 tight glyph )
246+24:1 NEWLINE
247+24:1 glyph ++
248+24:4 name shown
249+24:10 glyph ^-
250+24:13 glyph (
251+24:14 tight name element
252+24:22 glyph !!
253+24:24 tight glyph )
254+24:26 glyph (
255+24:27 tight name text
256+24:32 lit 5
257+24:33 tight glyph )
258+24:34 NEWLINE
tests/golden/inline-decimal-sites/tree.txtnew file+103
@@ -0,0 +1,103 @@
1+(module
2+ (mold 1:1 msg
3+ (union 2:3
4+ (cell 2:3
5+ (const 2:4 %tick)
6+ (face 2:10 at (aura 2:13 @da)))
7+ (cell 3:3
8+ (const 3:4 %done)
9+ (face 3:10 n (aura 3:12 @ud)))))
10+ (value 4:1 pause
11+ (gate 4:10
12+ (face 4:13 d (aura 4:15 @dr))
13+ (wing 4:19 d)))
14+ (value 5:1 arg
15+ (group 5:8
16+ (call 5:9 (wing 5:9 pause) (lit 5:15 30))))
17+ (value 6:1 later
18+ (gate 6:10
19+ (face 6:13 d (aura 6:15 @dr))
20+ (group 6:19
21+ (call 6:20 (wing 6:20 add) (wing 6:24 d) (lit 6:26 1)))))
22+ (value 7:1 sooner
23+ (gate 7:11
24+ (face 7:14 d (aura 7:16 @dr))
25+ (group 7:20
26+ (call 7:21 (wing 7:21 add) (lit 7:25 1) (wing 7:27 d)))))
27+ (value 8:1 zero
28+ (gate 8:9
29+ (face 8:12 d (aura 8:14 @dr))
30+ (group 8:18
31+ (call 8:19 (wing 8:19 eq) (wing 8:22 d) (lit 8:24 0)))))
32+ (value 9:1 record
33+ (cast 9:11
34+ (cell 9:14
35+ (face 9:15 gap (aura 9:19 @dr))
36+ (face 9:23 n (aura 9:25 @ud)))
37+ (tuple 9:30
38+ (face 9:31 gap (lit 9:35 30))
39+ (face 9:38 n (lit 9:40 1)))))
40+ (value 10:1 change
41+ (gate 10:11
42+ (face 10:14 m
43+ (cell 10:16
44+ (face 10:17 gap (aura 10:21 @dr))
45+ (face 10:25 n (aura 10:27 @ud))))
46+ (change 10:32 m
47+ (edit 10:34 gap (lit 10:38 30)))))
48+ (value 11:1 items
49+ (cast 11:10
50+ (apply 11:13 list (aura 11:19 @dr))
51+ (list 11:24 (lit 11:26 ~s1) (lit 11:30 2))))
52+ (value 12:1 open
53+ (list 12:9 (lit 12:11 ~s1) (lit 12:15 2)))
54+ (value 13:1 open-first
55+ (list 13:15 (lit 13:17 2) (lit 13:19 ~s1)))
56+ (value 14:1 payload
57+ (cast 14:12
58+ (apply 14:15 unit (aura 14:21 @dr))
59+ (unit 14:26 (lit 14:27 30))))
60+ (value 15:1 either
61+ (gate 15:11
62+ (face 15:14 b (flag 15:16))
63+ (branch 15:18
64+ (wing 15:21 b)
65+ (arm 16:3 (lit 16:3 %.y) (lit 16:7 ~s1))
66+ (arm 17:3 (lit 17:3 %.n) (lit 17:7 2)))))
67+ (value 18:1 every
68+ (cast 18:10
69+ (apply 18:13 list
70+ (apply 18:19 sub (ref 18:24 msg)))
71+ (list 18:30
72+ (tuple 18:32 (lit 18:33 %every) (lit 18:40 1) (ctor 18:42 %tick)))))
73+ (value 19:1 every-ok
74+ (cast 19:13
75+ (apply 19:16 list
76+ (apply 19:22 sub (ref 19:27 msg)))
77+ (list 19:33
78+ (tuple 19:35 (lit 19:36 %every) (lit 19:43 ~s1) (ctor 19:47 %tick)))))
79+ (value 20:1 timer
80+ (cast 20:10
81+ (apply 20:13 cmd (ref 20:18 msg))
82+ (tuple 20:23
83+ (lit 20:24 %wait)
84+ (lit 20:30 30)
85+ (tuple 20:33 (lit 20:34 %done) (lit 20:40 1)))))
86+ (value 21:1 timer-pair
87+ (cast 21:15
88+ (apply 21:18 cmd (ref 21:23 msg))
89+ (pair 21:28 wait
90+ (tuple 21:33
91+ (lit 21:34 30)
92+ (tuple 21:37 (lit 21:38 %done) (lit 21:44 1))))))
93+ (value 22:1 note
94+ (group 22:9
95+ (call 22:10 (wing 22:10 text) (lit 22:15 5))))
96+ (value 23:1 note-ok
97+ (group 23:12
98+ (call 23:13 (wing 23:13 text) (str 23:18 "5"))))
99+ (value 24:1 shown
100+ (cast 24:10
101+ (apply 24:13 element (void 24:22))
102+ (group 24:26
103+ (call 24:27 (wing 24:27 text) (lit 24:32 5))))))
tests/golden/inline-decimal-sites/types.txtnew file+69
@@ -0,0 +1,69 @@
1+partial inference; module not checked
2++$ msg: cases proven disjoint; mold not checked
3+++ pause: $-(@dr @dr)
4+++ arg: `30` is a @ud, not a @dr; write ~s30
5+/tests/golden/inline-decimal-sites/source.jibb:5:15: decimal
6+++ arg (pause 30)
7+ ^
8+++ later: `1` is a @ud, not a @dr; write ~s1
9+/tests/golden/inline-decimal-sites/source.jibb:6:26: decimal
10+++ later |= d=@dr (add d 1)
11+ ^
12+++ sooner: `1` is a @ud, not a @dr; write ~s1
13+/tests/golden/inline-decimal-sites/source.jibb:7:25: decimal
14+++ sooner |= d=@dr (add 1 d)
15+ ^
16+++ zero: `0` is a @ud, not a @dr; write ~s0
17+/tests/golden/inline-decimal-sites/source.jibb:8:24: decimal
18+++ zero |= d=@dr (eq d 0)
19+ ^
20+++ record: `30` is a @ud, not a @dr; write ~s30
21+/tests/golden/inline-decimal-sites/source.jibb:9:35: decimal
22+++ record ^- [gap=@dr n=@ud] [gap=30 n=1]
23+ ^
24+++ change: `30` is a @ud, not a @dr; write ~s30
25+/tests/golden/inline-decimal-sites/source.jibb:10:38: decimal
26+++ change |= m=[gap=@dr n=@ud] m(gap=30)
27+ ^
28+++ items: `2` is a @ud, not a @dr; write ~s2
29+/tests/golden/inline-decimal-sites/source.jibb:11:30: decimal
30+++ items ^- (list @dr) ~[~s1 2]
31+ ^
32+++ open: `2` is a @ud, not a @dr; write ~s2
33+/tests/golden/inline-decimal-sites/source.jibb:12:15: decimal
34+++ open ~[~s1 2]
35+ ^
36+++ open-first: `2` is a @ud, not a @dr; write ~s2
37+/tests/golden/inline-decimal-sites/source.jibb:13:17: decimal
38+++ open-first ~[2 ~s1]
39+ ^
40+++ payload: `30` is a @ud, not a @dr; write ~s30
41+/tests/golden/inline-decimal-sites/source.jibb:14:27: decimal
42+++ payload ^- (unit @dr) `30
43+ ^
44+++ either: `2` is a @ud, not a @dr; write ~s2
45+/tests/golden/inline-decimal-sites/source.jibb:17:7: decimal
46+ %.n 2
47+ ^
48+++ every: `1` is a @ud, not a @dr; write ~s1
49+/tests/golden/inline-decimal-sites/source.jibb:18:40: decimal
50+++ every ^- (list (sub msg)) ~[[%every 1 |=%tick]]
51+ ^
52+++ every-ok: (list (sub msg))
53+++ timer: `30` is a @ud, not a @dr; write ~s30
54+/tests/golden/inline-decimal-sites/source.jibb:20:30: decimal
55+++ timer ^- (cmd msg) [%wait 30 [%done 1]]
56+ ^
57+++ timer-pair: `30` is a @ud, not a @dr; write ~s30
58+/tests/golden/inline-decimal-sites/source.jibb:21:34: decimal
59+++ timer-pair ^- (cmd msg) wait+[30 [%done 1]]
60+ ^
61+++ note: `5` is a @ud, not a @t; write "5"
62+/tests/golden/inline-decimal-sites/source.jibb:22:15: decimal
63+++ note (text 5)
64+ ^
65+++ note-ok: (element A)
66+++ shown: `5` is a @ud, not a @t; write "5"
67+/tests/golden/inline-decimal-sites/source.jibb:24:32: decimal
68+++ shown ^- (element !!) (text 5)
69+ ^
tests/golden/types-list-open-constraints/about.txt+1−1
@@ -1,4 +1,4 @@
11source: Grammar, Literals: a list literal has type `(list A)`; Tag resolution: tags and `~` take their type from context.
2−tests: Uncontextualized lists use a fresh, independently generalizable element type and a validated prelude list. Nested and homogeneous lists infer; uncertain widening and unresolved tags fail closed, and unrelated pending literals stay pending.
2+tests: Uncontextualized lists use a fresh, independently generalizable element type and a validated prelude list. Nested and homogeneous lists infer; a decimal beside a hexadecimal is an error, since a decimal is a `@ud`; uncertain widening and unresolved tags fail closed, and unrelated pending literals stay pending.
33expect: parses
44expect-types: a partial inference report
tests/golden/types-list-open-constraints/types.txt+4−1
@@ -10,7 +10,10 @@ partial inference; module not checked
1010++ generic |= [a=A b=B] ~[a b]
1111 ^
1212++ explicit: $-([a=A b=A] (list A))
13−++ num: (list @ux)
13+++ num: `1` is a @ud, not a @ux; write 0x1
14+/tests/golden/types-list-open-constraints/source.jibb:6:10: decimal
15+++ num ~[1 0x1f]
16+ ^
1417++ all-num: (list @ud)
1518++ ctor: list item needs context in partial inference
1619++ payload: list item constraint is not supported by partial inference
tests/golden/types-local-error-order/about.txt+1−1
@@ -1,4 +1,4 @@
11source: Implementation plan, Risks: "Each error names both conflicting sites, with excerpts"; Grammar, Runes: "local names at the start of any body (a gate's, an arm's, a `^-`'s, a `~&`'s or a `++`'s), visible to each other and the final expression".
2−tests: a cast mismatch inside a local `++` is not reported as an error while a sibling that might fix the untyped sample's type waits without sites, since another order, or support for that sibling, could let the body pass. `flat-mask`, `outer-mask` and `rec-widen` now infer because their decimal and hexadecimal branch results unify at `@ux`. The remaining siblings wait on their own nested stall (`nest-order`) or, in a local recursive gate, on the gate itself (`rec-order`, `rec-mask`) and keep the generic message; the `-ok`, `-g-first` and `-top` controls show the orders and forms the checker accepts or already leaves generic.
2+tests: a cast mismatch inside a local `++` is not reported as an error while a sibling that might fix the untyped sample's type waits without sites, since another order, or support for that sibling, could let the body pass. `flat-mask`, `outer-mask` and `rec-widen` infer because their two hexadecimal branch results unify at `@ux`. The remaining siblings wait on their own nested stall (`nest-order`) or, in a local recursive gate, on the gate itself (`rec-order`, `rec-mask`) and keep the generic message; the `-ok`, `-g-first` and `-top` controls show the orders and forms the checker accepts or already leaves generic.
33expect: parses
44expect-types: a partial inference report, not a checked module
tests/golden/types-local-error-order/source.jibb+3−3
@@ -21,7 +21,7 @@
2121 ++ g [(^- !! x) c]
2222 ++ b [(^- @ux x) (^- @t x)]
2323 ++ c ?- %.y
24− %.y 1
24+ %.y 0x1
2525 %.n 0x2
2626 b
2727++ flat-mask-ok |= x
@@ -35,7 +35,7 @@
3535 ++ b [(^- @ux x) (^- @t x)]
3636 b
3737 ++ c ?- %.y
38− %.y 1
38+ %.y 0x1
3939 %.n 0x2
4040 a
4141++ nest-order |= x
@@ -74,7 +74,7 @@
7474 ++ g [(^- !! x) (f x)]
7575 ++ b [(^- @ux x) (^- @t x)]
7676 ++ h ?- %.y
77− %.y 1
77+ %.y 0x1
7878 %.n 0x2
7979 b
8080 z
tests/golden/types-local-error-order/tokens.txt+3−3
@@ -208,7 +208,7 @@
20820823:11 lit %.y
20920924:5 INDENT
21021024:5 lit %.y
211−24:9 lit 1
211+24:9 lit 0x1
21221225:5 NEWLINE
21321325:5 lit %.n
21421425:9 lit 0x2
@@ -300,7 +300,7 @@
30030037:11 lit %.y
30130138:5 INDENT
30230238:5 lit %.y
303−38:9 lit 1
303+38:9 lit 0x1
30430439:5 NEWLINE
30530539:5 lit %.n
30630639:9 lit 0x2
@@ -574,7 +574,7 @@
57457476:13 lit %.y
57557577:7 INDENT
57657677:7 lit %.y
577−77:11 lit 1
577+77:11 lit 0x1
57857878:7 NEWLINE
57957978:7 lit %.n
58058078:11 lit 0x2
tests/golden/types-local-error-order/tree.txt+3−3
@@ -96,7 +96,7 @@
9696 (value 23:3 c
9797 (branch 23:8
9898 (lit 23:11 %.y)
99− (arm 24:5 (lit 24:5 %.y) (lit 24:9 1))
99+ (arm 24:5 (lit 24:5 %.y) (lit 24:9 0x1))
100100 (arm 25:5 (lit 25:5 %.n) (lit 25:9 0x2))))
101101 (wing 26:3 b))))
102102 (value 27:1 flat-mask-ok
@@ -138,7 +138,7 @@
138138 (value 37:3 c
139139 (branch 37:8
140140 (lit 37:11 %.y)
141− (arm 38:5 (lit 38:5 %.y) (lit 38:9 1))
141+ (arm 38:5 (lit 38:5 %.y) (lit 38:9 0x1))
142142 (arm 39:5 (lit 39:5 %.n) (lit 39:9 0x2))))
143143 (wing 40:3 a))))
144144 (value 41:1 nest-order
@@ -263,7 +263,7 @@
263263 (value 76:5 h
264264 (branch 76:10
265265 (lit 76:13 %.y)
266− (arm 77:7 (lit 77:7 %.y) (lit 77:11 1))
266+ (arm 77:7 (lit 77:7 %.y) (lit 77:11 0x1))
267267 (arm 78:7 (lit 78:7 %.n) (lit 78:11 0x2))))
268268 (wing 79:5 b))))
269269 (wing 80:3 z)))))
tests/golden/types-partial-aura-generalization/source.jibb+1−1
@@ -1,2 +1,2 @@
11++ id |=(x x)
2−++ hex ^- @ux (id 1)
2+++ unsigned ^- @u (id 1)
tests/golden/types-partial-aura-generalization/tokens.txt+8−8
@@ -6,11 +6,11 @@
661:13 tight glyph )
772:1 NEWLINE
882:1 glyph ++
9−2:4 name hex
10−2:8 glyph ^-
11−2:11 aura @ux
12−2:15 glyph (
13−2:16 tight name id
14−2:19 lit 1
15−2:20 tight glyph )
16−2:21 NEWLINE
9+2:4 name unsigned
10+2:13 glyph ^-
11+2:16 aura @u
12+2:19 glyph (
13+2:20 tight name id
14+2:23 lit 1
15+2:24 tight glyph )
16+2:25 NEWLINE
tests/golden/types-partial-aura-generalization/tree.txt+5−5
@@ -1,8 +1,8 @@
11(module
22 (value 1:1 id
33 (gate-wide 1:7 (bind 1:10 x) (wing 1:12 x)))
4− (value 2:1 hex
5− (cast 2:8
6− (aura 2:11 @ux)
7− (group 2:15
8− (call 2:16 (wing 2:16 id) (lit 2:19 1))))))
4+ (value 2:1 unsigned
5+ (cast 2:13
6+ (aura 2:16 @u)
7+ (group 2:19
8+ (call 2:20 (wing 2:20 id) (lit 2:23 1))))))
tests/golden/types-partial-aura-generalization/types.txt+1−1
@@ -1,3 +1,3 @@
11partial inference; module not checked
22++ id: $-(A A)
3−++ hex: @ux
3+++ unsigned: @u
tests/golden/types-partial-aura/source.jibb+1−1
@@ -1,3 +1,3 @@
11++ n 1
2−++ good ^- @ux 1
2+++ good ^- @u 1
33++ bad ^- ? 1
tests/golden/types-partial-aura/tokens.txt+2−2
@@ -5,8 +5,8 @@
552:1 glyph ++
662:4 name good
772:9 glyph ^-
8−2:12 aura @ux
9−2:16 lit 1
8+2:12 aura @u
9+2:15 lit 1
10103:1 NEWLINE
11113:1 glyph ++
12123:4 name bad
tests/golden/types-partial-aura/tree.txt+1−1
@@ -1,6 +1,6 @@
11(module
22 (value 1:1 n (lit 1:6 1))
33 (value 2:1 good
4− (cast 2:9 (aura 2:12 @ux) (lit 2:16 1)))
4+ (cast 2:9 (aura 2:12 @u) (lit 2:15 1)))
55 (value 3:1 bad
66 (cast 3:8 (flag 3:11) (lit 3:13 1))))
tests/golden/types-partial-aura/types.txt+1−1
@@ -1,6 +1,6 @@
11partial inference; module not checked
22++ n: @ud
3−++ good: @ux
3+++ good: @u
44++ bad: cast mold and expression type do not unify
55/tests/golden/types-partial-aura/source.jibb:3:11: cast mold has type ?
66++ bad ^- ? 1
tests/golden/types-prelude-like/source.jibb+1−1
@@ -1,5 +1,5 @@
11++ absent ^- (like @ud) [p=[p=1 q=2] q=~]
2−++ present ^- (like @ud) [p=[p=1 q=2] q=`[p=8 q=[p=[p=3 q=4] q=~[97 98]]]]
2+++ present ^- (like @ud) [p=[p=1 q=2] q=`[p=8 q=[p=[p=3 q=4] q=(trip "ab")]]]
33++ render (like |=(n=@ud "found") present)
44++ absent-render (like |=(n=@ud "found") absent)
55++ to-ship (like |=(n=@ud ~zod) present)
tests/golden/types-prelude-like/tokens.txt+7−7
@@ -61,13 +61,13 @@
61612:60 tight glyph ]
62622:62 name q
63632:63 tight glyph =
64−2:64 tight glyph ~[
65−2:66 tight lit 97
66−2:69 lit 98
67−2:71 tight glyph ]
68−2:72 tight glyph ]
69−2:73 tight glyph ]
70−2:74 tight glyph ]
64+2:64 tight glyph (
65+2:65 tight name trip
66+2:70 str "ab"
67+2:74 tight glyph )
68+2:75 tight glyph ]
69+2:76 tight glyph ]
70+2:77 tight glyph ]
71713:1 NEWLINE
72723:1 glyph ++
73733:4 name render
tests/golden/types-prelude-like/tree.txt+2−1
@@ -27,7 +27,8 @@
2727 (face 2:53 p (lit 2:55 3))
2828 (face 2:57 q (lit 2:59 4))))
2929 (face 2:62 q
30− (list 2:64 (lit 2:66 97) (lit 2:69 98)))))))))))
30+ (group 2:64
31+ (call 2:65 (wing 2:65 trip) (str 2:70 "ab"))))))))))))
3132 (value 3:1 render
3233 (group 3:11
3334 (call 3:12
tests/lib/jibb-arithmetic-guards.hoon+4−3
@@ -11,7 +11,7 @@
1111 =/ right=itype:jibb (itype-walk:jibb [%nvar 1] u.one)
1212 =/ rleft=itype:jibb (itype-walk:jibb [%rvar 0] u.two)
1313 =/ rright=itype:jibb (itype-walk:jibb [%nvar 1] u.two)
14− =/ bound=(unit isub:jibb) (itype-unify:jibb left [%atom %ux] u.one)
14+ =/ bound=(unit isub:jibb) (itype-unify:jibb left [%atom %u] u.one)
1515 =/ extra=(unit isub:jibb) (itype-unify:jibb right [%nvar 2] u.one)
1616 ?~ bound ~["combined variable did not bind to a concrete aura"]
1717 ?~ extra ~["second numeric variable did not merge"]
@@ -23,8 +23,9 @@
2323 =(left (itype-walk:jibb left u.one))
2424 ?=(~ (itype-unify:jibb left [%flag ~] u.one))
2525 ?=(~ (itype-unify:jibb left [%any-atom ~] u.one))
26− =([%atom %ux] (itype-walk:jibb [%rvar 0] u.bound))
27− =([%atom %ux] (itype-walk:jibb [%nvar 1] u.bound))
26+ ?=(~ (itype-unify:jibb left [%atom %ux] u.one))
27+ =([%atom %u] (itype-walk:jibb [%rvar 0] u.bound))
28+ =([%atom %u] (itype-walk:jibb [%nvar 1] u.bound))
2829 =(left (itype-walk:jibb [%nvar 2] u.extra))
2930 ==
3031 ?: (levy checks |=(ok=? ok)) arithmetic-face-guard-errors