···418418- #14331: Enforce current_level <= generic_level, and explain create_scope
419419 (Jacques Garrigue and Takafumi Saikawa, review by Gabriel Scherer)
420420421421+* #14388: Remove support for `let rec (module M : S) = e1 in e2`.
422422+ (Alistair O'Brien, review by Vincent Laviron and Gabriel Scherer)
423423+421424### Build system:
422425423426- #13810: Support build of cross compilers to native freestanding targets
···77 type t
88end;;
991010-let rec (module M : S) =
1010+let rec (m : (module S)) =
1111+ let (module M) = m in
1112 (module struct
1213 type t = M.t
1314 end : S
···1617();;
1718[%%expect{|
1819module type S = sig type t end
1919-Lines 6-9, characters 2-22:
2020-6 | ..(module struct
2121-7 | type t = M.t
2222-8 | end : S
2323-9 | with type t = M.t)
2020+Lines 7-10, characters 2-22:
2121+ 7 | ..(module struct
2222+ 8 | type t = M.t
2323+ 9 | end : S
2424+10 | with type t = M.t)
2525+Error: This expression has type "(module S with type t = M.t)"
2626+ but an expression was expected of type "(module S)"
2727+ The type constructor "M.t" would escape its scope
2828+|}, Principal{|
2929+module type S = sig type t end
3030+Lines 7-10, characters 2-22:
3131+ 7 | ..(module struct
3232+ 8 | type t = M.t
3333+ 9 | end : S
3434+10 | with type t = M.t)
2435Error: This expression has type "(module S with type t = M.t)"
2536 but an expression was expected of type "(module S)"
2637|}];;
27382839let rec k =
4040+ let (module A) = a in
2941 let (module K : S with type t = A.t) = k in
3042 (module struct
3143 type t = K.t
3244 end : S
3345 with type t = K.t)
3434-and (module A : S) =
4646+and (a : (module S)) =
3547 (module struct
3648 type t = unit
3749···4052in
4153();;
4254[%%expect{|
4343-Lines 2-6, characters 2-22:
4444-2 | ..let (module K : S with type t = A.t) = k in
4545-3 | (module struct
4646-4 | type t = K.t
4747-5 | end : S
4848-6 | with type t = K.t)
4949-Error: This expression has type "(module S with type t = A.t)"
5050- but an expression was expected of type "'a"
5555+Line 3, characters 41-42:
5656+3 | let (module K : S with type t = A.t) = k in
5757+ ^
5858+Error: The value "k" has type "'a" but an expression was expected of type
5959+ "(module S with type t = A.t)"
5160 The type constructor "A.t" would escape its scope
5261|}];;
53625463(* The locally abstract type lets us check the module's type
5564 without scope escape. *)
5665let f (type a) () =
5757- let rec (module M : S with type t = a) =
6666+ let rec (m : (module S with type t = a)) =
6767+ let (module M) = m in
5868 (module struct
5969 type t = M.t
6070 end : S with type t = M.t)
6171 in
7272+ ignore m;
6273 ()
6374;;
6475[%%expect{|
···6677|}];;
67786879let f (type a) () =
6969- let rec (module M : S with type t = a) =
8080+ let rec (m : (module S with type t = a)) =
8181+ let (module M) = m in
7082 (module struct
7183 type t = M.t
7284 end : S with type t = a)
7385 in
8686+ ignore m;
7487 ();;
7588[%%expect{|
7689val f : unit -> unit = <fun>
···303031313232let () =
3333- let rec Any x = Any () in
3434- ()
3535-[%%expect {|
3636-Line 2, characters 10-15:
3737-2 | let rec Any x = Any () in
3838- ^^^^^
3939-Error: Existential types are not allowed in recursive bindings,
4040- but the constructor "Any" introduces existential types.
4141-|}]
4242-4343-4444-let () =
4533 let[@attribute] Any x = Any () in
4634 ()
4735[%%expect {|
···10593Error: Existential types are not allowed in grouped ("let ... and ...") bindings,
10694 but the constructor "Any" introduces existential types.
10795|}]
108108-109109-110110-let () =
111111- let rec Any x = Any () in
112112- ()
113113-[%%expect {|
114114-Line 2, characters 10-15:
115115-2 | let rec Any x = Any () in
116116- ^^^^^
117117-Error: Existential types are not allowed in recursive bindings,
118118- but the constructor "Any" introduces existential types.
119119-|}]
120120-1219612297let () =
12398 let[@attribute] Any x = Any () in
···169169|}];;
170170171171(* Even works with recursion, but must be fully explicit *)
172172-let rec (module M : S') =
173173- (module struct let f n = if n <= 0 then 1 else n * M.f (n-1) end : S')
174174-in M.f 3;;
172172+let rec (m : (module S')) =
173173+ let (module M) = m in
174174+ (module struct
175175+ let f n = if n <= 0 then 1 else n * M.f (n - 1)
176176+ end : S')
177177+in
178178+let (module M) = m in
179179+M.f 3
175180[%%expect{|
176181- : int = 6
177177-|}];;
182182+|}]
178183179184(* Subtyping *)
180185
+150
testsuite/tests/typing-misc/let_rec_pat.ml
···11+(* TEST
22+ expect;
33+*)
44+55+(* This series of tests checks the pattern validation for [let rec] bindings.
66+ Only "variable-like" patterns are allowed. See [is_var_pat] for details. *)
77+88+(* Valid patterns *)
99+1010+let rec x = 1 in x
1111+[%%expect{|
1212+- : int = 1
1313+|}];;
1414+1515+let rec (x : int) = 1 in x
1616+[%%expect{|
1717+- : int = 1
1818+|}];;
1919+2020+let rec ((x : int) : int) = 1 in x
2121+[%%expect{|
2222+- : int = 1
2323+|}];;
2424+2525+module M = struct type t = int end;;
2626+let rec M.((x : t)) = 1 in x
2727+[%%expect{|
2828+module M : sig type t = int end
2929+- : M.t = 1
3030+|}];;
3131+3232+(* Invalid patterns *)
3333+3434+let rec _ = 1 in ()
3535+[%%expect{|
3636+Line 1, characters 8-9:
3737+1 | let rec _ = 1 in ()
3838+ ^
3939+Error: Only variables are allowed as left-hand side of "let rec"
4040+|}];;
4141+4242+let rec (x as y) = 1 in x
4343+[%%expect{|
4444+Line 1, characters 8-16:
4545+1 | let rec (x as y) = 1 in x
4646+ ^^^^^^^^
4747+Error: Only variables are allowed as left-hand side of "let rec"
4848+|}];;
4949+5050+let rec 42 = 42 in ()
5151+[%%expect{|
5252+Line 1, characters 8-10:
5353+1 | let rec 42 = 42 in ()
5454+ ^^
5555+Error: Only variables are allowed as left-hand side of "let rec"
5656+|}];;
5757+5858+let rec (x, y) = (1, 2) in x
5959+[%%expect{|
6060+Line 1, characters 8-14:
6161+1 | let rec (x, y) = (1, 2) in x
6262+ ^^^^^^
6363+Error: Only variables are allowed as left-hand side of "let rec"
6464+|}];;
6565+6666+let rec Some x = Some 1 in x
6767+[%%expect{|
6868+Line 1, characters 8-14:
6969+1 | let rec Some x = Some 1 in x
7070+ ^^^^^^
7171+Error: Only variables are allowed as left-hand side of "let rec"
7272+|}];;
7373+7474+type r = { a : int; b : int };;
7575+let rec { a; b } = { a = 1; b = 2 } in a
7676+[%%expect{|
7777+type r = { a : int; b : int; }
7878+Line 2, characters 8-16:
7979+2 | let rec { a; b } = { a = 1; b = 2 } in a
8080+ ^^^^^^^^
8181+Error: Only variables are allowed as left-hand side of "let rec"
8282+|}];;
8383+8484+let rec [| x |] = [| 1 |] in x
8585+[%%expect{|
8686+Line 1, characters 8-15:
8787+1 | let rec [| x |] = [| 1 |] in x
8888+ ^^^^^^^
8989+Error: Only variables are allowed as left-hand side of "let rec"
9090+|}];;
9191+9292+let rec (Some x | None as x) = None in ()
9393+[%%expect{|
9494+Line 1, characters 8-28:
9595+1 | let rec (Some x | None as x) = None in ()
9696+ ^^^^^^^^^^^^^^^^^^^^
9797+Error: Only variables are allowed as left-hand side of "let rec"
9898+|}];;
9999+100100+let rec lazy x = lazy 1 in x
101101+[%%expect{|
102102+Line 1, characters 8-14:
103103+1 | let rec lazy x = lazy 1 in x
104104+ ^^^^^^
105105+Error: Only variables are allowed as left-hand side of "let rec"
106106+|}];;
107107+108108+module type S = sig val f : int -> int end;;
109109+let rec (module M : S) = (module struct let f n = if n <= 0 then 1 else n * M.f (n - 1) end : S) in M.f 5
110110+[%%expect{|
111111+module type S = sig val f : int -> int end
112112+Line 2, characters 8-22:
113113+2 | let rec (module M : S) = (module struct let f n = if n <= 0 then 1 else n * M.f (n - 1) end : S) in M.f 5
114114+ ^^^^^^^^^^^^^^
115115+Error: Only variables are allowed as left-hand side of "let rec"
116116+|}];;
117117+118118+type t = [ `A ];;
119119+let rec #t = `A in ()
120120+[%%expect{|
121121+type t = [ `A ]
122122+Line 2, characters 8-10:
123123+2 | let rec #t = `A in ()
124124+ ^^
125125+Error: Only variables are allowed as left-hand side of "let rec"
126126+|}];;
127127+128128+let rec ((x, y) : int * int) = (1, 2) in x
129129+[%%expect{|
130130+Line 1, characters 8-28:
131131+1 | let rec ((x, y) : int * int) = (1, 2) in x
132132+ ^^^^^^^^^^^^^^^^^^^^
133133+Error: Only variables are allowed as left-hand side of "let rec"
134134+|}];;
135135+136136+let rec M.(Some (x : t)) = Some 1 in x
137137+[%%expect{|
138138+Line 1, characters 8-24:
139139+1 | let rec M.(Some (x : t)) = Some 1 in x
140140+ ^^^^^^^^^^^^^^^^
141141+Error: Only variables are allowed as left-hand side of "let rec"
142142+|}];;
143143+144144+let rec x = a and (a, b) = (1, 2) in x
145145+[%%expect{|
146146+Line 1, characters 18-24:
147147+1 | let rec x = a and (a, b) = (1, 2) in x
148148+ ^^^^^^
149149+Error: Only variables are allowed as left-hand side of "let rec"
150150+|}];;
+32-7
typing/typecore.ml
···36683668 | Tpat_construct (_, cd, _, _) when cd.cstr_generalized -> true
36693669 | _ -> false } p
3670367036713671+36723672+(* When typing [let rec p = e ...], we require [p] to be "variable-like":
36733673+ it must consists of a single variable [x], optionally wrapped in
36743674+ erasable pattern constructs (e.g. annotations, local opens) *)
36753675+let rec is_var_pat p =
36763676+ match p.ppat_desc with
36773677+ | Ppat_var _ -> true
36783678+ | Ppat_constraint (p, _)
36793679+ | Ppat_open (_, p) -> is_var_pat p
36803680+ | Ppat_any
36813681+ | Ppat_alias _
36823682+ | Ppat_constant _
36833683+ | Ppat_interval _
36843684+ | Ppat_tuple _
36853685+ | Ppat_construct _
36863686+ | Ppat_variant _
36873687+ | Ppat_record _
36883688+ | Ppat_array _
36893689+ | Ppat_or _
36903690+ | Ppat_type _
36913691+ | Ppat_lazy _
36923692+ | Ppat_unpack _
36933693+ | Ppat_exception _
36943694+ | Ppat_effect _
36953695+ | Ppat_extension _ -> false
36963696+36713697(* There are various things that we need to do in presence of GADT constructors
36723698 that aren't required if there are none.
36733699 However, because of disambiguation, we can't know for sure whether the
···65786604 let spatl = List.map vb_pat_constraint spat_sexp_list in
65796605 let attrs_list = List.map fst spatl in
65806606 let is_recursive = (rec_flag = Recursive) in
65816581-66076607+ if is_recursive then
66086608+ List.iter
66096609+ (fun { pvb_pat = pat; _ } ->
66106610+ if not (is_var_pat pat)
66116611+ then raise (Error (pat.ppat_loc, env, Illegal_letrec_pat)))
66126612+ spat_sexp_list;
65826613 let (pat_list, exp_list, new_env, mvs) =
65836614 with_local_level_generalize begin fun () ->
65846615 if existential_context = At_toplevel then Typetexp.TyVarEnv.reset ();
···67026733 })
67036734 l spat_sexp_list
67046735 in
67056705- if is_recursive then
67066706- List.iter
67076707- (fun {vb_pat=pat} -> match pat.pat_desc with
67086708- Tpat_var _ -> ()
67096709- | _ -> raise(Error(pat.pat_loc, env, Illegal_letrec_pat)))
67106710- l;
67116736 List.iter (fun vb ->
67126737 if pattern_needs_partial_application_check vb.vb_pat then
67136738 check_partial_application ~statement:false vb.vb_expr