@@ -7768,6 +7768,8 @@
7768 ?: &(?=(%collection -.expected) =(%list name.expected) (context-list-expression e))
7768 ?: &(?=(%collection -.expected) =(%list name.expected) (context-list-expression e))
7769 (infer-list-context e expected env state context)
7769 (infer-list-context e expected env state context)
7770 ?: ?=(%branch -.e)
7770 ?: ?=(%branch -.e)
7771+ =/ named=(unit idiag) (branch-tag-name e env state)
7772+ ?^ named [%| u.named]
7771 =/ empty-list=(unit iresult) (empty-list-null-branch e env state `[expected context])
7773 =/ empty-list=(unit iresult) (empty-list-null-branch e env state `[expected context])
7772 ?^ empty-list u.empty-list
7774 ?^ empty-list u.empty-list
7773 ?~ arms.e [%| ["branch is not supported by partial inference" ~]]
7775 ?~ arms.e [%| ["branch is not supported by partial inference" ~]]
@@ -8163,6 +8165,78 @@
8163 ?: ?=(%cell -.p) (union-pattern-bind-items items.p t env globals)
8165 ?: ?=(%cell -.p) (union-pattern-bind-items items.p t env globals)
8168+:: +branch-tag-name: a ?- pattern name that spells one of the subject's tags
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.
8179+ |= [e=expr env=ienv state=istate]
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
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)
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"]]
8196+:: +tag-name-pattern: the first name in p that t types by a tag
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]`.
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))) ~
8210+ =/ inner=(list itype) (weld args.t args)
8211+ =/ cases=(list itype) cases.t
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)
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)) ~
8223+:: +tag-name-items: +tag-name-pattern along a cell pattern's items
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.
8228+ |= [ps=(list pattern) t=itype args=(list itype)]
8229+ ^- (unit [at=span name=term])
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)
8236+ =/ head=(unit [at=span name=term]) (tag-name-pattern i.ps hed.t args)
8238+ $(ps t.ps, t tal.t)
8166:: Split loobean fields into finite refinements for partial patterns.
8240:: Split loobean fields into finite refinements for partial patterns.
8167:: Keep original cases for binder types and preserve whole-case matching
8241:: Keep original cases for binder types and preserve whole-case matching
8168:: before trying refinements. Cap products at 64; unknown, empty or opaque
8242:: before trying refinements. Cap products at 64; unknown, empty or opaque
@@ -8876,6 +8950,8 @@
8876 ?: ?=(%| -.result) result
8950 ?: ?=(%| -.result) result
8877 [%& typ.p.result state.p.result(globals globals.state, molds molds.state)]
8951 [%& typ.p.result state.p.result(globals globals.state, molds molds.state)]
8953+ =/ named=(unit idiag) (branch-tag-name e env state)
8954+ ?^ named [%| u.named]
8879 ?^ defer.state (dg-boolean-branch e env state)
8955 ?^ defer.state (dg-boolean-branch e env state)
8880 ?~ arms.e [%| ["branch is not supported by partial inference" ~]]
8956 ?~ arms.e [%| ["branch is not supported by partial inference" ~]]
8881 ?~ t.arms.e
8957 ?~ t.arms.e
@@ -9713,6 +9789,8 @@
9713 ?: ?=(%bad -.fit) [%| ["recursive mold cell does not fit its source shape" ~]]
9789 ?: ?=(%bad -.fit) [%| ["recursive mold cell does not fit its source shape" ~]]
9714 [%& target state.p.value(sub sub.fit, next next.fit)]
9790 [%& target state.p.value(sub sub.fit, next next.fit)]
9715 ?: ?=(%call -.e) (infer-contextual-call e target env state)
9791 ?: ?=(%call -.e) (infer-contextual-call e target env state)
9792+ =/ named=(unit idiag) (branch-tag-name e env state)
9793+ ?^ named [%| u.named]
9716 =/ empty-list=(unit iresult) (empty-list-null-branch e env state `[target context])
9794 =/ empty-list=(unit iresult) (empty-list-null-branch e env state `[target context])
9717 ?^ empty-list u.empty-list
9795 ?^ empty-list u.empty-list
9718 ?: (single-structured-pattern e)
9796 ?: (single-structured-pattern e)