Skip to content

Commit 7c6f354

Browse files
authored
Do not show coercion suggestion when coercion isn't possible (#7721)
* fix bug where suggestion to run coercion was shown even when coercion wasn't possible * changelog
1 parent c79b033 commit 7c6f354

File tree

5 files changed

+35
-7
lines changed

5 files changed

+35
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
- Apply heuristic to suggest using JSX fragments where we guess that might be what the user wanted. https://github.com/rescript-lang/rescript/pull/7714
1818

19+
#### :bug: Bug fix
20+
21+
- Fix error message that falsely suggested using coercion when it wouldn't work. https://github.com/rescript-lang/rescript/pull/7721
22+
1923
# 12.0.0-beta.3
2024

2125
#### :boom: Breaking Change

compiler/ml/error_message_utils.ml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ let extract_string_constant text =
233233
| _ -> None
234234
235235
let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
236-
(bottom_aliases : (Types.type_expr * Types.type_expr) option)
236+
(bottom_aliases : (Types.type_expr * Types.type_expr) option) trace
237237
type_clash_context =
238238
match (type_clash_context, bottom_aliases) with
239239
| Some (MathOperator {for_float; operator; is_constant}), _ -> (
@@ -623,10 +623,16 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
623623
| None -> ())
624624
| None -> ())
625625
| _ -> ())
626-
| _, Some (t1, t2) ->
626+
| _, Some (_supplied_type, target_type) ->
627+
(* Coercion should always target the top level types. *)
628+
let top_level_types =
629+
match trace with
630+
| (_, t1_top) :: (_, t2_top) :: _ -> Some (t1_top, t2_top)
631+
| _ -> None
632+
in
627633
let can_show_coercion_message =
628-
match (t1.desc, t2.desc) with
629-
| Tvariant _, Tvariant _ ->
634+
match top_level_types with
635+
| Some ({Types.desc = Tvariant _}, {Types.desc = Tvariant _}) ->
630636
(* Subtyping polymorphic variants give some weird messages sometimes,
631637
so let's turn it off for now. For an example, turn them on again and try:
632638
```
@@ -635,13 +641,14 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
635641
```
636642
*)
637643
false
638-
| _ -> (
644+
| Some (t1, t2) -> (
639645
try
640646
Ctype.subtype env t1 t2 ();
641647
true
642648
with _ -> false)
649+
| None -> false
643650
in
644-
let target_type_string = Format.asprintf "%a" type_expr t2 in
651+
let target_type_string = Format.asprintf "%a" type_expr target_type in
645652
let target_expr_text = Parser.extract_text_at_loc loc in
646653
let suggested_rewrite =
647654
match

compiler/ml/typecore.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ let print_expr_type_clash ~context env loc trace ppf =
800800
| ppf -> error_type_text ppf context)
801801
(function ppf -> error_expected_type_text ppf context);
802802
print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
803-
bottom_aliases_result context;
803+
bottom_aliases_result trace context;
804804
show_extra_help ppf env trace
805805

806806
let report_arity_mismatch ~arity_a ~arity_b ppf =
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/dict_show_no_coercion.res:2:23-35
4+
5+
1 │ // This should not show coercion suggestion since just the inner types a
6+
│ re coercable, not the full type + expression (dict<float> -> dict<JSON.t
7+
│ >)
8+
2 │ let x: dict<JSON.t> = dict{"1": 1.}
9+
3 │
10+
11+
This has type: dict<float>
12+
But it's expected to have type: dict<JSON.t>
13+
14+
The incompatible parts:
15+
float vs JSON.t (defined as JSON.t)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// This should not show coercion suggestion since just the inner types are coercable, not the full type + expression (dict<float> -> dict<JSON.t>)
2+
let x: dict<JSON.t> = dict{"1": 1.}

0 commit comments

Comments
 (0)