Skip to content

Commit

Permalink
Error messages: Improve "Somewhere wanted" messages (#6410)
Browse files Browse the repository at this point in the history
* first batch of changes trying to improve the Somewhere wanted error messages

* tweaks

* add more fixtures

* remove redundant text

* add specialized errors for array items and setting record fields

* tweak set record field message

* hint about tuple in array message

* move message handling to own file

* cleanup

* cleanup

* cleanup

* cleanup

* changelog

* add example of tuple to error message
  • Loading branch information
zth authored Sep 26, 2023
1 parent a8c7f15 commit 6f972d7
Show file tree
Hide file tree
Showing 48 changed files with 558 additions and 74 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

- A little performance improvement for JSX V4 runtime helper by removing one object allocation for components with key prop. https://github.com/rescript-lang/rescript-compiler/pull/6376
- The error message for "toplevel expressions should evaluate to unit" has been revamped and improved. https://github.com/rescript-lang/rescript-compiler/pull/6407
- Improve "Somewhere wanted" error messages by changing wording and adding more context + suggested solutions to the error messages where appropriate. https://github.com/rescript-lang/rescript-compiler/pull/6410

# 11.0.0-rc.3

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

We've found a bug for you!
/.../fixtures/array_item_type_mismatch.res:1:16-22

1 │ let x = [1, 2, "hello"]
2 │

This array item has type: string
But this array is expected to have items of type: int

Arrays can only contain items of the same type.

Possible solutions:
- Convert all values in the array to the same type.
- Use a tuple, if your array is of fixed length. Tuples can mix types freely, and compiles to a JavaScript array. Example of a tuple: `let myTuple = (10, "hello", 15.5, true)

You can convert string to int with Belt.Int.fromString.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
3 │

This has type: string
Somewhere wanted: int
But it's expected to have type: int

You can convert string to int with Belt.Int.fromString.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

We've found a bug for you!
/.../fixtures/comparison_operator.res:3:17

1 │ let f = Some(0)
2 │
3 │ let x = 100 === f
4 │

This has type: option<int>
But it's being compared to something of type: int

You can only compare things of the same type.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

We've found a bug for you!
/.../fixtures/function_argument_mismatch.res:3:28-30

1 │ let makeName = (s, i) => s ++ i
2 │
3 │ let name = makeName("123", 123)
4 │

This has type: int
But this function argument is expecting: string

You can convert int to string with Belt.Int.toString.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

We've found a bug for you!
/.../fixtures/function_call_mismatch.res:6:3-10

4 │
5 │ let cloneInTemp = (temp: string): string => {
6 │ cd(temp)
7 │ exec("git clone [email protected]:myorg/myrepo.git")
8 │ }

This function call returns: string
But it's expected to return: unit
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

We've found a bug for you!
/.../fixtures/function_return_mismatch.res:9:3-5

7 │
8 │ let x = fnExpectingCleanup(() => {
9 │ 123
10 │ })
11 │

This has type: int
But it's expected to have type: cleanup (defined as unit => unit)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
4 │

This has type: string
Somewhere wanted: int
But it's expected to have type: int

You can convert string to int with Belt.Int.fromString.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
5 ┆

This has type: string
Somewhere wanted: int
But it's expected to have type: int

You can convert string to int with Belt.Int.fromString.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
5 │

This has type: string
Somewhere wanted: int
But it's expected to have type: int

You can convert string to int with Belt.Int.fromString.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
3 │

This has type: string
Somewhere wanted: int
But it's expected to have type: int

You can convert string to int with Belt.Int.fromString.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

We've found a bug for you!
/.../fixtures/if_branch_mismatch.res:4:3-5

2 │ "123"
3 │ } else {
4 │ 123
5 │ }
6 │

This has type: int
But this if statement is expected to return: string

if expressions must return the same type in all branches (if, else if, else).

You can convert int to string with Belt.Int.toString.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

We've found a bug for you!
/.../fixtures/if_condition_mismatch.res:1:12-18

1 │ let x = if "horse" {
2 │ ()
3 │ }

This has type: string
But if conditions must always be of type: bool

To fix this, change the highlighted code so it evaluates to a bool.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

We've found a bug for you!
/.../fixtures/math_operator_constant.res:3:15-17

1 │ let num = 0
2 │
3 │ let x = num + 12.
4 │

This value has type: float
But it's being used with the + operator, which works on: int

Floats and ints have their own mathematical operators. This means you cannot add a float and an int without converting between the two.

Possible solutions:
- Ensure all values in this calculation has the type int. You can convert between floats and ints via Belt.Float.toInt and Belt.Int.fromFloat.
- Make 12. an int by removing the dot or explicitly converting to int

You can convert float to int with Belt.Float.toInt.
If this is a literal, try a number without a trailing dot (e.g. 20).
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

We've found a bug for you!
/.../fixtures/math_operator_float.res:3:9-11

1 │ let num = 0
2 │
3 │ let x = num +. 12.
4 │

This has type: int
But it's being used with the +. operator, which works on: float

Floats and ints have their own mathematical operators. This means you cannot add a float and an int without converting between the two.

Possible solutions:
- Ensure all values in this calculation has the type float. You can convert between floats and ints via Belt.Float.toInt and Belt.Int.fromFloat.
- Change the operator to +, which works on int

You can convert int to float with Belt.Int.toFloat.
If this is a literal, try a number with a trailing dot (e.g. 20.).
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

We've found a bug for you!
/.../fixtures/math_operator_int.res:3:9-11

1 │ let num = 0.
2 │
3 │ let x = num + 12.
4 │

This has type: float
But it's being used with the + operator, which works on: int

Floats and ints have their own mathematical operators. This means you cannot add a float and an int without converting between the two.

Possible solutions:
- Ensure all values in this calculation has the type int. You can convert between floats and ints via Belt.Float.toInt and Belt.Int.fromFloat.
- Change the operator to +., which works on float

You can convert float to int with Belt.Float.toInt.
If this is a literal, try a number without a trailing dot (e.g. 20).
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@
2 │ 2. + 2
3 │

This has type: float
Somewhere wanted: int
This value has type: float
But it's being used with the + operator, which works on: int

Floats and ints have their own mathematical operators. This means you cannot add a float and an int without converting between the two.

Possible solutions:
- Ensure all values in this calculation has the type int. You can convert between floats and ints via Belt.Float.toInt and Belt.Int.fromFloat.
- Make 2. an int by removing the dot or explicitly converting to int

You can convert float to int with Belt.Float.toInt.
If this is a literal, try a number without a trailing dot (e.g. 20).
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
6 │

This has type: b (defined as option<bb>)
Somewhere wanted: a (defined as option<aa>)
But it's expected to have type: a (defined as option<aa>)

The incompatible parts:
bb (defined as option<int>) vs aa (defined as option<string>)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
3 │

This has type: int
Somewhere wanted: string
But this function argument is expecting: string

You can convert int to string with Belt.Int.toString.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
4 │

This has type: int
Somewhere wanted: float
But it's expected to have type: float

You can convert int to float with Belt.Int.toFloat.
If this is a literal, try a number with a trailing dot (e.g. 20.).
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
4 │

This has type: list<int>
Somewhere wanted: list<float>
But this function argument is expecting: list<float>

The incompatible parts:
int vs float
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
2 │

This has type: string
Somewhere wanted: int
But it's expected to have type: int

You can convert string to int with Belt.Int.fromString.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
10 │

This has type: string
Somewhere wanted: int
But it's expected to have type: int

You can convert string to int with Belt.Int.fromString.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

We've found a bug for you!
/.../fixtures/set_record_field_type_match.res:11:13-14

9 │ }
10 │
11 │ user.name = 12
12 │

You're assigning something to this field that has type: int
But this record field is of type: string

You can convert int to string with Belt.Int.toString.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

We've found a bug for you!
/.../fixtures/switch_different_types.res:7:10-23

5 │ switch foo {
6 │ | "world" => ()
7 │ | _ => someFunction()
8 │ }
9 │ }

This has type: string
But this switch is expected to return: unit

All branches in a switch must return the same type. To fix this, change your branch to return the expected type.
14 changes: 14 additions & 0 deletions jscomp/build_tests/super_errors/expected/switch_guard.res.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

We've found a bug for you!
/.../fixtures/switch_guard.res:6:16-22

4 │ let bar = () => {
5 │ switch foo {
6 │ | "world" if "horse" => ()
7 │ | _ => someFunction()
8 │ }

This has type: string
But if conditions must always be of type: bool

To fix this, change the highlighted code so it evaluates to a bool.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
23 │ /* */

This has type: string
Somewhere wanted: int
But it's expected to have type: int

You can convert string to int with Belt.Int.fromString.
10 changes: 8 additions & 2 deletions jscomp/build_tests/super_errors/expected/type1.res.expected
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@
1 │ let x = 2. + 2
2 │

This has type: float
Somewhere wanted: int
This value has type: float
But it's being used with the + operator, which works on: int

Floats and ints have their own mathematical operators. This means you cannot add a float and an int without converting between the two.

Possible solutions:
- Ensure all values in this calculation has the type int. You can convert between floats and ints via Belt.Float.toInt and Belt.Int.fromFloat.
- Make 2. an int by removing the dot or explicitly converting to int

You can convert float to int with Belt.Float.toInt.
If this is a literal, try a number without a trailing dot (e.g. 20).
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
8 │

This has type: string
Somewhere wanted: int
But this function argument is expecting: int

You can convert string to int with Belt.Int.fromString.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
│ (unicode symbols of length 2)

This has type: int
Somewhere wanted: string
But this function argument is expecting: string

You can convert int to string with Belt.Int.toString.
Loading

0 comments on commit 6f972d7

Please sign in to comment.