Skip to content

Commit 61aff32

Browse files
committed
error handling
1 parent 279c248 commit 61aff32

9 files changed

+78
-4
lines changed

compiler/frontend/bs_builtin_ppx.ml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,15 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
149149
- `@let.unwrap let Some(inner_pat) = expr`
150150
- `@let.unwrap let None = expr`
151151
...into switches *)
152+
| Pexp_let (_, [{pvb_pat; pvb_attributes}], _)
153+
when Ast_attributes.has_unwrap_attr pvb_attributes ->
154+
if not (Experimental_features.is_enabled Experimental_features.LetUnwrap)
155+
then
156+
Bs_syntaxerr.err pvb_pat.ppat_loc
157+
(Experimental_feature_not_enabled LetUnwrap)
158+
else
159+
Bs_syntaxerr.err pvb_pat.ppat_loc
160+
(LetUnwrap_not_supported_in_position `Unsupported_type)
152161
| Pexp_let
153162
( Nonrecursive,
154163
[
@@ -441,6 +450,19 @@ let signature_item_mapper (self : mapper) (sigi : Parsetree.signature_item) :
441450
let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) :
442451
Parsetree.structure_item =
443452
match str.pstr_desc with
453+
| Pstr_value (_, vbs)
454+
when List.exists
455+
(fun (vb : Parsetree.value_binding) ->
456+
Ast_attributes.has_unwrap_attr vb.pvb_attributes)
457+
vbs ->
458+
let vb =
459+
List.find
460+
(fun (vb : Parsetree.value_binding) ->
461+
Ast_attributes.has_unwrap_attr vb.pvb_attributes)
462+
vbs
463+
in
464+
Bs_syntaxerr.err vb.pvb_pat.ppat_loc
465+
(LetUnwrap_not_supported_in_position `Toplevel)
444466
| Pstr_type (rf, tdcls) (* [ {ptype_attributes} as tdcl ] *) ->
445467
Ast_tdcls.handle_tdcls_in_stru self str rf tdcls
446468
| Pstr_primitive prim

compiler/frontend/bs_syntaxerr.ml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ type error =
4848
| Optional_in_uncurried_bs_attribute
4949
| Bs_this_simple_pattern
5050
| Experimental_feature_not_enabled of Experimental_features.feature
51+
| LetUnwrap_not_supported_in_position of [`Toplevel | `Unsupported_type]
5152

5253
let pp_error fmt err =
5354
Format.pp_print_string fmt
@@ -89,7 +90,13 @@ let pp_error fmt err =
8990
"Experimental feature not enabled: %s. Enable it by setting \"%s\" to \
9091
true under \"experimentalFeatures\" in rescript.json"
9192
(Experimental_features.to_string feature)
92-
(Experimental_features.to_string feature))
93+
(Experimental_features.to_string feature)
94+
| LetUnwrap_not_supported_in_position hint -> (
95+
match hint with
96+
| `Toplevel -> "`let?` is not allowed for top-level bindings."
97+
| `Unsupported_type ->
98+
"`let?` is only supported in let bindings targeting the `result` or \
99+
`option` type."))
93100

94101
type exn += Error of Location.t * error
95102

compiler/frontend/bs_syntaxerr.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ type error =
4848
| Optional_in_uncurried_bs_attribute
4949
| Bs_this_simple_pattern
5050
| Experimental_feature_not_enabled of Experimental_features.feature
51+
| LetUnwrap_not_supported_in_position of [`Toplevel | `Unsupported_type]
5152

5253
val err : Location.t -> error -> 'a
5354

compiler/common/experimental_features.ml renamed to compiler/ml/experimental_features.ml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ let from_string (s : string) : feature option =
99
| "LetUnwrap" -> Some LetUnwrap
1010
| _ -> None
1111

12-
let enabled_features : feature list ref = ref []
12+
module FeatureSet = Set.Make (struct
13+
type t = feature
14+
let compare = compare
15+
end)
16+
17+
let enabled_features : FeatureSet.t ref = ref FeatureSet.empty
1318
let enable_from_string (s : string) =
1419
match from_string s with
15-
| Some f -> enabled_features := f :: !enabled_features
20+
| Some f -> enabled_features := FeatureSet.add f !enabled_features
1621
| None -> ()
1722

18-
let is_enabled (f : feature) = List.mem f !enabled_features
23+
let is_enabled (f : feature) = FeatureSet.mem f !enabled_features
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/let_unwrap_on_not_supported_variant.res:13:8-16
4+
5+
11 │
6+
12 │ let ff = {
7+
13 │ let? Failed(x) = xx
8+
14 │ Ok(x)
9+
15 │ }
10+
11+
`let?` is only supported in let bindings targeting the `result` or `option` type.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/let_unwrap_on_top_level.res:3:6-10
4+
5+
1 │ let x = Ok(1)
6+
2 │
7+
3 │ let? Ok(_) = x
8+
4 │
9+
10+
`let?` is not allowed for top-level bindings.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@@config({flags: ["-enable-experimental", "LetUnwrap"]})
2+
3+
let x = switch 1 {
4+
| 1 => Ok(1)
5+
| _ => Error(#Invalid)
6+
}
7+
8+
type ff = Failed(int) | GoOn
9+
10+
let xx = Failed(1)
11+
12+
let ff = {
13+
let? Failed(x) = xx
14+
Ok(x)
15+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
let x = Ok(1)
2+
3+
let? Ok(_) = x

0 commit comments

Comments
 (0)