Skip to content

Commit 6ddf320

Browse files
committed
try to improve error message
1 parent 1080871 commit 6ddf320

File tree

4 files changed

+35
-13
lines changed

4 files changed

+35
-13
lines changed

compiler/ml/error_message_utils.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ type type_clash_context =
9696
| IfReturn
9797
| TernaryReturn
9898
| SwitchReturn
99+
| LetUnwrapReturn
99100
| TryReturn
100101
| StringConcat
101102
| ComparisonOperator
@@ -131,6 +132,7 @@ let context_to_string = function
131132
| Some TernaryReturn -> "TernaryReturn"
132133
| Some Await -> "Await"
133134
| Some BracedIdent -> "BracedIdent"
135+
| Some LetUnwrapReturn -> "LetUnwrapReturn"
134136
| None -> "None"
135137
136138
let fprintf = Format.fprintf
@@ -163,6 +165,9 @@ let error_expected_type_text ppf type_clash_context =
163165
| Some ComparisonOperator ->
164166
fprintf ppf "But it's being compared to something of type:"
165167
| Some SwitchReturn -> fprintf ppf "But this switch is expected to return:"
168+
| Some LetUnwrapReturn ->
169+
fprintf ppf
170+
"But this @{<info>let?@} is used in a context expecting the type:"
166171
| Some TryReturn -> fprintf ppf "But this try/catch is expected to return:"
167172
| Some WhileCondition ->
168173
fprintf ppf "But a @{<info>while@} loop condition must always be of type:"
@@ -314,6 +319,11 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
314319
"\n\n\
315320
\ All branches in a @{<info>switch@} must return the same type.@,\
316321
To fix this, change your branch to return the expected type."
322+
| Some LetUnwrapReturn, _ ->
323+
fprintf ppf
324+
"\n\n\
325+
\ @{<info>let?@} can only be used in a context that expects \
326+
@{<info>option@} or @{<info>result@}."
317327
| Some TryReturn, _ ->
318328
fprintf ppf
319329
"\n\n\

compiler/ml/typecore.ml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2486,12 +2486,21 @@ and type_expect_ ~context ?in_function ?(recarg = Rejected) env sexp ty_expected
24862486
(* Note: val_caselist = [] and exn_caselist = [], i.e. a fully
24872487
empty pattern matching can be generated by Camlp4 with its
24882488
revised syntax. Let's accept it for backward compatibility. *)
2489+
let call_context =
2490+
if
2491+
Ext_list.exists sexp.pexp_attributes (fun ({txt}, _) ->
2492+
match txt with
2493+
| "let.unwrap" -> true
2494+
| _ -> false)
2495+
then `LetUnwrap
2496+
else `Switch
2497+
in
24892498
let val_cases, partial =
2490-
type_cases ~call_context:`Switch env arg.exp_type ty_expected true loc
2499+
type_cases ~call_context env arg.exp_type ty_expected true loc
24912500
val_caselist
24922501
in
24932502
let exn_cases, _ =
2494-
type_cases ~call_context:`Switch env Predef.type_exn ty_expected false loc
2503+
type_cases ~call_context env Predef.type_exn ty_expected false loc
24952504
exn_caselist
24962505
in
24972506
re
@@ -3887,8 +3896,9 @@ and type_statement ~context env sexp =
38873896
38883897
(* Typing of match cases *)
38893898
3890-
and type_cases ~(call_context : [`Switch | `Function | `Try]) ?in_function env
3891-
ty_arg ty_res partial_flag loc caselist : _ * Typedtree.partial =
3899+
and type_cases ~(call_context : [`LetUnwrap | `Switch | `Function | `Try])
3900+
?in_function env ty_arg ty_res partial_flag loc caselist :
3901+
_ * Typedtree.partial =
38923902
(* ty_arg is _fully_ generalized *)
38933903
let patterns = List.map (fun {pc_lhs = p} -> p) caselist in
38943904
let contains_polyvars = List.exists contains_polymorphic_variant patterns in
@@ -4006,6 +4016,7 @@ and type_cases ~(call_context : [`Switch | `Function | `Try]) ?in_function env
40064016
(match call_context with
40074017
| `Switch -> Some SwitchReturn
40084018
| `Try -> Some TryReturn
4019+
| `LetUnwrap -> Some LetUnwrapReturn
40094020
| `Function -> None)
40104021
?in_function ext_env sexp ty_res'
40114022
in
Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11

22
We've found a bug for you!
3-
/.../fixtures/let_unwrap_return_type_mismatch.res:4:8-14
3+
/.../fixtures/let_unwrap_return_type_mismatch.res:6:8-14
44

5-
2 │
6-
3 │ let fn = (): int => {
7-
4 │ let? Some(x) = None
8-
5 │ 42
9-
6 │ }
5+
4 │
6+
5 │ let fn = (): int => {
7+
6 │ let? Some(x) = None
8+
7 │ 42
9+
8 │ }
1010

1111
This has type: option<'a>
12-
But this switch is expected to return: int
12+
But this let? is used in a context expecting the type: int
1313

14-
All branches in a switch must return the same type.
15-
To fix this, change your branch to return the expected type.
14+
let? can only be used in a context that expects option or result.

tests/build_tests/super_errors/fixtures/let_unwrap_return_type_mismatch.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
@@config({flags: ["-enable-experimental", "LetUnwrap"]})
22

3+
let x = Some(1)
4+
35
let fn = (): int => {
46
let? Some(x) = None
57
42

0 commit comments

Comments
 (0)