File tree Expand file tree Collapse file tree 5 files changed +39
-4
lines changed
tests/build_tests/super_errors Expand file tree Collapse file tree 5 files changed +39
-4
lines changed Original file line number Diff line number Diff line change 29
29
#### :nail_care : Polish
30
30
31
31
- Make parser less strict around leading attributes. https://github.com/rescript-lang/rescript/pull/7787
32
+ - Dedicated error message for ternary type mismatch. https://github.com/rescript-lang/rescript/pull/7804
32
33
33
34
#### :house : Internal
34
35
Original file line number Diff line number Diff line change @@ -93,6 +93,7 @@ type type_clash_context =
93
93
| IfCondition
94
94
| AssertCondition
95
95
| IfReturn
96
+ | TernaryReturn
96
97
| SwitchReturn
97
98
| TryReturn
98
99
| StringConcat
@@ -125,6 +126,7 @@ let context_to_string = function
125
126
| Some (FunctionArgument _ ) -> " FunctionArgument"
126
127
| Some ComparisonOperator -> " ComparisonOperator"
127
128
| Some IfReturn -> " IfReturn"
129
+ | Some TernaryReturn -> " TernaryReturn"
128
130
| Some Await -> " Await"
129
131
| None -> " None"
130
132
@@ -168,6 +170,7 @@ let error_expected_type_text ppf type_clash_context =
168
170
| Some AssertCondition -> fprintf ppf " But assertions must always be of type:"
169
171
| Some IfReturn ->
170
172
fprintf ppf " But this @{<info>if@} statement is expected to return:"
173
+ | Some TernaryReturn -> fprintf ppf " But this ternary is expected to return:"
171
174
| Some ArrayValue ->
172
175
fprintf ppf " But this array is expected to have items of type:"
173
176
| Some (SetRecordField _ ) -> fprintf ppf " But the record field is of type:"
@@ -332,6 +335,11 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
332
335
" \n\n \
333
336
\ @{<info>if@} expressions must return the same type in all branches \
334
337
(@{<info>if@}, @{<info>else if@}, @{<info>else@})."
338
+ | Some TernaryReturn , _ ->
339
+ fprintf ppf
340
+ " \n\n \
341
+ \ Ternaries (@{<info>?@} and @{<info>:@}) must return the same type in \
342
+ both branches."
335
343
| Some MaybeUnwrapOption , _ ->
336
344
fprintf ppf
337
345
" \n\n \
Original file line number Diff line number Diff line change @@ -2826,13 +2826,25 @@ and type_expect_ ~context ?in_function ?(recarg = Rejected) env sexp ty_expected
2826
2826
exp_env = env;
2827
2827
}
2828
2828
| Pexp_ifthenelse (scond , sifso , sifnot ) -> (
2829
+ (* TODO(attributes) Unify the attribute handling in the parser and rest of the compiler. *)
2830
+ let is_ternary =
2831
+ let rec has_ternary = function
2832
+ | [] -> false
2833
+ | ({Location. txt = "res.ternary" } , _ ) :: _ -> true
2834
+ | _ :: rest -> has_ternary rest
2835
+ in
2836
+ has_ternary sexp.pexp_attributes
2837
+ in
2838
+ let return_context =
2839
+ if is_ternary then Some TernaryReturn else Some IfReturn
2840
+ in
2829
2841
let cond =
2830
2842
type_expect ~context: (Some IfCondition ) env scond Predef. type_bool
2831
2843
in
2832
2844
match sifnot with
2833
2845
| None ->
2834
2846
let ifso =
2835
- type_expect ~context: ( Some IfReturn ) env sifso Predef. type_unit
2847
+ type_expect ~context: return_context env sifso Predef. type_unit
2836
2848
in
2837
2849
rue
2838
2850
{
@@ -2844,10 +2856,10 @@ and type_expect_ ~context ?in_function ?(recarg = Rejected) env sexp ty_expected
2844
2856
exp_env = env;
2845
2857
}
2846
2858
| Some sifnot ->
2847
- let ifso = type_expect ~context: ( Some IfReturn ) env sifso ty_expected in
2848
- let ifnot = type_expect ~context: ( Some IfReturn ) env sifnot ty_expected in
2859
+ let ifso = type_expect ~context: return_context env sifso ty_expected in
2860
+ let ifnot = type_expect ~context: return_context env sifnot ty_expected in
2849
2861
(* Keep sharing *)
2850
- unify_exp ~context: ( Some IfReturn ) env ifnot ifso.exp_type;
2862
+ unify_exp ~context: return_context env ifnot ifso.exp_type;
2851
2863
re
2852
2864
{
2853
2865
exp_desc = Texp_ifthenelse (cond, ifso, Some ifnot);
Original file line number Diff line number Diff line change
1
+
2
+ [1;31mWe've found a bug for you![0m
3
+ [36m/.../fixtures/ternary_branch_mismatch.res[0m:[2m1:24-26[0m
4
+
5
+ [1;31m1[0m [2m│[0m let x = true ? "123" : [1;31m123[0m
6
+ 2 [2m│[0m
7
+
8
+ This has type: [1;31mint[0m
9
+ But this ternary is expected to return: [1;33mstring[0m
10
+
11
+ Ternaries ([1;33m?[0m and [1;33m:[0m) must return the same type in both branches.
12
+
13
+ You can convert [1;33mint[0m to [1;33mstring[0m with [1;33mInt.toString[0m.
Original file line number Diff line number Diff line change
1
+ let x = true ? "123" : 123
You can’t perform that action at this time.
0 commit comments