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:
parent
9e0ae3a4ce
commit
1ee54d6b56
1
.gitignore
vendored
1
.gitignore
vendored
@ -68,3 +68,4 @@ test/web-files-out.txt
|
||||
# Python bytecode from the tools directory
|
||||
__pycache__/
|
||||
*.pyc
|
||||
/forms.so
|
||||
|
||||
25
lib/check.ml
25
lib/check.ml
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user