Skip to content

Commit e155410

Browse files
goldfirereTheNumbat
authored andcommitted
Small simplification to the new add_gadt_equation (#2623)
* Small simplification to the new add_gadt_equation * Add backtracking * Add tests for mcomp * Check kinds in mcomp * Chris's suggestions
1 parent 308d542 commit e155410

File tree

4 files changed

+310
-71
lines changed

4 files changed

+310
-71
lines changed

ocaml/testsuite/tests/typing-layouts/basics.ml

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2554,3 +2554,230 @@ module N :
25542554
val f : (M.t, M.t s) eq -> int
25552555
end
25562556
|}]
2557+
2558+
module N2 = struct
2559+
type ('a, 'b) eq =
2560+
| Refl : ('a, 'a) eq
2561+
2562+
let f (x : (M.t, ('a : immediate) s) eq) : int =
2563+
match x with
2564+
| Refl -> 42
2565+
end
2566+
2567+
[%%expect{|
2568+
module N2 :
2569+
sig
2570+
type ('a, 'b) eq = Refl : ('a, 'a) eq
2571+
val f : (M.t, M.t s) eq -> int
2572+
end
2573+
|}]
2574+
2575+
type ('a : immediate) s_imm = 'a
2576+
2577+
module N3 = struct
2578+
type ('a, 'b) eq =
2579+
| Refl : ('a, 'a) eq
2580+
2581+
let f (x : (M.t, 'a s_imm) eq) : int =
2582+
match x with
2583+
| Refl -> 42
2584+
end
2585+
2586+
[%%expect{|
2587+
type ('a : immediate) s_imm = 'a
2588+
module N3 :
2589+
sig
2590+
type ('a, 'b) eq = Refl : ('a, 'a) eq
2591+
val f : (M.t, M.t s_imm) eq -> int
2592+
end
2593+
|}]
2594+
2595+
module M2 = struct
2596+
type t : value
2597+
end
2598+
2599+
module N4 = struct
2600+
type ('a, 'b) eq =
2601+
| Refl : ('a, 'a) eq
2602+
2603+
let f (x : (M2.t, 'a s_imm) eq) : int =
2604+
match x with
2605+
| Refl -> 42
2606+
end
2607+
2608+
(* CR layouts v2.9: This message is rubbish. *)
2609+
[%%expect{|
2610+
module M2 : sig type t : value end
2611+
Line 11, characters 6-10:
2612+
11 | | Refl -> 42
2613+
^^^^
2614+
Error: This pattern matches values of type (M2.t, M2.t) eq
2615+
but a pattern was expected which matches values of type
2616+
(M2.t, $'a s_imm) eq
2617+
Type M2.t is not compatible with type $'a s_imm = $'a
2618+
The type constructor $'a would escape its scope
2619+
|}]
2620+
2621+
module N5 = struct
2622+
type ('a : any, 'b : any) eq =
2623+
| Refl : ('a : any). ('a, 'a) eq
2624+
2625+
let f (x : (M2.t, ('a : bits64)) eq) : int =
2626+
match x with
2627+
| Refl -> 42
2628+
end
2629+
2630+
(* CR layouts v2.9: This message is rubbish. *)
2631+
[%%expect{|
2632+
Line 7, characters 6-10:
2633+
7 | | Refl -> 42
2634+
^^^^
2635+
Error: This pattern matches values of type (M2.t, M2.t) eq
2636+
but a pattern was expected which matches values of type (M2.t, $'a) eq
2637+
The type constructor $'a would escape its scope
2638+
|}]
2639+
2640+
module M2 = struct
2641+
type 'a t : immediate
2642+
end
2643+
2644+
module N6 = struct
2645+
type ('a,'b) eq =
2646+
| Refl : ('a, 'a) eq
2647+
2648+
let f (x : (_ M2.t, 'a s) eq) : int =
2649+
match x with
2650+
| Refl -> 42
2651+
end
2652+
2653+
[%%expect{|
2654+
module M2 : sig type 'a t : immediate end
2655+
module N6 :
2656+
sig
2657+
type ('a, 'b) eq = Refl : ('a, 'a) eq
2658+
val f : ('a M2.t, 'a M2.t s) eq -> int
2659+
end
2660+
|}]
2661+
2662+
type ('a : any) is_value =
2663+
| V : ('a : value) is_value
2664+
2665+
module A : sig
2666+
type 'a t : any
2667+
2668+
val is_value : 'a t is_value
2669+
end = struct
2670+
type 'a t = int
2671+
2672+
let is_value = V
2673+
end
2674+
2675+
let magic (type a) (x : a A.t is_value) : 'b =
2676+
match x with
2677+
| _ -> .
2678+
2679+
let not_so_good : 'b = magic A.is_value
2680+
2681+
[%%expect{|
2682+
type ('a : any) is_value = V : 'a is_value
2683+
module A : sig type 'a t : any val is_value : 'a t is_value end
2684+
Line 16, characters 4-5:
2685+
16 | | _ -> .
2686+
^
2687+
Error: This match case could not be refuted.
2688+
Here is an example of a value that would reach it: V
2689+
|}]
2690+
2691+
type ('a : any) is_value =
2692+
| V : ('a : value) is_value
2693+
2694+
type t : float64
2695+
2696+
let refute (x : t is_value) =
2697+
match x with
2698+
| _ -> .
2699+
2700+
[%%expect{|
2701+
type ('a : any) is_value = V : 'a is_value
2702+
type t : float64
2703+
val refute : t is_value -> 'a = <fun>
2704+
|}]
2705+
2706+
type ('a : any) is_value =
2707+
| V : ('a : value) is_value
2708+
2709+
type 'a t : float64
2710+
2711+
let refute (x : 'a t is_value) =
2712+
match x with
2713+
| _ -> .
2714+
2715+
[%%expect{|
2716+
type ('a : any) is_value = V : 'a is_value
2717+
type 'a t : float64
2718+
val refute : 'a t is_value -> 'b = <fun>
2719+
|}]
2720+
2721+
(***********************************)
2722+
(* Test 44: Kind-checking in mcomp *)
2723+
2724+
type (!'a : any) inj
2725+
2726+
module type S = sig
2727+
type 'a value : value
2728+
type 'a bits64 : bits64
2729+
end
2730+
2731+
type ('a : any) s = 'a
2732+
2733+
(* These all have to use polymorphic variants to avoid getting handled
2734+
by special cases in unification: we're trying to trigger the call to
2735+
[mcomp_for] in [unify3_var]. *)
2736+
module F (X : S) = struct
2737+
let f1 : ([ `K of 'a X.bits64 inj ], [ `K of 'a X.value inj ]) eq -> _ =
2738+
function _ -> .
2739+
let f2 : ([ `K of 'a X.bits64 inj ], [ `K of (int -> int) inj ]) eq -> _ =
2740+
function _ -> .
2741+
let f3 : ([ `K of 'a X.bits64 inj ], [ `K of ('b : value) inj ]) eq -> _ =
2742+
function _ -> .
2743+
let f4 : ([ `K of ('b : value) inj ], [ `K of 'a X.bits64 inj ]) eq -> _ =
2744+
function _ -> .
2745+
let f5 : ([ `K of 'a X.bits64 s inj ], [ `K of ('b : value) s inj ]) eq -> _ =
2746+
function _ -> .
2747+
let f6 : ([ `K of ('b : value) s inj ], [ `K of 'a X.bits64 s inj ]) eq -> _ =
2748+
function _ -> .
2749+
end
2750+
2751+
[%%expect{|
2752+
type (!'a : any) inj
2753+
module type S = sig type 'a value : value type 'a bits64 : bits64 end
2754+
type ('a : any) s = 'a
2755+
module F :
2756+
functor (X : S) ->
2757+
sig
2758+
val f1 : ([ `K of 'a X.bits64 inj ], [ `K of 'a X.value inj ]) eq -> 'b
2759+
val f2 :
2760+
([ `K of 'a X.bits64 inj ], [ `K of (int -> int) inj ]) eq -> 'b
2761+
val f3 : ([ `K of 'a X.bits64 inj ], [ `K of 'b inj ]) eq -> 'c
2762+
val f4 : ([ `K of 'b inj ], [ `K of 'a X.bits64 inj ]) eq -> 'c
2763+
val f5 : ([ `K of 'a X.bits64 s inj ], [ `K of 'b s inj ]) eq -> 'c
2764+
val f6 : ([ `K of 'b s inj ], [ `K of 'a X.bits64 s inj ]) eq -> 'c
2765+
end
2766+
|}]
2767+
2768+
(* This naturally doesn't work if the type isn't injective *)
2769+
type ('a : any) not_inj
2770+
2771+
module F (X : S) = struct
2772+
let f1 : ([ `K of 'a X.bits64 not_inj ], [ `K of 'a X.value not_inj ]) eq -> _ =
2773+
function _ -> .
2774+
end
2775+
2776+
[%%expect{|
2777+
type ('a : any) not_inj
2778+
Line 5, characters 13-14:
2779+
5 | function _ -> .
2780+
^
2781+
Error: This match case could not be refuted.
2782+
Here is an example of a value that would reach it: Refl
2783+
|}]

0 commit comments

Comments
 (0)