Skip to content

Commit f7cd48f

Browse files
authored
flambda-backend: Backport #10364 (#1788)
1 parent 5740ebd commit f7cd48f

File tree

7 files changed

+48
-53
lines changed

7 files changed

+48
-53
lines changed

testsuite/tests/typing-gadts/ambivalent_apply.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ type (_, _) eq = Refl : ('a, 'a) eq
1111
let f (type a b) (w1 : (a, b -> b) eq) (w2 : (a, int -> int) eq) (g : a) =
1212
let Refl = w1 in let Refl = w2 in g 3;;
1313
[%%expect{|
14+
val f : ('a, 'b -> 'b) eq -> ('a, int -> int) eq -> 'a -> 'b = <fun>
15+
|}, Principal{|
1416
Line 2, characters 37-40:
1517
2 | let Refl = w1 in let Refl = w2 in g 3;;
1618
^^^

testsuite/tests/typing-gadts/didier.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ val f : 't -> 't ty -> bool = <fun>
5252
Line 4, characters 12-13:
5353
4 | | Bool -> x
5454
^
55-
Error: This expression has type t but an expression was expected of type bool
55+
Error: This expression has type t = bool
56+
but an expression was expected of type bool
57+
This instance of bool is ambiguous:
58+
it would escape the scope of its equation
5659
|}];;
5760
(* val f : 'a -> 'a ty -> bool = <fun> *)
5861

@@ -72,7 +75,10 @@ Error: This expression has type bool but an expression was expected of type
7275
Line 4, characters 11-16:
7376
4 | | Int -> x > 0
7477
^^^^^
75-
Error: This expression has type bool but an expression was expected of type t
78+
Error: This expression has type bool but an expression was expected of type
79+
t = int
80+
This instance of int is ambiguous:
81+
it would escape the scope of its equation
7682
|}];;
7783
(* Error: This expression has type bool but an expression was expected of type
7884
t = int *)

testsuite/tests/typing-gadts/test.ml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,10 @@ module Propagation :
370370
Line 13, characters 19-20:
371371
13 | | BoolLit b -> b
372372
^
373-
Error: This expression has type bool but an expression was expected of type s
373+
Error: This expression has type bool but an expression was expected of type
374+
s = bool
375+
This instance of bool is ambiguous:
376+
it would escape the scope of its equation
374377
|}];;
375378

376379
module Normal_constrs = struct
@@ -782,13 +785,6 @@ Error: This expression has type [> `A of a ]
782785
Type a is not compatible with type b = a
783786
This instance of a is ambiguous:
784787
it would escape the scope of its equation
785-
|}, Principal{|
786-
Line 2, characters 9-15:
787-
2 | fun Eq o -> o ;; (* fail *)
788-
^^^^^^
789-
Error: This expression has type ([> `A of b ] as 'a) -> 'a
790-
but an expression was expected of type [> `A of a ] -> [> `A of b ]
791-
Types for tag `A are incompatible
792788
|}];;
793789

794790
let f (type a b) (eq : (a,b) eq) (v : [> `A of a]) : [> `A of b] =

testsuite/tests/typing-layouts/basics_alpha.ml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -464,13 +464,6 @@ Line 8, characters 16-21:
464464
8 | | `Bar v -> { v }
465465
^^^^^
466466
Error: This expression should not be a record, the expected type is result
467-
|}, Principal{|
468-
Line 8, characters 18-19:
469-
8 | | `Bar v -> { v }
470-
^
471-
Error: This expression has type ('a : value)
472-
but an expression was expected of type t_void
473-
t_void has layout void, which is not a sublayout of value.
474467
|}];;
475468

476469
module M8_3 = struct

testsuite/tests/typing-poly/poly.ml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,15 +1542,6 @@ Error: This expression has type < m : 'x. [< `Foo of 'x ] -> 'x >
15421542
but an expression was expected of type
15431543
< m : 'a. [< `Foo of int ] -> 'a >
15441544
The universal variable 'x would escape its scope
1545-
|}, Principal{|
1546-
Line 2, characters 2-72:
1547-
2 | object method m : 'x. [< `Foo of 'x] -> 'x = fun x -> assert false end;;
1548-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1549-
Error: This expression has type < m : 'x. [< `Foo of 'x ] -> 'x >
1550-
but an expression was expected of type < m : 'a. 'b -> 'a >
1551-
The method m has type 'x. [< `Foo of 'x ] -> 'x,
1552-
but the expected method type was 'a. 'b -> 'a
1553-
The universal variable 'x would escape its scope
15541545
|}];;
15551546
(* ok *)
15561547
let f (n : < m : 'a 'r. [< `Foo of 'a & int | `Bar] as 'r >) =

testsuite/tests/typing-polyvariants-bugs/pr8575.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ val test : unit -> [> `A_t of A.t | `Onoes ] = <fun>
1818
Line 5, characters 49-50:
1919
5 | | B -> if Random.bool () then `Onoes else `A_t B;;
2020
^
21-
Error: Unbound constructor B
21+
Warning 18 [not-principal]: this type-based constructor disambiguation is not principal.
22+
val test : unit -> [> `A_t of A.t | `Onoes ] = <fun>
2223
|}]
2324

