Skip to content

Commit 63ed2cc

Browse files
committed
parmatch.ml: refactor matrix_stable_vars to easily handle inconsistent matrices
1 parent 67b235c commit 63ed2cc

1 file changed

Lines changed: 38 additions & 23 deletions

File tree

typing/parmatch.ml

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2135,23 +2135,22 @@ and simplify_head_pat head_bound_variables p ps varsets k =
21352135
| _ ->
21362136
(p, { row = ps; varsets = head_bound_variables :: varsets; }) :: k
21372137

2138+
(* Compute stable bindings *)
21382139

2139-
let split_rows rows =
2140-
let extend_row columns r =
2141-
{ r with row = columns @ r.row } in
2142-
let q0 = discr_pat omega rows in
2143-
match build_specialized_submatrices ~extend_row q0 rows with
2144-
| { default; constrs = [] } -> [default]
2145-
| { default = _; constrs } -> List.map snd constrs
2140+
type stable_vars =
2141+
| All
2142+
| Vars of IdSet.t
21462143

2147-
(* Compute stable bindings *)
2144+
let stable_inter sv1 sv2 = match sv1, sv2 with
2145+
| All, sv | sv, All -> sv
2146+
| Vars s1, Vars s2 -> Vars (IdSet.inter s1 s2)
21482147

21492148
let reduce f = function
21502149
| [] -> invalid_arg "reduce"
21512150
| x::xs -> List.fold_left f x xs
21522151

21532152
let rec matrix_stable_vars rs = match rs with
2154-
| [] -> assert false (* No empty matrix *)
2153+
| [] -> All
21552154
| { row = []; _ } :: _ ->
21562155
(* All rows have the same number of columns;
21572156
if the first row is empty, they all are. *)
@@ -2165,13 +2164,27 @@ let rec matrix_stable_vars rs = match rs with
21652164
let stables_in_varsets = reduce (List.map2 IdSet.inter) rows_varsets in
21662165

21672166
(* The stable variables are those stable at any position *)
2168-
List.fold_left IdSet.union IdSet.empty stables_in_varsets
2169-
| rs ->
2170-
let submatrices = split_rows (simplify_first_col rs) in
2171-
let submat_stable = List.map matrix_stable_vars submatrices in
2172-
(* a stable variable must be stable in each submatrix;
2173-
if the matrix has at least one row, there is at least one submatrix *)
2174-
reduce IdSet.inter submat_stable
2167+
Vars (List.fold_left IdSet.union IdSet.empty stables_in_varsets)
2168+
| rows ->
2169+
let rows = simplify_first_col rows in
2170+
let extend_row columns r =
2171+
{ r with row = columns @ r.row } in
2172+
let q0 = discr_pat omega rows in
2173+
match build_specialized_submatrices ~extend_row q0 rows with
2174+
| { default; constrs = [] } ->
2175+
(* the first column contains no head constructor;
2176+
they are all _ after simplification, so it can be dropped *)
2177+
matrix_stable_vars default
2178+
| { default = _; constrs } ->
2179+
(* A stable variable must be stable in each submatrix.
2180+
2181+
If the first column contains some head constructors, there
2182+
is no need to look at stability for the default matrix: all
2183+
other submatrices contain the default matrix, so they have
2184+
less stable variables. *)
2185+
let submatrices = List.map snd constrs in
2186+
let submat_stable = List.map matrix_stable_vars submatrices in
2187+
List.fold_left stable_inter All submat_stable
21752188

21762189
let pattern_stable_vars p = matrix_stable_vars [{varsets = []; row = [p]}]
21772190

@@ -2239,12 +2252,14 @@ let check_ambiguous_bindings =
22392252
let all =
22402253
IdSet.inter (pattern_vars p) (all_rhs_idents g) in
22412254
if not (IdSet.is_empty all) then begin
2242-
let stable = pattern_stable_vars p in
2243-
let ambiguous = IdSet.diff all stable in
2244-
if not (IdSet.is_empty ambiguous) then begin
2245-
let pps = IdSet.elements ambiguous |> List.map Ident.name in
2246-
let warn = Ambiguous_pattern pps in
2247-
Location.prerr_warning p.pat_loc warn
2248-
end
2255+
match pattern_stable_vars p with
2256+
| All -> ()
2257+
| Vars stable ->
2258+
let ambiguous = IdSet.diff all stable in
2259+
if not (IdSet.is_empty ambiguous) then begin
2260+
let pps = IdSet.elements ambiguous |> List.map Ident.name in
2261+
let warn = Ambiguous_pattern pps in
2262+
Location.prerr_warning p.pat_loc warn
2263+
end
22492264
end)
22502265
cases

0 commit comments

Comments
 (0)