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 2929#### :nail_care : Polish
3030
3131- 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
3233
3334#### :house : Internal
3435
Original file line number Diff line number Diff line change @@ -93,6 +93,7 @@ type type_clash_context =
9393 | IfCondition
9494 | AssertCondition
9595 | IfReturn
96+ | TernaryReturn
9697 | SwitchReturn
9798 | TryReturn
9899 | StringConcat
@@ -125,6 +126,7 @@ let context_to_string = function
125126 | Some (FunctionArgument _ ) -> " FunctionArgument"
126127 | Some ComparisonOperator -> " ComparisonOperator"
127128 | Some IfReturn -> " IfReturn"
129+ | Some TernaryReturn -> " TernaryReturn"
128130 | Some Await -> " Await"
129131 | None -> " None"
130132
@@ -168,6 +170,7 @@ let error_expected_type_text ppf type_clash_context =
168170 | Some AssertCondition -> fprintf ppf " But assertions must always be of type:"
169171 | Some IfReturn ->
170172 fprintf ppf " But this @{<info>if@} statement is expected to return:"
173+ | Some TernaryReturn -> fprintf ppf " But this ternary is expected to return:"
171174 | Some ArrayValue ->
172175 fprintf ppf " But this array is expected to have items of type:"
173176 | 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
332335 " \n\n \
333336 \ @{<info>if@} expressions must return the same type in all branches \
334337 (@{<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."
335343 | Some MaybeUnwrapOption , _ ->
336344 fprintf ppf
337345 " \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
28262826 exp_env = env;
28272827 }
28282828 | 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
28292841 let cond =
28302842 type_expect ~context: (Some IfCondition ) env scond Predef. type_bool
28312843 in
28322844 match sifnot with
28332845 | None ->
28342846 let ifso =
2835- type_expect ~context: ( Some IfReturn ) env sifso Predef. type_unit
2847+ type_expect ~context: return_context env sifso Predef. type_unit
28362848 in
28372849 rue
28382850 {
@@ -2844,10 +2856,10 @@ and type_expect_ ~context ?in_function ?(recarg = Rejected) env sexp ty_expected
28442856 exp_env = env;
28452857 }
28462858 | 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
28492861 (* Keep sharing *)
2850- unify_exp ~context: ( Some IfReturn ) env ifnot ifso.exp_type;
2862+ unify_exp ~context: return_context env ifnot ifso.exp_type;
28512863 re
28522864 {
28532865 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