2425
let test () =
@@ -32,5 +33,6 @@ val test : unit -> [> `A_t of A.t | `Onoes ] = <fun>
3233
Line 5, characters 49-50:
3334
5 | | B -> if Random.bool () then `Onoes else `A_t B;;
3435
^
35-
Error: Unbound constructor B
36+
Warning 18 [not-principal]: this type-based constructor disambiguation is not principal.
37+
val test : unit -> [> `A_t of A.t | `Onoes ] = <fun>
3638
|}]

typing/typecore.ml

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -678,13 +678,19 @@ let extract_option_type env ty =
678678
Tconstr(path, [ty], _) when Path.same path Predef.path_option -> ty
679679
| _ -> assert false
680680

681+
let protect_expansion env ty =
682+
if Env.has_local_constraints env then generic_instance ty else ty
683+
681684
type record_extraction_result =
682685
| Record_type of Path.t * Path.t * Types.label_declaration list * record_representation
683686
| Not_a_record_type
684687
| Maybe_a_record_type
685688

689+
let extract_concrete_typedecl_protected env ty =
690+
extract_concrete_typedecl env (protect_expansion env ty)
691+
686692
let extract_concrete_record env ty =
687-
match extract_concrete_typedecl env ty with
693+
match extract_concrete_typedecl_protected env ty with
688694
| Typedecl(p0, p, {type_kind=Type_record (fields, repres)}) ->
689695
Record_type (p0, p, fields, repres)
690696
| Has_no_typedecl | Typedecl(_, _, _) -> Not_a_record_type
@@ -696,7 +702,7 @@ type variant_extraction_result =
696702
| Maybe_a_variant_type
697703

698704
let extract_concrete_variant env ty =
699-
match extract_concrete_typedecl env ty with
705+
match extract_concrete_typedecl_protected env ty with
700706
| Typedecl(p0, p, {type_kind=Type_variant (cstrs, _)}) ->
701707
Variant_type (p0, p, cstrs)
702708
| Typedecl(p0, p, {type_kind=Type_open}) ->
@@ -3342,6 +3348,12 @@ let collect_unknown_apply_args env funct ty_fun mode_fun rev_args sargs ret_tvar
33423348
let collect_apply_args env funct ignore_labels ty_fun ty_fun0 mode_fun sargs ret_tvar =
33433349
let warned = ref false in
33443350
let rec loop ty_fun ty_fun0 mode_fun rev_args sargs =
3351+
let type_unknown_args () =
3352+
(* We're not looking at a *known* function type anymore, or there are no
3353+
arguments left. *)
3354+
collect_unknown_apply_args env funct ty_fun0 mode_fun rev_args sargs ret_tvar
3355+
in
3356+
if sargs = [] then type_unknown_args () else
33453357
let ty_fun' = expand_head env ty_fun in
33463358
match get_desc ty_fun', get_desc (expand_head env ty_fun0), sargs with
33473359
| Tarrow (ad, ty_arg, ty_ret, com),
@@ -3426,9 +3438,7 @@ let collect_apply_args env funct ignore_labels ty_fun ty_fun0 mode_fun sargs ret
34263438
in
34273439
loop ty_ret ty_ret0 mode_ret ((l, arg) :: rev_args) remaining_sargs
34283440
| _ ->
3429-
(* We're not looking at a *known* function type anymore, or there are no
3430-
arguments left. *)
3431-
collect_unknown_apply_args env funct ty_fun0 mode_fun rev_args sargs ret_tvar
3441+
type_unknown_args ()
34323442
in
34333443
loop ty_fun ty_fun0 mode_fun [] sargs
34343444

