A union is a type name, and (vec-new) did not think so

The prelude's own (vec-new Form) was refused with "nothing here says what
(vec-new) is a Vec of" -- a message about a missing annotation, to a program
that had written one. The build went red the moment the Form declaration was
checked against anything, which is why the front half landed unmeasured.

The test a leading bare symbol has to pass was spelled out twice, once in
vec_new_elem and once in map_new_types, and both lists were written before
unions existed: primitives, structs, enums, aliases. resolve_name has known
about unions since they landed, so the two halves disagreed about what a type
name is. Now there is one list, read by both, so the next kind of type cannot
be added to one of them.

The case is in unions.flan rather than in a file of its own, because what it
asserts is that a union is an element type like any other -- (vec-new Shape),
(map-new string Shape) -- and that is a sentence about unions.

Also drops forms.so, a build artefact the last lane committed.
This commit is contained in:
Joseph Ferano 2026-09-12 20:27:19 +07:00
parent 9e0ae3a4ce
commit 1ee54d6b56
5 changed files with 34 additions and 9 deletions

1
.gitignore vendored
View File

@ -68,3 +68,4 @@ test/web-files-out.txt
# Python bytecode from the tools directory
__pycache__/
*.pyc
/forms.so

BIN
forms.so

Binary file not shown.

View File

@ -2073,6 +2073,21 @@ and file_guard ctx loc ~path_slot ~op mk_steps =
(Tast.Let ([ (ok, mk loc Types.Bool (Tast.Bool false)) ],
[ mk loc Types.Unit (Tast.While (notok (), [ body ])) ]))
(* Is this bare symbol the name of a type? Every table [resolve_name] will look
in, and the union table is one of them: a union is [Named] exactly as a
struct is, so (vec-new Form) is as ordinary as (vec-new Cell). It was left
out when unions landed, which made the prelude's own (vec-new Form) fail
with "nothing here says what (vec-new) is a Vec of" a message about a
missing annotation for a program that had written one. One list, read by
both callers, so the next kind of type added cannot be added to one of
them. *)
and type_named ctx n =
List.mem n Types.primitive_names
|| Hashtbl.mem ctx.env.structs n
|| Hashtbl.mem ctx.env.unions n
|| Hashtbl.mem ctx.env.enums n
|| Hashtbl.mem ctx.env.aliases n
(* The element type for [vec-new]: a leading bare symbol naming a type, or the
expectation at the site. A bare symbol shadowed by a local or a global is
that binding an allocator, in practice and not a type. *)
@ -2082,10 +2097,7 @@ and vec_new_elem ctx ~want loc args =
| { Ast.e = Ast.Var n; _ } :: rest
when lookup ctx n = None
&& (not (Hashtbl.mem ctx.env.globals n))
&& (List.mem n Types.primitive_names
|| Hashtbl.mem ctx.env.structs n
|| Hashtbl.mem ctx.env.enums n
|| Hashtbl.mem ctx.env.aliases n) ->
&& type_named ctx n ->
Some (resolve_name ctx.env ~seen:[] loc n, rest)
| _ -> None
in
@ -2114,10 +2126,7 @@ and map_new_types ctx ~want loc args =
let is_type n =
lookup ctx n = None
&& (not (Hashtbl.mem ctx.env.globals n))
&& (List.mem n Types.primitive_names
|| Hashtbl.mem ctx.env.structs n
|| Hashtbl.mem ctx.env.enums n
|| Hashtbl.mem ctx.env.aliases n)
&& type_named ctx n
in
match args with
| { Ast.e = Ast.Var k; _ } :: { Ast.e = Ast.Var v; _ } :: rest

View File

@ -93,4 +93,18 @@
(print (Shape.Dot {.x 1.5 .y -2.5})) (println "")
(print (Shape.Tag {.name "printed" .n 9})) (println "")
(print (Cell {.id 7 .s (Shape.Rect {.w 1 .h 2})})) (println "")
;; A union names an element type the same way a struct does. It reads as
;; trivia and it was not: the type-name test (vec-new) and (map-new) use to
;; read a leading bare symbol listed structs, enums, aliases and primitives
;; and not unions, so (vec-new Shape) was refused for not saying what it
;; held -- by a program that had said.
(let [vs (vec-new Shape)
ms (map-new string Shape)]
(push vs (Shape.Rect {.w 2 .h 3}))
(push vs Shape.Empty)
(put ms "only" (Shape.Tag {.name "in a map" .n 1}))
(print (i64 (area (at vs 0)))) (println "")
(println (describe (at vs 1)))
(println (match (get ms "only") (Some s) (describe s) None "missing")))
0)

View File

@ -1696,7 +1696,8 @@ ERR@7 unexpected token: not the kind the caller was reading
32\n0\n-1\nin a cell\nempty\n30\nreassigned\n15\n\
Shape.Empty\n(Shape.Dot {.x 1.5 .y -2.5})\n\
(Shape.Tag {.name \"printed\" .n 9})\n\
(Cell {.id 7 .s (Shape.Rect {.w 1 .h 2})})\n"
(Cell {.id 7 .s (Shape.Rect {.w 1 .h 2})})\n\
6\nempty\nin a map\n"
in
outputs "unions" "programs/unions.flan" unions_out;
outputs ~opt:"-O0" "unions, -O0" "programs/unions.flan" unions_out;