Skip to content

Commit 1850fe5

Browse files
authored
Error message for when trying to await something that is not a promise (#7561)
* error message for when trying to await something that is not a promise * changelog * format
1 parent b9e2059 commit 1850fe5

File tree

5 files changed

+59
-1
lines changed

5 files changed

+59
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
1313
# 12.0.0-alpha.15 (Unreleased)
1414

15+
#### :nail_care: Polish
16+
17+
- Better error message for when trying to await something that is not a promise. https://github.com/rescript-lang/rescript/pull/7561
18+
1519
# 12.0.0-alpha.14
1620

1721
#### :boom: Breaking Change

compiler/ml/ast_await.ml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,25 @@ let create_await_expression (e : Parsetree.expression) =
99
in
1010
Ast_helper.Exp.apply ~loc unsafe_await [(Nolabel, e)]
1111

12+
let is_await_expr (e : Parsetree.expression) =
13+
match e with
14+
| {
15+
pexp_loc = {loc_ghost = true};
16+
pexp_desc =
17+
Pexp_apply
18+
{
19+
funct =
20+
{
21+
pexp_loc = {loc_ghost = true};
22+
pexp_desc = Pexp_ident {txt = Ldot (Lident ident, "unsafe_await")};
23+
};
24+
args = [(Nolabel, _)];
25+
};
26+
}
27+
when ident = Primitive_modules.promise ->
28+
true
29+
| _ -> false
30+
1231
(* Transform `@res.await M` to unpack(@res.await Js.import(module(M: __M0__))) *)
1332
let create_await_module_expression ~module_type_lid (e : Parsetree.module_expr)
1433
=

compiler/ml/error_message_utils.ml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ type type_clash_context =
102102
| FunctionArgument of {optional: bool; name: string option}
103103
| Statement of type_clash_statement
104104
| ForLoopCondition
105+
| Await
105106
106107
let context_to_string = function
107108
| Some WhileCondition -> "WhileCondition"
@@ -120,6 +121,7 @@ let context_to_string = function
120121
| Some (FunctionArgument _) -> "FunctionArgument"
121122
| Some ComparisonOperator -> "ComparisonOperator"
122123
| Some IfReturn -> "IfReturn"
124+
| Some Await -> "Await"
123125
| None -> "None"
124126
125127
let fprintf = Format.fprintf
@@ -185,6 +187,10 @@ let error_expected_type_text ppf type_clash_context =
185187
"But it's being used with the @{<info>%s@} operator, which works on:"
186188
operator
187189
| Some StringConcat -> fprintf ppf "But string concatenation is expecting:"
190+
| Some Await ->
191+
fprintf ppf
192+
"But you're using @{<info>await@} on this expression, so it is expected \
193+
to be of type:"
188194
| Some MaybeUnwrapOption | None ->
189195
fprintf ppf "But it's expected to have type:"
190196
@@ -282,6 +288,14 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
282288
"\n\n\
283289
\ To fix this, change the highlighted code so it evaluates to a \
284290
@{<info>bool@}."
291+
| Some Await, _ ->
292+
fprintf ppf
293+
"\n\n\
294+
\ You're trying to await something that is not a promise.\n\n\
295+
Possible solutions:\n\
296+
\ - Remove the @{<info>await@} if this is not expected to be a promise\n\
297+
\ - Wrap the expression in @{<info>Promise.resolve@} to convert the \
298+
expression to a promise"
285299
| Some IfReturn, _ ->
286300
fprintf ppf
287301
"\n\n\
@@ -533,7 +547,7 @@ let type_clash_context_from_function sexp sfunct =
533547
Some (MathOperator {for_float = true; operator; is_constant})
534548
| Pexp_ident {txt = Lident (("/" | "*" | "+" | "-") as operator)} ->
535549
Some (MathOperator {for_float = false; operator; is_constant})
536-
| _ -> None
550+
| _ -> if Ast_await.is_await_expr sexp then Some Await else None
537551
538552
let type_clash_context_for_function_argument ~label type_clash_context sarg0 =
539553
match type_clash_context with
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/awaiting_non_promise.res:3:15
4+
5+
1 │ let x = 1
6+
2 │
7+
3 │ let f = await x
8+
4 │
9+
10+
This has type: int
11+
But you're using await on this expression, so it is expected to be of type:
12+
promise<'a>
13+
14+
You're trying to await something that is not a promise.
15+
16+
Possible solutions:
17+
- Remove the await if this is not expected to be a promise
18+
- Wrap the expression in Promise.resolve to convert the expression to a promise
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
let x = 1
2+
3+
let f = await x

0 commit comments

Comments
 (0)