@@ -4537,7 +4547,7 @@ and type_expect_
45374547
| Pexp_constant(Pconst_string (str, _, _) as cst) ->
45384548
let cst = constant_or_raise env loc cst in
45394549
(* Terrible hack for format strings *)
4540-
let ty_exp = expand_head env ty_expected in
4550+
let ty_exp = expand_head env (protect_expansion env ty_expected) in
45414551
let fmt6_path =
45424552
Path.(Pdot (Pident (Ident.create_persistent "CamlinternalFormatBasics"),
45434553
"format6"))
@@ -4973,10 +4983,11 @@ and type_expect_
49734983
sarg ty_expected_explained sexp.pexp_attributes
49744984
| Pexp_variant(l, sarg) ->
49754985
(* Keep sharing *)
4986+
let ty_expected1 = protect_expansion env ty_expected in
49764987
let ty_expected0 = instance ty_expected in
49774988
let argument_mode = mode_subcomponent expected_mode in
49784989
begin try match
4979-
sarg, get_desc (expand_head env ty_expected),
4990+
sarg, get_desc (expand_head env ty_expected1),
49804991
get_desc (expand_head env ty_expected0)
49814992
with
49824993
| Some sarg, Tvariant row, Tvariant row0 ->
@@ -5746,7 +5757,7 @@ and type_expect_
57465757
| Pexp_poly(sbody, sty) ->
57475758
if !Clflags.principal then begin_def ();
57485759
let ty, cty =
5749-
match sty with None -> ty_expected, None
5760+
match sty with None -> protect_expansion env ty_expected, None
57505761
| Some sty ->
57515762
let sty = Ast_helper.Typ.force_poly sty in
57525763
let cty =
@@ -5796,7 +5807,8 @@ and type_expect_
57965807
match get_desc (Ctype.expand_head env (instance ty_expected)) with
57975808
Tpackage (p, fl) ->
57985809
if !Clflags.principal &&
5799-
get_level (Ctype.expand_head env ty_expected)
5810+
get_level (Ctype.expand_head env
5811+
(protect_expansion env ty_expected))
58005812
< Btype.generic_level
58015813
then
58025814
Location.prerr_warning loc
@@ -6684,7 +6696,7 @@ and type_argument ?explanation ?recarg env (mode : expected_mode) sarg
66846696
(lv <> generic_level || get_level ty_fun' <> generic_level)
66856697
and ty_fun = instance ty_fun' in
66866698
let marg, ty_arg, mret, ty_res =
6687-
match get_desc (expand_head env ty_expected') with
6699+
match get_desc (expand_head env ty_expected) with
66886700
Tarrow((Nolabel,marg,mret),ty_arg,ty_res,_) ->
66896701
marg, ty_arg, mret, ty_res
66906702
| _ -> assert false
@@ -7182,6 +7194,8 @@ and type_cases
71827194
) half_typed_cases;
71837195
(* type bodies *)
71847196
let in_function = if List.length caselist = 1 then in_function else None in
7197+
let ty_res' = instance ty_res in
7198+
if !Clflags.principal then begin_def ();
71857199
let cases =
71867200
List.map
71877201
(fun { typed_pat = pat; branch_env = ext_env;
@@ -7200,14 +7214,8 @@ and type_cases
72007214
~check_as:(fun s -> Warnings.Unused_var s)
72017215
in
72027216
let ext_env = add_module_variables ext_env mvs in
7203-
let ty_res' =
7204-
if !Clflags.principal then begin
7205-
begin_def ();
7206-
let ty = instance ~partial:true ty_res in
7207-
end_def ();
7208-
generalize_structure ty; ty
7209-
end
7210-
else if contains_gadt then
7217+
let ty_expected =
7218+
if contains_gadt && not !Clflags.principal then
72117219
(* allow propagation from preceding branches *)
72127220
correct_levels ty_res
72137221
else ty_res in
@@ -7221,20 +7229,17 @@ and type_cases
72217229
in
72227230
let exp =
72237231
type_expect ?in_function ext_env emode
7224-
pc_rhs (mk_expected ?explanation ty_res')
7232+
pc_rhs (mk_expected ?explanation ty_expected)
72257233
in
72267234
{
72277235
c_lhs = pat;
72287236
c_guard = guard;
7229-
c_rhs = {exp with exp_type = instance ty_res'}
7237+
c_rhs = {exp with exp_type = ty_res'}
72307238
}
72317239
)
72327240
half_typed_cases
72337241
in
7234-
if !Clflags.principal || does_contain_gadt then begin
7235-
let ty_res' = instance ty_res in
7236-
List.iter (fun c -> unify_exp env c.c_rhs ty_res') cases
7237-
end;
7242+
if !Clflags.principal then end_def ();
72387243
let do_init = may_contain_gadts || needs_exhaust_check in
72397244
let ty_arg_check =
72407245
if do_init then
@@ -7281,7 +7286,7 @@ and type_cases
72817286
if create_inner_level then begin
72827287
end_def ();
72837288
(* Ensure that existential types do not escape *)
7284-
unify_exp_types loc env (instance ty_res)
7289+
unify_exp_types loc env ty_res'
72857290
(newvar (Layout.any ~why:Dummy_layout));
72867291
end;
72877292
cases, partial

0 commit comments

Comments
 (0)