-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Closed
Description
The following program is wrongly accepted by the typechecker, which can be turned into a segfault:
module F(X : sig type 'a t end) = struct
type (_, _) gadt = T : ('a X.t, 'a) gadt
(*
let __ (type a b) (Equal : (a X.t, b X.t) Type.eq) =
(Equal : (a, b) Type.eq)
*)
let equate_param2_based_on_param1 (type tt m1 m2)
(T : (tt, m1) gadt) (T : (tt, m2) gadt) : (m1, m2) Type.eq =
Equal
;;
end
module Z = F(struct type 'a t = unit end)
let () =
let t1 = (Z.T : (unit, int) Z.gadt) in
let t2 = (Z.T : (unit, string) Z.gadt) in
let eq : (int, string) Type.eq = Z.equate_param2_based_on_param1 t1 t2 in
let cast (type a b) (Equal : (a, b) Type.eq) (a : a) : b = a in
print_string (cast eq 1)
;;The problem is that the function equate_param2_based_on_param1 is considered well-typed by the typechecker, but in reality it's well-typed iff X.t is injective in 'a. By contrast, the commented-out injectivity function is correctly accepted iff X.t is injective in 'a.
(this came up while @mbarbin and I were thinking about the type safety in https://github.com/mbarbin/provider/).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels