A bare def is answered with the let to write, and a generic missing its arrow is refused at the end of its line.

This commit is contained in:
Joseph Ferano 2026-09-26 05:54:01 +07:00
parent 895828992e
commit 6f6e01db06
3 changed files with 26 additions and 11 deletions

View File

@ -1544,6 +1544,18 @@ and header (s : st) w : Form.t =
let head =
match w with "def" -> "def" | "once" -> "defonce" | _ -> "defconst"
in
if shown = "def" then
failk "def-is-let" l0
"a global is written with let, at the file's top level:\n\n let %s%s%s"
(text_of name)
(match tyf, v with
| Some t, _ -> ": " ^ text_of t
| None, None -> ": i32"
| None, Some _ -> "")
(match v, tyf with
| Some v, _ -> " = " ^ text_of v
| None, None -> " = 0"
| None, Some _ -> "");
let items =
match w, tyf, v with
| "const", None, Some v -> [ name; v ]
@ -1560,12 +1572,6 @@ and header (s : st) w : Form.t =
i32 = 0"
shown (text_of name) shown (text_of name)
in
if shown = "def" then
failk "def-is-let" l0
"a global is written with let, at the file's top level:\n\n let %s%s%s"
(text_of name)
(match tyf with Some t -> ": " ^ text_of t | None -> "")
(match v with Some v -> " = " ^ text_of v | None -> "");
named head items
| "struct" | "union" ->
let name = name_tok p ~what:"the type's name" in
@ -1677,7 +1683,10 @@ and header (s : st) w : Form.t =
match (peek p).tok with
| NAME "->" -> ignore (advance p); ty p
| _ ->
failk "generic-return" (where_ p)
(* At the end of the header's line, where the arrow goes. *)
let e = (last p).loc in
failk "generic-return"
{ e with Loc.line = e.Loc.eline; col = e.Loc.ecol }
"a %s states the type every method returns: %s %s(%s) -> dyn"
w w (text_of name) names
in

View File

@ -582,6 +582,13 @@ let () =
reads "a top-level let is a global" "let g = 1\nlet h: i32 = 2\nlet s: [4 u8]\nf(g)"
"(def g dyn 1)\n(def h i32 2)\n(def s [4 u8])\n(f g)";
refuses "def" "def g: i32 = 1" "indent/def-is-let" "let g: i32 = 1";
refuses "a bare def" "def g" "indent/def-is-let" "let g: i32 = 0";
(match read "generic f(a)\n\nfn g() = 1" with
| exception Loc.Error d when d.Loc.dloc.Loc.line = 1 && d.Loc.dloc.Loc.col = 13 -> ()
| exception Loc.Error d ->
fail "a generic with no arrow is refused at %d:%d, not at its line's end"
d.Loc.dloc.Loc.line d.Loc.dloc.Loc.col
| _ -> fail "a generic with no arrow was read");
reads "a let in a comment block stays local" "comment:\n let x = 1\n f(x)"
"(comment (let [x 1] (f x)))";
reads "and in a fn" "fn f() -> i32\n let x = 1\n x" "(defn f [] i32 (let [x 1] x))";

View File

@ -81,10 +81,9 @@ do
name=${pair%%:*}; src=${pair#*:}
printf '%s\n' "$src" > "$here/.q.flan"
out=$("$FLAN" check "$here/.q.flan" 2>&1)
# A probe that compiles is the failure this loop is most likely to meet, and
# it is the one that used to be unreadable: `flan check` answers a clean
# program with its whole symbol table, so the needle became eighty lines of
# prelude signatures and the diff said nothing. Say what actually happened.
# A probe that compiles is the failure this loop is most likely to meet:
# `flan check` prints nothing for it, so the needle would be empty and the
# diff would say nothing. Say what actually happened.
if "$FLAN" check "$here/.q.flan" >/dev/null 2>&1; then
echo "FAIL message: $name"
echo " this program compiles now — the page still says it is refused"