Skip to content

Commit 51aeb04

Browse files
committed
Keep generalized structure from patterns when typing let
1 parent 4b68bb3 commit 51aeb04

File tree

4 files changed

+29
-39
lines changed

4 files changed

+29
-39
lines changed

testsuite/tests/typing-misc/pr7937.ml

-14
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,6 @@ Line 3, characters 35-39:
1212
^^^^
1313
Error: This expression has type bool but an expression was expected of type
1414
([< `X of int & 'a ] as 'a) r
15-
|}, Principal{|
16-
type 'a r = 'a constraint 'a = [< `X of int & 'a ]
17-
Line 3, characters 35-39:
18-
3 | let f: 'a. 'a r -> 'a r = fun x -> true;;
19-
^^^^
20-
Error: This expression has type bool but an expression was expected of type
21-
([< `X of 'b & 'a & 'c ] as 'a) r
2215
|}]
2316

2417
let g: 'a. 'a r -> 'a r = fun x -> { contents = 0 };;
@@ -28,13 +21,6 @@ Line 1, characters 35-51:
2821
^^^^^^^^^^^^^^^^
2922
Error: This expression has type int ref
3023
but an expression was expected of type ([< `X of int & 'a ] as 'a) r
31-
|}, Principal{|
32-
Line 1, characters 35-51:
33-
1 | let g: 'a. 'a r -> 'a r = fun x -> { contents = 0 };;
34-
^^^^^^^^^^^^^^^^
35-
Error: This expression has type int ref
36-
but an expression was expected of type
37-
([< `X of 'b & 'a & 'c ] as 'a) r
3824
|}]
3925

4026
let h: 'a. 'a r -> _ = function true | false -> ();;

testsuite/tests/typing-poly/poly.ml

+9
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,15 @@ Error: This expression has type < m : 'x. [< `Foo of 'x ] -> 'x >
15401540
but an expression was expected of type
15411541
< m : 'a. [< `Foo of int ] -> 'a >
15421542
The universal variable 'x would escape its scope
1543+
|}, Principal{|
1544+
Line 2, characters 2-72:
1545+
2 | object method m : 'x. [< `Foo of 'x] -> 'x = fun x -> assert false end;;
1546+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1547+
Error: This expression has type < m : 'x. [< `Foo of 'x ] -> 'x >
1548+
but an expression was expected of type < m : 'a. 'b -> 'a >
1549+
The method m has type 'x. [< `Foo of 'x ] -> 'x,
1550+
but the expected method type was 'a. 'b -> 'a
1551+
The universal variable 'x would escape its scope
15431552
|}];;
15441553
(* ok *)
15451554
let f (n : < m : 'a 'r. [< `Foo of 'a & int | `Bar] as 'r >) =

testsuite/tests/typing-poly/pr11544.ml

-7
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,4 @@ let poly3 : 'b. M.t -> 'b -> 'b =
88
[%%expect {|
99
module M : sig type t = T end
1010
val poly3 : M.t -> 'b -> 'b = <fun>
11-
|}, Principal{|
12-
module M : sig type t = T end
13-
Line 3, characters 6-7:
14-
3 | fun T x -> x
15-
^
16-
Warning 18 [not-principal]: this type-based constructor disambiguation is not principal.
17-
val poly3 : M.t -> 'b -> 'b = <fun>
1811
|}];;

typing/typecore.ml

+20-18
Original file line numberDiff line numberDiff line change
@@ -6304,11 +6304,13 @@ and type_let
63046304
end_def ();
63056305
iter_pattern_variables_type generalize_structure pvs;
63066306
List.map (fun (m, pat) ->
6307-
generalize_structure pat.pat_type;
6308-
m, {pat with pat_type = instance pat.pat_type}
6307+
let ty = pat.pat_type in
6308+
generalize_structure ty;
6309+
m, {pat with pat_type = instance ty}, ty
63096310
) pat_list
6310-
end else
6311-
pat_list
6311+
end else begin
6312+
List.map (fun (m, pat) -> (m, pat, pat.pat_type)) pat_list
6313+
end
63126314
in
63136315
(* Only bind pattern variables after generalizing *)
63146316
List.iter (fun f -> f()) force;
@@ -6342,7 +6344,7 @@ and type_let
63426344
|| (is_recursive && (Warnings.is_active Warnings.Unused_rec_flag))))
63436345
attrs_list
63446346
in
6345-
let mode_pat_slot_list =
6347+
let mode_typ_slot_list =
63466348
(* Algorithm to detect unused declarations in recursive bindings:
63476349
- During type checking of the definitions, we capture the 'value_used'
63486350
events on the bound identifiers and record them in a slot corresponding
@@ -6360,9 +6362,9 @@ and type_let
63606362
warning is 26, not 27.
63616363
*)
63626364
List.map2
6363-
(fun attrs (mode, pat) ->
6365+
(fun attrs (mode, pat, expected_ty) ->
63646366
Builtin_attributes.warning_scope ~ppwarning:false attrs (fun () ->
6365-
if not warn_about_unused_bindings then mode, pat, None
6367+
if not warn_about_unused_bindings then mode, expected_ty, None
63666368
else
63676369
let some_used = ref false in
63686370
(* has one of the identifier of this pattern been used? *)
@@ -6394,16 +6396,16 @@ and type_let
63946396
)
63956397
)
63966398
(Typedtree.pat_bound_idents pat);
6397-
mode, pat, Some slot
6399+
mode, expected_ty, Some slot
63986400
))
63996401
attrs_list
64006402
pat_list
64016403
in
64026404
let exp_list =
64036405
List.map2
6404-
(fun {pvb_expr=sexp; pvb_attributes; _} (mode, pat, slot) ->
6406+
(fun {pvb_expr=sexp; pvb_attributes; _} (mode, expected_ty, slot) ->
64056407
if is_recursive then current_slot := slot;
6406-
match get_desc pat.pat_type with
6408+
match get_desc expected_ty with
64076409
| Tpoly (ty, tl) ->
64086410
if !Clflags.principal then begin_def ();
64096411
let vars, ty' = instance_poly ~keep_names:true true tl ty in
@@ -6427,13 +6429,13 @@ and type_let
64276429
Builtin_attributes.warning_scope pvb_attributes (fun () ->
64286430
if rec_flag = Recursive then
64296431
type_unpacks exp_env mode
6430-
unpacks sexp (mk_expected pat.pat_type)
6432+
unpacks sexp (mk_expected expected_ty)
64316433
else
64326434
type_expect exp_env mode
6433-
sexp (mk_expected pat.pat_type))
6435+
sexp (mk_expected expected_ty))
64346436
in
64356437
exp, None)
6436-
spat_sexp_list mode_pat_slot_list in
6438+
spat_sexp_list mode_typ_slot_list in
64376439
current_slot := None;
64386440
if is_recursive && not !rec_needed then begin
64396441
let {pvb_pat; pvb_attributes} = List.hd spat_sexp_list in
@@ -6444,7 +6446,7 @@ and type_let
64446446
)
64456447
end;
64466448
List.iter2
6447-
(fun (_,pat) (attrs, exp) ->
6449+
(fun (_,pat,_) (attrs, exp) ->
64486450
Builtin_attributes.warning_scope ~ppwarning:false attrs
64496451
(fun () ->
64506452
ignore(check_partial env pat.pat_type pat.pat_loc
@@ -6456,13 +6458,13 @@ and type_let
64566458
let pvs = List.map (fun pv -> { pv with pv_type = instance pv.pv_type}) pvs in
64576459
end_def();
64586460
List.iter2
6459-
(fun (_,pat) (exp, _) ->
6461+
(fun (_,pat,_) (exp, _) ->
64606462
if maybe_expansive exp then
64616463
lower_contravariant env pat.pat_type)
64626464
pat_list exp_list;
64636465
iter_pattern_variables_type generalize pvs;
64646466
List.iter2
6465-
(fun (_,pat) (exp, vars) ->
6467+
(fun (_,_,expected_ty) (exp, vars) ->
64666468
match vars with
64676469
| None ->
64686470
(* We generalize expressions even if they are not bound to a variable
@@ -6478,12 +6480,12 @@ and type_let
64786480
| Some vars ->
64796481
if maybe_expansive exp then
64806482
lower_contravariant env exp.exp_type;
6481-
generalize_and_check_univars env "definition" exp pat.pat_type vars)
6483+
generalize_and_check_univars env "definition" exp expected_ty vars)
64826484
pat_list exp_list;
64836485
let l = List.combine pat_list exp_list in
64846486
let l =
64856487
List.map2
6486-
(fun ((_,p), (e, _)) pvb ->
6488+
(fun ((_,p,_), (e, _)) pvb ->
64876489
{vb_pat=p; vb_expr=e; vb_attributes=pvb.pvb_attributes;
64886490
vb_loc=pvb.pvb_loc;
64896491
})

0 commit comments

Comments
 (0)