A literal local read as a typed array's element takes that element's type, and the Option str refusal test names str.

This commit is contained in:
Joseph Ferano 2026-09-26 18:06:29 +07:00
parent b814aca187
commit 8333ba017d
4 changed files with 19 additions and 4 deletions

View File

@ -9863,8 +9863,17 @@ and check_the ctx ~want loc (t : Ast.texpr) (v : Ast.expr) =
| _ -> ty | _ -> ty
in in
let is_nil = match v.Ast.e with Ast.Var "nil" -> true | _ -> false in let is_nil = match v.Ast.e with Ast.Var "nil" -> true | _ -> false in
(* Quietly: what [v] is on its own terms is not a use of a literal local
inside it — [[x]] read with no want would pin x at its guess, and the
annotation's want below is the use that says what x is. *)
let own_ty () =
let was = !lit_quiet in
lit_quiet := true;
Fun.protect ~finally:(fun () -> lit_quiet := was) (fun () ->
probe ctx loc (fun () -> (check ctx v).Tast.ty))
in
if ty <> Types.Dyn && not is_nil if ty <> Types.Dyn && not is_nil
&& probe ctx loc (fun () -> (check ctx v).Tast.ty) = Some Types.Dyn && own_ty () = Some Types.Dyn
(* A keyword naming one of an enum's members is that member at the (* A keyword naming one of an enum's members is that member at the
enum's type, not a dyn: [let d: Dir = :north]. *) enum's type, not a dyn: [let d: Dir = :north]. *)
&& not (match ty, v.Ast.e with Types.Enum _, Ast.Kw _ -> true | _ -> false) && not (match ty, v.Ast.e with Types.Enum _, Ast.Kw _ -> true | _ -> false)

View File

@ -127,6 +127,12 @@ fn main()
let lv = 200 let lv = 200
let wv: u8 = lv let wv: u8 = lv
println(wu ?? 0, wv) println(wu ?? 0, wv)
;; and from a typed array's element, with or without an Option
let la2 = 3
let xa: [1 i64] = [la2]
let lb2 = 3
let xb: [2 i64?] = [lb2, None]
println(la2 * 1000000000, lb2 * 1000000000, xa[0], xb[0] ?? 0)
;; None first in an if, as in a match ;; None first in an if, as in a match
let e1 = if x > 1 then None else 5 let e1 = if x > 1 then None else 5
let e2 = if x > 1 then 5 else None let e2 = if x > 1 then 5 else None

View File

@ -2279,7 +2279,7 @@ let () =
("autowrap.fln", ("autowrap.fln",
"-1\n5 4 2\n7 8 -1\n3 4\n7\n1 0 4\n5\n2 6 0\n2 -1 -1 2\n4\n-1 3 0\n\ "-1\n5 4 2\n7 8 -1\n3 4\n7\n1 0 4\n5\n2 6 0\n2 -1 -1 2\n4\n-1 3 0\n\
some some some none\nsome some some none none\n1 6 -1 -1\n1\n9 8 3 5\n\ some some some none\nsome some some none none\n1 6 -1 -1\n1\n9 8 3 5\n\
4000000000 4000000000 4 4\n4 4000000000\n3.5 3.5 7 7\n200 200\n-1 5\n1 0\n10\n"); 4000000000 4000000000 4 4\n4 4000000000\n3.5 3.5 7 7\n200 200\n3000000000 3000000000 3 3\n-1 5\n1 0\n10\n");
(* x? tests and narrows, e? as g names what it found (decision 133). *) (* x? tests and narrows, e? as g names what it found (decision 133). *)
("presence.fln", "true false true\n6\n-1\n3\n101 209 0\n11\n42\n2\nabsent\n6\nfalse true\n3\n6\n15\n"); ("presence-dyn.fln", "true false\n103 209 0\nno pet\nann\n3 2\n") ]; ("presence.fln", "true false true\n6\n-1\n3\n101 209 0\n11\n42\n2\nabsent\n6\nfalse true\n3\n6\n15\n"); ("presence-dyn.fln", "true false\n103 209 0\nno pet\nann\n3 2\n") ];
(* The pipe (decision 137): chains, multi-line, qualified, dyn, and the (* The pipe (decision 137): chains, multi-line, qualified, dyn, and the

View File

@ -8413,8 +8413,8 @@ let () =
~needle:"expected (Option i32), found str" ~needle:"expected (Option i32), found str"
"(defn f [] (Option i32) \"no\")\n(defn main [] ())"; "(defn f [] (Option i32) \"no\")\n(defn main [] ())";
rejects_check "a literal that does not fit is refused at the Option" rejects_check "a literal that does not fit is refused at the Option"
~needle:"expected (Option string), found the integer literal 5" ~needle:"expected (Option str), found the integer literal 5"
"(defn f [] (Option string) 5)\n(defn main [] ())"; "(defn f [] (Option str) 5)\n(defn main [] ())";
rejects_check "a narrowing is not wrapped" ~needle:"expected (Option i32), found i64" rejects_check "a narrowing is not wrapped" ~needle:"expected (Option i32), found i64"
"(defn f [x i64] (Option i32) x)\n(defn main [] ())"; "(defn f [x i64] (Option i32) x)\n(defn main [] ())";
rejects_check "no wrap inside a container" ~needle:"expected (Vec (Option i32)), found (Vec i32)" rejects_check "no wrap inside a container" ~needle:"expected (Vec (Option i32)), found (Vec i32)"