(* TEST expect; *) (* PR#5835 *) let f ~x = x + 1;; f ?x:0;; [%%expect{| val f : x:int -> int = Line 2, characters 5-6: 2 | f ?x:0;; ^ Warning 43 [nonoptional-label]: the label "x" is not optional. - : int = 1 |}];; (* PR#6352 *) let foo (f : unit -> unit) = ();; let g ?x () = ();; foo ((); g);; [%%expect{| val foo : (unit -> unit) -> unit = val g : ?x:'a -> unit -> unit = - : unit = () |}];; (* PR#5748 *) foo (fun ?opt () -> ()) ;; (* fails *) [%%expect{| Line 1, characters 4-23: 1 | foo (fun ?opt () -> ()) ;; (* fails *) ^^^^^^^^^^^^^^^^^^^ Error: This function should have type "unit -> unit" but its first argument is labeled "?opt" instead of being unlabeled |}];; (* filter_arrow *) let (f : x:int -> int) = fun y -> y [%%expect{| Line 1, characters 25-35: 1 | let (f : x:int -> int) = fun y -> y ^^^^^^^^^^ Error: This function should have type "x:int -> int" but its first argument is unlabeled instead of being labeled "~x" |}];; let (f : int -> int) = fun ~y -> y [%%expect{| Line 1, characters 23-34: 1 | let (f : int -> int) = fun ~y -> y ^^^^^^^^^^^ Error: This function should have type "int -> int" but its first argument is labeled "~y" instead of being unlabeled |}];; let (f : x:int -> int) = fun ~y -> y [%%expect{| Line 1, characters 25-36: 1 | let (f : x:int -> int) = fun ~y -> y ^^^^^^^^^^^ Error: This function should have type "x:int -> int" but its first argument is labeled "~y" instead of "~x" |}];; (* More examples *) let f g = ignore (g ?x:(Some 2) ()); g ~x:3 () ;; [%%expect{| Line 1, characters 37-38: 1 | let f g = ignore (g ?x:(Some 2) ()); g ~x:3 () ;; ^ Error: This function is applied to arguments in an order different from other calls. This is only allowed when the real type is known. |}];; let f g = let _ = g ?x:(Some 2) () in g ~x:3 () ;; [%%expect{| Line 1, characters 38-39: 1 | let f g = let _ = g ?x:(Some 2) () in g ~x:3 () ;; ^ Error: This function is applied to arguments in an order different from other calls. This is only allowed when the real type is known. |}];; (* principality warning *) let f g = ignore (g : ?x:int -> unit -> int); g ~x:3 () ;; [%%expect{| val f : (?x:int -> unit -> int) -> int = |}, Principal{| Line 1, characters 51-52: 1 | let f g = ignore (g : ?x:int -> unit -> int); g ~x:3 () ;; ^ Warning 18 [not-principal]: using an optional argument here is not principal. val f : (?x:int -> unit -> int) -> int = |}];; let f g = ignore (g : ?x:int -> unit -> int); g ();; [%%expect{| val f : (?x:int -> unit -> int) -> int = |}, Principal{| Line 1, characters 46-47: 1 | let f g = ignore (g : ?x:int -> unit -> int); g ();; ^ Warning 19 [non-principal-labels]: eliminated optional argument without principality. val f : (?x:int -> unit -> int) -> int = |}];; let f g = ignore (g : x:int -> unit -> int); g ();; [%%expect{| val f : (x:int -> unit -> int) -> x:int -> int = |}, Principal{| Line 1, characters 45-46: 1 | let f g = ignore (g : x:int -> unit -> int); g ();; ^ Warning 19 [non-principal-labels]: commuted an argument without principality. val f : (x:int -> unit -> int) -> x:int -> int = |}];; (* 9859: inferred function types may appear in the right hand side of :> *) class setup = object method with_ f = (f 0:unit) end class virtual fail = object (self) method trigger = (self :> setup ) end [%%expect {| class setup : object method with_ : (int -> unit) -> unit end class virtual fail : object method trigger : setup method virtual with_ : (int -> unit) -> unit end |}] module type T = sig type t end let type_of (type x) (x: x) = (module struct type t = x end: T with type t = x) let f g = 1 + g ~x:0 ~y:0;; module E = (val type_of f) let g = ( (fun _ -> f) :> 'a -> E.t) [%%expect {| module type T = sig type t end val type_of : 'x -> (module T with type t = 'x) = val f : (x:int -> y:int -> int) -> int = module E : sig type t = (x:int -> y:int -> int) -> int end val g : 'a -> E.t = |}] let labeled ~x = () let unlabeled x = () let wrong_label ~y = () let expect_unlabeled g = if true then g () let expect_labeled g x = if true then g ~x;; [%%expect {| val labeled : x:'a -> unit = val unlabeled : 'a -> unit = val wrong_label : y:'a -> unit = val expect_unlabeled : (unit -> unit) -> unit = val expect_labeled : (x:'a -> unit) -> 'a -> unit = |}] let () = expect_unlabeled labeled [%%expect {| Line 1, characters 26-33: 1 | let () = expect_unlabeled labeled ^^^^^^^ Error: The value "labeled" has type "x:'a -> unit" but an expression was expected of type "unit -> unit" The first argument is labeled "x", but an unlabeled argument was expected |}] let () = expect_labeled unlabeled [%%expect {| Line 1, characters 24-33: 1 | let () = expect_labeled unlabeled ^^^^^^^^^ Error: The value "unlabeled" has type "'a -> unit" but an expression was expected of type "x:'b -> unit" A label "x" was expected |}] let () = expect_labeled wrong_label [%%expect {| Line 1, characters 24-35: 1 | let () = expect_labeled wrong_label ^^^^^^^^^^^ Error: The value "wrong_label" has type "y:'a -> unit" but an expression was expected of type "x:'b -> unit" Labels "y" and "x" do not match |}]