@@ -7768,6 +7768,8 @@
77687768 ?: &(?=(%collection -.expected) =(%list name.expected) (context-list-expression e))
77697769 (infer-list-context e expected env state context)
77707770 ?: ?=(%branch -.e)
7771+ =/ named=(unit idiag) (branch-tag-name e env state)
7772+ ?^ named [%| u.named]
77717773 =/ empty-list=(unit iresult) (empty-list-null-branch e env state `[expected context])
77727774 ?^ empty-list u.empty-list
77737775 ?~ arms.e [%| ["branch is not supported by partial inference" ~]]
@@ -8163,6 +8165,78 @@
81638165 ?: ?=(%cell -.p) (union-pattern-bind-items items.p t env globals)
81648166 `env
81658167::
8168+:: +branch-tag-name: a ?- pattern name that spells one of the subject's tags
8169+::
8170+:: A name in a pattern binds, so `stop` written for `%stop` would
8171+:: catch every case left. Where the subject's type at a name's
8172+:: position is a union, or a one-case mold, with a case whose constant
8173+:: there is the term the name spells, the name is an error (Grammar,
8174+:: Patterns). Every path that checks a ?- asks this first, so they
8175+:: agree; it infers the subject apart and drops the state it leaves.
8176+:: A subject that fails, or whose type isn't known yet, is left to the
8177+:: path. Samples aren't patterns: every sample name binds.
8178+++ branch-tag-name
8179+ |= [e=expr env=ienv state=istate]
8180+ ^- (unit idiag)
8181+ ?. ?=(%branch -.e) ~
8182+ ?. (lien arms.e |=(a=arm (union-pattern-has-bind pat.a))) ~
8183+ =/ subject=iresult (infer-fragment subject.e env state)
8184+ ?: ?=(%| -.subject) ~
8185+ =/ typ=itype (itype-normalize typ.p.subject sub.state.p.subject)
8186+ =/ arms=(list arm) arms.e
8187+ |-
8188+ ?~ arms ~
8189+ =/ found=(unit [at=span name=term]) (tag-name-pattern pat.i.arms typ ~)
8190+ ?~ found $(arms t.arms)
8191+ =/ name=tape (trip name.u.found)
8192+ :- ~
8193+ :- "`{name}` binds a name, but the subject's type has `%{name}` here; write %{name}, or * for a catch-all"
8194+ ~[[(span-of subject.e) "subject"] [at.u.found "pattern name"]]
8195+::
8196+:: +tag-name-pattern: the first name in p that t types by a tag
8197+::
8198+:: The walk enters faces, cells and unions, and of a union only the
8199+:: cases a cell pattern can match, so `[t %draft]` reads t at @t. It
8200+:: stops at atoms, `*`, variables, collections and recursive molds,
8201+:: and at a generic union's argument positions, which a type variable
8202+:: types in its mold, as u in `[~ u=A]`.
8203+++ tag-name-pattern
8204+ |= [p=pattern t=itype args=(list itype)]
8205+ ^- (unit [at=span name=term])
8206+ ?. ?=(?(%bind %cell) -.p) ~
8207+ ?: ?=(%face -.t) $(t body.t)
8208+ ?: (lien args |=(a=itype =(a t))) ~
8209+ ?: ?=(%union -.t)
8210+ =/ inner=(list itype) (weld args.t args)
8211+ =/ cases=(list itype) cases.t
8212+ |-
8213+ ?~ cases ~
8214+ ?: &(?=(%cell -.p) =(%none (union-pattern p i.cases))) $(cases t.cases)
8215+ =/ found=(unit [at=span name=term]) (tag-name-pattern p i.cases inner)
8216+ ?^ found found
8217+ $(cases t.cases)
8218+ ?: ?=(%cell -.p) (tag-name-items items.p t args)
8219+ ?. ?=(%const -.t) ~
8220+ ?. &(=(%term form.literal.t) =(%tas aura.literal.t) =(name.p val.literal.t)) ~
8221+ `[at.p name.p]
8222+::
8223+:: +tag-name-items: +tag-name-pattern along a cell pattern's items
8224+::
8225+:: As in +union-pattern-items, the last item takes the rest of the
8226+:: spine. A union mid-spine is read as the rest of the pattern.
8227+++ tag-name-items
8228+ |= [ps=(list pattern) t=itype args=(list itype)]
8229+ ^- (unit [at=span name=term])
8230+ ?~ ps ~
8231+ ?~ t.ps (tag-name-pattern i.ps t args)
8232+ ?: ?=(%face -.t) $(t body.t)
8233+ ?: (lien args |=(a=itype =(a t))) ~
8234+ ?: ?=(%union -.t) (tag-name-pattern [%cell at.i.ps ps] t args)
8235+ ?. ?=(%cell -.t) ~
8236+ =/ head=(unit [at=span name=term]) (tag-name-pattern i.ps hed.t args)
8237+ ?^ head head
8238+ $(ps t.ps, t tal.t)
8239+::
81668240:: Split loobean fields into finite refinements for partial patterns.
81678241:: Keep original cases for binder types and preserve whole-case matching
81688242:: before trying refinements. Cap products at 64; unknown, empty or opaque
@@ -8876,6 +8950,8 @@
88768950 ?: ?=(%| -.result) result
88778951 [%& typ.p.result state.p.result(globals globals.state, molds molds.state)]
88788952 %branch
8953+ =/ named=(unit idiag) (branch-tag-name e env state)
8954+ ?^ named [%| u.named]
88798955 ?^ defer.state (dg-boolean-branch e env state)
88808956 ?~ arms.e [%| ["branch is not supported by partial inference" ~]]
88818957 ?~ t.arms.e
@@ -9713,6 +9789,8 @@
97139789 ?: ?=(%bad -.fit) [%| ["recursive mold cell does not fit its source shape" ~]]
97149790 [%& target state.p.value(sub sub.fit, next next.fit)]
97159791 ?: ?=(%call -.e) (infer-contextual-call e target env state)
9792+ =/ named=(unit idiag) (branch-tag-name e env state)
9793+ ?^ named [%| u.named]
97169794 =/ empty-list=(unit iresult) (empty-list-null-branch e env state `[target context])
97179795 ?^ empty-list u.empty-list
97189796 ?: (single-structured-pattern e)