diff --git a/lib/indent_reader.ml b/lib/indent_reader.ml index 0e35d43e..7c007aea 100644 --- a/lib/indent_reader.ml +++ b/lib/indent_reader.ml @@ -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 diff --git a/test/test_syntax.ml b/test/test_syntax.ml index 74d578b2..3427a6e1 100644 --- a/test/test_syntax.ml +++ b/test/test_syntax.ml @@ -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))"; diff --git a/web/examples/quotes.sh b/web/examples/quotes.sh index 630157fd..631bf749 100644 --- a/web/examples/quotes.sh +++ b/web/examples/quotes.sh @@ -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"