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:
parent
b814aca187
commit
8333ba017d
11
lib/check.ml
11
lib/check.ml
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user