From 69703dec91ed6603f220a4042a1cad0d854079f5 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Mon, 5 Oct 2026 22:34:39 +0200 Subject: [PATCH] Answer architecture round 2: linkTemplates' doc says which steps pass names as arguments, checkEveryNameRead, and an invariant guard on a binding with no read at link --- link.go | 4 ++-- name.go | 6 +++--- namefence.go | 4 ++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/link.go b/link.go index e524550..8b0f374 100644 --- a/link.go +++ b/link.go @@ -62,8 +62,8 @@ type linkedNames struct { } // linkTemplates links ts in steps, each over every template before the next starts, each -// returning what it builds and taking what an earlier step built as an argument: the references, -// the names' targets, the compiled formats, the keys and reads of each name, and the column each +// returning what it builds: the references and the compiled formats, kept on each template, the +// names' targets, keys and reads, passed to the steps after as arguments, and the column each // format reads. The bindings take their targets and keys once every check has passed. func linkTemplates(ts []linkSite, root map[string]node) error { for _, s := range ts { diff --git a/name.go b/name.go index 4c36a04..87c7071 100644 --- a/name.go +++ b/name.go @@ -96,11 +96,11 @@ func bindNames(root node) error { if err != nil { return err } - return checkRead(scopes, read) + return checkEveryNameRead(scopes, read) } -// checkRead refuses a binding of scopes that read does not hold. -func checkRead(scopes []*nameScope, read map[*nameBinding]bool) error { +// checkEveryNameRead refuses a binding of scopes that nothing reads. +func checkEveryNameRead(scopes []*nameScope, read map[*nameBinding]bool) error { for _, sc := range scopes { for _, b := range sc.order { if !read[b] { diff --git a/namefence.go b/namefence.go index b7a65f4..6363cc1 100644 --- a/namefence.go +++ b/namefence.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/larvit/fejkdata/internal/grammar" + "github.com/larvit/fejkdata/internal/invariant" ) // checkNameReads refuses each binding of t that checkUses refuses, a read of a name inside the @@ -67,6 +68,9 @@ func rendersInside(nodes []node, t *template) bool { // template reaches the binder through fields. Where the spelling would be a CLI argument or tag // of one reference alone, that entry point's own refusal then names the bare path. func (b *nameBinding) checkUses(uses []nameUse) error { + if len(uses) == 0 { + panic(invariant.Broken("name %q has no read at link, though its compile found one", b.name)) + } r := uses[0] if len(uses) > 1 || r.nested { return nil