Skip to content

Commit 3705657

Browse files
handle mixed constraints of types and anon fields (fixes #10162)
1 parent 43860db commit 3705657

File tree

7 files changed

+55
-15
lines changed

7 files changed

+55
-15
lines changed

extra/CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
all : fixed completion for a type in `expr is Type` (#10167)
99
all : fixed subtypes in `expr is Module.SubType` expressions (#10174)
1010
all : fixed typing chains of calls with constrained type params (#10198)
11+
all : fixed mixed constraints of anonymous structures and other types (#10162)
1112
hl : fixed debugging of `catch` blocks (#10109)
1213
jvm : fixed manifest generation for cases with a lot of jar libraries (#10157)
1314
js : fixed extending extern classes for es5 (#10192)

src/context/display/displayFields.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ let collect ctx e_ast e dk with_type p =
137137
in
138138
match follow t with
139139
| TMono m ->
140-
begin match Monomorph.classify_down_constraints m with
140+
let rec fold_constraints items = function
141141
| CStructural(fields,is_open) ->
142142
if not is_open then begin
143143
Monomorph.close m;
@@ -151,7 +151,10 @@ let collect ctx e_ast e dk with_type p =
151151
items
152152
| CUnknown ->
153153
items
154-
end
154+
| CMixed l ->
155+
List.fold_left fold_constraints items l
156+
in
157+
fold_constraints items (Monomorph.classify_down_constraints m)
155158
| TInst ({cl_kind = KTypeParameter tl},_) ->
156159
(* Type parameters can access the fields of their constraints *)
157160
List.fold_left (fun acc t -> loop acc t) items tl

src/core/tPrinting.ml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,15 @@ let rec s_type ctx t =
3939
with Not_found ->
4040
let id = List.length !ctx in
4141
ctx := (t,id) :: !ctx;
42-
let s_const = match !monomorph_classify_constraints_ref r with
42+
let s_const =
43+
let rec loop = function
4344
| CUnknown -> ""
44-
| CTypes tl -> " : " ^ String.concat " & " (List.map (fun (t,_) -> s_type ctx t) tl)
45-
| CStructural(fields,_) -> " : " ^ s_type ctx (mk_anon ~fields (ref Closed))
45+
| CTypes tl -> String.concat " & " (List.map (fun (t,_) -> s_type ctx t) tl)
46+
| CStructural(fields,_) -> s_type ctx (mk_anon ~fields (ref Closed))
47+
| CMixed l -> String.concat " & " (List.map loop l)
48+
in
49+
let s = loop (!monomorph_classify_constraints_ref r) in
50+
if s = "" then s else " : " ^ s
4651
in
4752
Printf.sprintf "Unknown<%d>%s" id s_const
4853
end

src/core/tType.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ and tmono_constraint =
6565
and tmono_constraint_kind =
6666
| CUnknown
6767
| CStructural of (string,tclass_field) PMap.t * bool
68+
| CMixed of tmono_constraint_kind list
6869
| CTypes of (t * string option) list
6970

7071
and tlazy =

src/core/tUnification.ml

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,18 +131,25 @@ module Monomorph = struct
131131
in
132132
List.iter check m.tm_down_constraints;
133133
let kind =
134-
if DynArray.length types > 0 then
135-
CTypes (DynArray.to_list types)
136-
else if not (PMap.is_empty !fields) || !is_open then
137-
CStructural(!fields,!is_open)
134+
let k1 =
135+
if DynArray.length types > 0 then
136+
CTypes (DynArray.to_list types)
137+
else
138+
CUnknown
139+
in
140+
if not (PMap.is_empty !fields) || !is_open then
141+
let k2 = CStructural(!fields,!is_open) in
142+
match k1 with
143+
| CTypes _ -> CMixed [k1; k2]
144+
| _ -> k2
138145
else
139-
CUnknown
146+
k1
140147
in
141148
!monos,kind
142149

143150
let classify_down_constraints m = snd (classify_down_constraints' m)
144151

145-
let check_down_constraints constr t =
152+
let rec check_down_constraints constr t =
146153
match constr with
147154
| CUnknown ->
148155
()
@@ -156,6 +163,8 @@ module Monomorph = struct
156163
| CStructural(fields,is_open) ->
157164
let t2 = mk_anon ~fields (ref Closed) in
158165
(!unify_ref) default_unification_context t t2
166+
| CMixed l ->
167+
List.iter (fun constr -> check_down_constraints constr t) l
159168

160169
let rec collect_up_constraints m =
161170
let rec collect m acc =
@@ -213,7 +222,7 @@ module Monomorph = struct
213222
(* Due to recursive constraints like in #9603, we tentatively bind the monomorph to the type we're checking
214223
against before checking the constraints. *)
215224
m.tm_type <- Some t;
216-
let monos,kind = classify_down_constraints' m in
225+
let kind = classify_down_constraints m in
217226
Std.finally (fun () -> m.tm_type <- None) (fun () -> check_down_constraints kind t) ();
218227
do_bind m t
219228
end
@@ -227,7 +236,7 @@ module Monomorph = struct
227236
| CTypes [(t,_)] ->
228237
do_bind m t;
229238
()
230-
| CTypes _ ->
239+
| CTypes _ | CMixed _ ->
231240
()
232241
| CStructural(fields,_) ->
233242
let check_recursion cf =

src/typing/fields.ml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) =
354354
(mk_field i (mk_mono()) p null_pos) with
355355
cf_kind = Var { v_read = AccNormal; v_write = if is_set then AccNormal else AccNo }
356356
} in
357-
(match Monomorph.classify_down_constraints r with
357+
let rec check_constr = function
358358
| CStructural (fields,is_open) ->
359359
(try
360360
let f = PMap.find i fields in
@@ -377,7 +377,18 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) =
377377
Monomorph.add_down_constraint r (MField f);
378378
Monomorph.add_down_constraint r MOpenStructure;
379379
field_access f FHAnon
380-
)
380+
| CMixed l ->
381+
let rec loop_constraints l =
382+
match l with
383+
| [] ->
384+
raise Not_found
385+
| constr :: l ->
386+
try check_constr constr
387+
with Not_found -> loop_constraints l
388+
in
389+
loop_constraints l
390+
in
391+
check_constr (Monomorph.classify_down_constraints r)
381392
| TAbstract (a,tl) ->
382393
(try
383394
let c = find_some a.a_impl in

tests/unit/src/unit/TestDCE.hx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,16 @@ class TestDCE extends Test {
190190
var c = Type.getClass(me);
191191
hf(c, "get_bar");
192192
}
193+
194+
public function testIssue10162() {
195+
eq('bar', foo(ClassWithBar));
196+
}
197+
static function foo<T:Class<Dynamic> & { function bar():String; }>(cls:T)
198+
return cls.bar();
199+
}
200+
201+
class ClassWithBar {
202+
static public function bar() return 'bar';
193203
}
194204

195205
class UsedConstructed {

0 commit comments

Comments
 (0)