Skip to content

Commit 12b9b6e

Browse files
lpw25lthlsgoldfirere
authored
Track types of variables bound by as (#3507)
* Track types of variables bound by `as` Keep the types of variables bound by `as` because they may not equal the types of the `as` patterns themselves. This fixes some incorrect value kinds that can lead to miscompilation. * Add test * Get ocamldoc compiling * Fix chamelon --------- Co-authored-by: Vincent Laviron <vincent.laviron@gmail.com> Co-authored-by: Richard Eisenberg <reisenberg@janestreet.com>
1 parent e99c40a commit 12b9b6e

22 files changed

+96
-66
lines changed

chamelon/compat.jst.ml

+5-4
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,10 @@ type tpat_var_identifier = Value.l
297297
let mkTpat_var ?id:(mode = dummy_value_mode) (ident, name) =
298298
Tpat_var (ident, name, Uid.internal_not_actually_unique, mode)
299299

300-
type tpat_alias_identifier = Value.l
300+
type tpat_alias_identifier = Value.l * Types.type_expr
301301

302-
let mkTpat_alias ?id:(mode = dummy_value_mode) (p, ident, name) =
303-
Tpat_alias (p, ident, name, Uid.internal_not_actually_unique, mode)
302+
let mkTpat_alias ~id:(mode, ty) (p, ident, name) =
303+
Tpat_alias (p, ident, name, Uid.internal_not_actually_unique, mode, ty)
304304

305305
type tpat_array_identifier = mutability * Jkind.sort
306306

@@ -340,7 +340,8 @@ type 'a matched_pattern_desc =
340340
let view_tpat (type a) (p : a pattern_desc) : a matched_pattern_desc =
341341
match p with
342342
| Tpat_var (ident, name, _uid, mode) -> Tpat_var (ident, name, mode)
343-
| Tpat_alias (p, ident, name, _uid, mode) -> Tpat_alias (p, ident, name, mode)
343+
| Tpat_alias (p, ident, name, _uid, mode, ty) ->
344+
Tpat_alias (p, ident, name, (mode, ty))
344345
| Tpat_array (mut, arg_sort, l) -> Tpat_array (l, (mut, arg_sort))
345346
| Tpat_tuple pats ->
346347
let labels, pats = List.split pats in

chamelon/compat.mli

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ val mkTpat_var :
121121
?id:tpat_var_identifier -> Ident.t * string Location.loc -> value pattern_desc
122122

123123
val mkTpat_alias :
124-
?id:tpat_alias_identifier ->
124+
id:tpat_alias_identifier ->
125125
value general_pattern * Ident.t * string Location.loc ->
126126
value pattern_desc
127127

chamelon/compat.upstream.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ let mkTpat_var ?id:(() = ()) (ident, name) = Tpat_var (ident, name)
175175

176176
type tpat_alias_identifier = unit
177177

178-
let mkTpat_alias ?id:(() = ()) (p, ident, name) = Tpat_alias (p, ident, name)
178+
let mkTpat_alias ~id:() (p, ident, name) = Tpat_alias (p, ident, name)
179179

180180
type tpat_array_identifier = unit
181181

lambda/matching.ml

+14-12
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,9 @@ end = struct
239239
| Tpat_any
240240
| Tpat_var _ ->
241241
p
242-
| Tpat_alias (q, id, s, uid, mode) ->
243-
{ p with pat_desc = Tpat_alias (simpl_under_orpat q, id, s, uid, mode) }
242+
| Tpat_alias (q, id, s, uid, mode, ty) ->
243+
{ p with pat_desc =
244+
Tpat_alias (simpl_under_orpat q, id, s, uid, mode, ty) }
244245
| Tpat_or (p1, p2, o) ->
245246
let p1, p2 = (simpl_under_orpat p1, simpl_under_orpat p2) in
246247
if le_pat p1 p2 then
@@ -267,8 +268,8 @@ end = struct
267268
match p.pat_desc with
268269
| `Any -> stop p `Any
269270
| `Var (id, s, uid, mode) ->
270-
continue p (`Alias (Patterns.omega, id, s, uid, mode))
271-
| `Alias (p, id, _, _, _) ->
271+
continue p (`Alias (Patterns.omega, id, s, uid, mode, p.pat_type))
272+
| `Alias (p, id, _, _, _, _) ->
272273
aux
273274
( (General.view p, patl),
274275
bind_alias p id ~arg ~arg_sort ~action )
@@ -375,10 +376,11 @@ end = struct
375376
match p.pat_desc with
376377
| `Or (p1, p2, _) ->
377378
split_explode p1 aliases (split_explode p2 aliases rem)
378-
| `Alias (p, id, _, _, _) -> split_explode p (id :: aliases) rem
379+
| `Alias (p, id, _, _, _, _) -> split_explode p (id :: aliases) rem
379380
| `Var (id, str, uid, mode) ->
380381
explode
381-
{ p with pat_desc = `Alias (Patterns.omega, id, str, uid, mode) }
382+
{ p with pat_desc =
383+
`Alias (Patterns.omega, id, str, uid, mode, p.pat_type) }
382384
aliases rem
383385
| #view as view ->
384386
(* We are doing two things here:
@@ -626,7 +628,7 @@ end = struct
626628
match p.pat_desc with
627629
| `Or (p1, p2, _) ->
628630
filter_rec ((left, p1, right) :: (left, p2, right) :: rem)
629-
| `Alias (p, _, _, _, _) -> filter_rec ((left, p, right) :: rem)
631+
| `Alias (p, _, _, _, _, _) -> filter_rec ((left, p, right) :: rem)
630632
| `Var _ -> filter_rec ((left, Patterns.omega, right) :: rem)
631633
| #Simple.view as view -> (
632634
let p = { p with pat_desc = view } in
@@ -676,7 +678,7 @@ let rec flatten_pat_line size p k =
676678
| Tpat_tuple args -> (List.map snd args) :: k
677679
| Tpat_or (p1, p2, _) ->
678680
flatten_pat_line size p1 (flatten_pat_line size p2 k)
679-
| Tpat_alias (p, _, _, _, _) ->
681+
| Tpat_alias (p, _, _, _, _, _) ->
680682
(* Note: we are only called from flatten_matrix,
681683
which is itself only ever used in places
682684
where variables do not matter (default environments,
@@ -754,7 +756,7 @@ end = struct
754756
| (p, ps) :: rem -> (
755757
let p = General.view p in
756758
match p.pat_desc with
757-
| `Alias (p, _, _, _, _) -> filter_rec ((p, ps) :: rem)
759+
| `Alias (p, _, _, _, _, _) -> filter_rec ((p, ps) :: rem)
758760
| `Var _ -> filter_rec ((Patterns.omega, ps) :: rem)
759761
| `Or (p1, p2, _) -> filter_rec_or p1 p2 ps rem
760762
| #Simple.view as view -> (
@@ -1304,7 +1306,7 @@ let rec omega_like p =
13041306
| Tpat_any
13051307
| Tpat_var _ ->
13061308
true
1307-
| Tpat_alias (p, _, _, _, _) -> omega_like p
1309+
| Tpat_alias (p, _, _, _, _, _) -> omega_like p
13081310
| Tpat_or (p1, p2, _) -> omega_like p1 || omega_like p2
13091311
| _ -> false
13101312

@@ -3723,7 +3725,7 @@ let rec name_pattern default = function
37233725
| ((pat, _), _) :: rem -> (
37243726
match pat.pat_desc with
37253727
| Tpat_var (id, _, _, _) -> id
3726-
| Tpat_alias (_, id, _, _, _) -> id
3728+
| Tpat_alias (_, id, _, _, _, _) -> id
37273729
| _ -> name_pattern default rem
37283730
)
37293731
| _ -> Ident.create_local default
@@ -4267,7 +4269,7 @@ let for_let ~scopes ~arg_sort ~return_layout loc param pat body =
42674269
for "let _ = ...". See #6865. *)
42684270
Lsequence (param, body)
42694271
| Tpat_var (id, _, _, _)
4270-
| Tpat_alias ({ pat_desc = Tpat_any }, id, _, _, _) ->
4272+
| Tpat_alias ({ pat_desc = Tpat_any }, id, _, _, _, _) ->
42714273
(* Fast path, and keep track of simple bindings to unboxable numbers.
42724274
42734275
Note: the (Tpat_alias (Tpat_any, id)) case needs to be

lambda/translclass.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ let create_object cl obj init =
155155
let name_pattern default p =
156156
match p.pat_desc with
157157
| Tpat_var (id, _, _, _) -> id
158-
| Tpat_alias(_, id, _, _, _) -> id
158+
| Tpat_alias(_, id, _, _, _, _) -> id
159159
| _ -> Ident.create_local default
160160

161161
let rec build_object_init ~scopes cl_table obj params inh_init obj_init cl =

lambda/translcore.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ let fuse_method_arity (parent : fusable_function) : fusable_function =
322322
let rec iter_exn_names f pat =
323323
match pat.pat_desc with
324324
| Tpat_var (id, _, _, _) -> f id
325-
| Tpat_alias (p, id, _, _, _) ->
325+
| Tpat_alias (p, id, _, _, _, _) ->
326326
f id;
327327
iter_exn_names f p
328328
| _ -> ()

ocamldoc/odoc_ast.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ module Typedtree_search =
5151
let iter_val_pattern = function
5252
| Typedtree.Tpat_any -> None
5353
| Typedtree.Tpat_var (name, _, _, _)
54-
| Typedtree.Tpat_alias (_, name, _, _, _) -> Some (Name.from_ident name)
54+
| Typedtree.Tpat_alias (_, name, _, _, _, _) -> Some (Name.from_ident name)
5555
| Typedtree.Tpat_tuple _ -> None (* FIXME when we will handle tuples *)
5656
| _ -> None
5757

@@ -258,7 +258,7 @@ module Analyser =
258258
sn_type = Odoc_env.subst_type env pat.pat_type
259259
}
260260

261-
| Typedtree.Tpat_alias (pat, _, _, _, _) ->
261+
| Typedtree.Tpat_alias (pat, _, _, _, _, _) ->
262262
iter_pattern pat
263263

264264
| Typedtree.Tpat_tuple patlist ->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
(* TEST
2+
native;
3+
*)
4+
5+
type r = { foo : float }
6+
7+
type 'a t = Left of 'a | Right of r
8+
9+
type 'a ty =
10+
| Float : float ty
11+
| Anything : 'a ty
12+
13+
let f (type a) (ty : a ty) (x : a t) =
14+
match ty, x with
15+
| Float, Right { foo = (((3.5 : a) as a) : float) }
16+
| _, Left a -> ignore (Sys.opaque_identity a)
17+
| _, _ -> ()
18+
19+
let f = Sys.opaque_identity f
20+
21+
let () = f Anything (Left 0)

typing/cmt2annot.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ let variables_iterator scope =
2323
let super = default_iterator in
2424
let pat sub (type k) (p : k general_pattern) =
2525
begin match p.pat_desc with
26-
| Tpat_var (id, _, _, _) | Tpat_alias (_, id, _, _, _) ->
26+
| Tpat_var (id, _, _, _) | Tpat_alias (_, id, _, _, _, _) ->
2727
Stypes.record (Stypes.An_ident (p.pat_loc,
2828
Ident.name id,
2929
Annot.Idef scope))

typing/parmatch.ml

+11-11
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,8 @@ module Compat
335335
| ((Tpat_any|Tpat_var _),_)
336336
| (_,(Tpat_any|Tpat_var _)) -> true
337337
(* Structural induction *)
338-
| Tpat_alias (p,_,_,_,_),_ -> compat p q
339-
| _,Tpat_alias (q,_,_,_,_) -> compat p q
338+
| Tpat_alias (p,_,_,_,_,_),_ -> compat p q
339+
| _,Tpat_alias (q,_,_,_,_,_) -> compat p q
340340
| Tpat_or (p1,p2,_),_ ->
341341
(compat p1 q || compat p2 q)
342342
| _,Tpat_or (q1,q2,_) ->
@@ -1216,7 +1216,7 @@ let build_other ext env =
12161216
let rec has_instance p = match p.pat_desc with
12171217
| Tpat_variant (l,_,r) when is_absent l r -> false
12181218
| Tpat_any | Tpat_var _ | Tpat_constant _ | Tpat_variant (_,None,_) -> true
1219-
| Tpat_alias (p,_,_,_,_) | Tpat_variant (_,Some p,_) -> has_instance p
1219+
| Tpat_alias (p,_,_,_,_,_) | Tpat_variant (_,Some p,_) -> has_instance p
12201220
| Tpat_or (p1,p2,_) -> has_instance p1 || has_instance p2
12211221
| Tpat_construct (_,_,ps, _) | Tpat_array (_, _, ps) ->
12221222
has_instances ps
@@ -1676,7 +1676,7 @@ let is_var_column rs =
16761676
(* Standard or-args for left-to-right matching *)
16771677
let rec or_args p = match p.pat_desc with
16781678
| Tpat_or (p1,p2,_) -> p1,p2
1679-
| Tpat_alias (p,_,_,_,_) -> or_args p
1679+
| Tpat_alias (p,_,_,_,_,_) -> or_args p
16801680
| _ -> assert false
16811681

16821682
(* Just remove current column *)
@@ -1856,8 +1856,8 @@ and every_both pss qs q1 q2 =
18561856
let rec le_pat p q =
18571857
match (p.pat_desc, q.pat_desc) with
18581858
| (Tpat_var _|Tpat_any),_ -> true
1859-
| Tpat_alias(p,_,_,_,_), _ -> le_pat p q
1860-
| _, Tpat_alias(q,_,_,_,_) -> le_pat p q
1859+
| Tpat_alias(p,_,_,_,_,_), _ -> le_pat p q
1860+
| _, Tpat_alias(q,_,_,_,_,_) -> le_pat p q
18611861
| Tpat_constant(c1), Tpat_constant(c2) -> const_compare c1 c2 = 0
18621862
| Tpat_construct(_,c1,ps,_), Tpat_construct(_,c2,qs,_) ->
18631863
Types.equal_tag c1.cstr_tag c2.cstr_tag && le_pats ps qs
@@ -1917,8 +1917,8 @@ let get_mins le ps =
19171917
*)
19181918

19191919
let rec lub p q = match p.pat_desc,q.pat_desc with
1920-
| Tpat_alias (p,_,_,_,_),_ -> lub p q
1921-
| _,Tpat_alias (q,_,_,_,_) -> lub p q
1920+
| Tpat_alias (p,_,_,_,_,_),_ -> lub p q
1921+
| _,Tpat_alias (q,_,_,_,_,_) -> lub p q
19221922
| (Tpat_any|Tpat_var _),_ -> q
19231923
| _,(Tpat_any|Tpat_var _) -> p
19241924
| Tpat_or (p1,p2,_),_ -> orlub p1 p2 q
@@ -2150,7 +2150,7 @@ let rec collect_paths_from_pat r p = match p.pat_desc with
21502150
List.fold_left
21512151
(fun r (_, _, p) -> collect_paths_from_pat r p)
21522152
r lps
2153-
| Tpat_variant (_, Some p, _) | Tpat_alias (p,_,_,_,_) ->
2153+
| Tpat_variant (_, Some p, _) | Tpat_alias (p,_,_,_,_,_) ->
21542154
collect_paths_from_pat r p
21552155
| Tpat_or (p1,p2,_) ->
21562156
collect_paths_from_pat (collect_paths_from_pat r p1) p2
@@ -2290,7 +2290,7 @@ let inactive ~partial pat =
22902290
List.for_all (fun (_,p,_) -> loop p) ps
22912291
| Tpat_construct (_, _, ps, _) | Tpat_array (Immutable, _, ps) ->
22922292
List.for_all (fun p -> loop p) ps
2293-
| Tpat_alias (p,_,_,_,_) | Tpat_variant (_, Some p, _) ->
2293+
| Tpat_alias (p,_,_,_,_,_) | Tpat_variant (_, Some p, _) ->
22942294
loop p
22952295
| Tpat_record (ldps,_) ->
22962296
List.for_all
@@ -2419,7 +2419,7 @@ type amb_row = { row : pattern list ; varsets : Ident.Set.t list; }
24192419
let simplify_head_amb_pat head_bound_variables varsets ~add_column p ps k =
24202420
let rec simpl head_bound_variables varsets p ps k =
24212421
match (Patterns.General.view p).pat_desc with
2422-
| `Alias (p,x,_,_,_) ->
2422+
| `Alias (p,x,_,_,_,_) ->
24232423
simpl (Ident.Set.add x head_bound_variables) varsets p ps k
24242424
| `Var (x, _, _, _) ->
24252425
simpl (Ident.Set.add x head_bound_variables) varsets Patterns.omega ps k

typing/patterns.ml

+7-5
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ module General = struct
8585
type view = [
8686
| Half_simple.view
8787
| `Var of Ident.t * string loc * Uid.t * Mode.Value.l
88-
| `Alias of pattern * Ident.t * string loc * Uid.t * Mode.Value.l
88+
| `Alias of pattern * Ident.t * string loc
89+
* Uid.t * Mode.Value.l * Types.type_expr
8990
]
9091
type pattern = view pattern_data
9192

@@ -94,8 +95,8 @@ module General = struct
9495
`Any
9596
| Tpat_var (id, str, uid, mode) ->
9697
`Var (id, str, uid, mode)
97-
| Tpat_alias (p, id, str, uid, mode) ->
98-
`Alias (p, id, str, uid, mode)
98+
| Tpat_alias (p, id, str, uid, mode, ty) ->
99+
`Alias (p, id, str, uid, mode, ty)
99100
| Tpat_constant cst ->
100101
`Constant cst
101102
| Tpat_tuple ps ->
@@ -120,7 +121,8 @@ module General = struct
120121
let erase_desc = function
121122
| `Any -> Tpat_any
122123
| `Var (id, str, uid, mode) -> Tpat_var (id, str, uid, mode)
123-
| `Alias (p, id, str, uid, mode) -> Tpat_alias (p, id, str, uid, mode)
124+
| `Alias (p, id, str, uid, mode, ty) ->
125+
Tpat_alias (p, id, str, uid, mode, ty)
124126
| `Constant cst -> Tpat_constant cst
125127
| `Tuple ps -> Tpat_tuple ps
126128
| `Unboxed_tuple ps -> Tpat_unboxed_tuple ps
@@ -141,7 +143,7 @@ module General = struct
141143

142144
let rec strip_vars (p : pattern) : Half_simple.pattern =
143145
match p.pat_desc with
144-
| `Alias (p, _, _, _, _) -> strip_vars (view p)
146+
| `Alias (p, _, _, _, _, _) -> strip_vars (view p)
145147
| `Var _ -> { p with pat_desc = `Any }
146148
| #Half_simple.view as view -> { p with pat_desc = view }
147149
end

typing/patterns.mli

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ module General : sig
6969
type view = [
7070
| Half_simple.view
7171
| `Var of Ident.t * string loc * Uid.t * Mode.Value.l
72-
| `Alias of pattern * Ident.t * string loc * Uid.t * Mode.Value.l
72+
| `Alias of pattern * Ident.t * string loc * Uid.t
73+
* Mode.Value.l * Types.type_expr
7374
]
7475
type pattern = view pattern_data
7576

typing/printpat.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ let rec pretty_val : type k . _ -> k general_pattern -> _ = fun ppf v ->
114114
fprintf ppf "@[[%c %a %c]@]" punct (pretty_vals " ;") vs punct
115115
| Tpat_lazy v ->
116116
fprintf ppf "@[<2>lazy@ %a@]" pretty_arg v
117-
| Tpat_alias (v, x, _, _, _) ->
117+
| Tpat_alias (v, x, _, _, _, _) ->
118118
fprintf ppf "@[(%a@ as %a)@]" pretty_val v Ident.print x
119119
| Tpat_value v ->
120120
fprintf ppf "%a" pretty_val (v :> pattern)

typing/printtyped.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ and pattern : type k . _ -> _ -> k general_pattern -> unit = fun i ppf x ->
327327
| Tpat_var (s,_,_,m) ->
328328
line i ppf "Tpat_var \"%a\"\n" fmt_ident s;
329329
value_mode i ppf m
330-
| Tpat_alias (p, s,_,_,m) ->
330+
| Tpat_alias (p, s,_,_,m,_) ->
331331
line i ppf "Tpat_alias \"%a\"\n" fmt_ident s;
332332
value_mode i ppf m;
333333
pattern i ppf p;

typing/tast_iterator.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ let pat
270270
| Tpat_record_unboxed_product (l, _) ->
271271
List.iter (fun (lid, _, i) -> iter_loc sub lid; sub.pat sub i) l
272272
| Tpat_array (_, _, l) -> List.iter (sub.pat sub) l
273-
| Tpat_alias (p, _, s, _, _) -> sub.pat sub p; iter_loc sub s
273+
| Tpat_alias (p, _, s, _, _, _) -> sub.pat sub p; iter_loc sub s
274274
| Tpat_lazy p -> sub.pat sub p
275275
| Tpat_value p -> sub.pat sub (p :> pattern)
276276
| Tpat_exception p -> sub.pat sub p

typing/tast_mapper.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,8 @@ let pat
319319
Tpat_record_unboxed_product
320320
(List.map (tuple3 (map_loc sub) id (sub.pat sub)) l, closed)
321321
| Tpat_array (am, arg_sort, l) -> Tpat_array (am, arg_sort, List.map (sub.pat sub) l)
322-
| Tpat_alias (p, id, s, uid, m) ->
323-
Tpat_alias (sub.pat sub p, id, map_loc sub s, uid, m)
322+
| Tpat_alias (p, id, s, uid, m, ty) ->
323+
Tpat_alias (sub.pat sub p, id, map_loc sub s, uid, m, ty)
324324
| Tpat_lazy p -> Tpat_lazy (sub.pat sub p)
325325
| Tpat_value p ->
326326
(as_computation_pattern (sub.pat sub (p :> pattern))).pat_desc

0 commit comments

Comments
 (0)