Skip to content

Commit 4c94e00

Browse files
committed
teach IR typechecker to reject refutable import patterns
1 parent b109d6d commit 4c94e00

File tree

9 files changed

+28
-1
lines changed

9 files changed

+28
-1
lines changed

src/ir_def/check_ir.ml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,10 @@ and check_dec env dec =
10571057
| LetD (pat, exp) ->
10581058
ignore (check_pat_exhaustive env pat);
10591059
check_exp env exp;
1060-
typ exp <: pat.note
1060+
typ exp <: pat.note;
1061+
check env pat.at
1062+
Ir_utils.(expected_irrefutable dec ==> is_irrefutable pat)
1063+
"refutable pattern in import"
10611064
| VarD (id, t, exp) ->
10621065
check_exp env exp;
10631066
typ exp <: t

src/ir_def/ir_utils.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@ let rec is_irrefutable p = match p.it with
77
| WildP | VarP _ -> true
88
| TagP _ | LitP _ | OptP _ -> false
99

10+
11+
let expected_irrefutable : dec -> bool = function
12+
| { it = LetD (_, { it = VarE id; _ }); _ } ->
13+
Lib.String.starts_with "file$" id
14+
| _ -> false

src/lib/lib.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ struct
195195
else
196196
None
197197

198+
let starts_with prefix s = (* in OCaml 4.13 *)
199+
match chop_prefix prefix s with
200+
| Some _ -> true
201+
| _ -> false
202+
198203
let chop_suffix suffix s =
199204
let suffix_len = String.length suffix in
200205
let s_len = String.length s in

src/lib/lib.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ sig
154154
val split : string -> char -> string list
155155
val breakup : string -> int -> string list
156156
val find_from_opt : (char -> bool) -> string -> int -> int option
157+
val starts_with : string -> string -> bool
157158
val chop_prefix : string -> string -> string option
158159
val chop_suffix : string -> string -> string option
159160
val lightweight_escaped : string -> string

test/fail/nat-module.mo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module { public let why = 42 }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Ill-typed intermediate code after Desugaring (use -v to see dumped IR):
2+
refutable-import.mo:1.8-1.20: IR type error [M0000], refutable pattern in import
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Return code 1

test/fail/ok/refutable-import.tc.ok

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
refutable-import.mo:1.8-1.20: warning [M0145], this pattern of type
2+
module {why : Nat}
3+
does not cover value
4+
{why = 0 or 1 or _}

test/fail/refutable-import.mo

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { why = 42 } = "nat-module";
2+
3+
//SKIP run
4+
//SKIP run-low
5+
//SKIP comp

0 commit comments

Comments
 (0)