Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit15b1855

Browse files
committed
more work on error messages
1 parent6ddf320 commit15b1855

File tree

6 files changed

+128
-9
lines changed

6 files changed

+128
-9
lines changed

‎compiler/ml/error_message_utils.ml‎

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,7 @@ let error_expected_type_text ppf type_clash_context =
166166
fprintf ppf"But it's being compared to something of type:"
167167
|SomeSwitchReturn -> fprintf ppf"But this switch is expected to return:"
168168
|SomeLetUnwrapReturn ->
169-
fprintf ppf
170-
"But this @{<info>let?@} is used in a context expecting the type:"
169+
fprintf ppf"But this @{<info>let?@} is used where this type is expected:"
171170
|SomeTryReturn -> fprintf ppf"But this try/catch is expected to return:"
172171
|SomeWhileCondition ->
173172
fprintf ppf"But a @{<info>while@} loop condition must always be of type:"
@@ -319,11 +318,65 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
319318
"\n\n\
320319
\ All branches in a @{<info>switch@} must return the same type.@,\
321320
To fix this, change your branch to return the expected type."
322-
|SomeLetUnwrapReturn,_ ->
323-
fprintf ppf
324-
"\n\n\
325-
\ @{<info>let?@} can only be used in a context that expects \
326-
@{<info>option@} or @{<info>result@}."
321+
|SomeLetUnwrapReturn,bottom_aliases -> (
322+
let kind=
323+
match bottom_aliaseswith
324+
|Some ({Types.desc=Tconstr (p, _, _)}, _)
325+
whenPath.same pPredef.path_option ->
326+
`Option
327+
|Some (_, {Types.desc=Tconstr (p, _, _)})
328+
whenPath.same pPredef.path_option ->
329+
`Option
330+
|Some ({Types.desc=Tconstr (p, _, _)}, _)
331+
whenPath.same pPredef.path_result ->
332+
`Result
333+
|Some (_, {Types.desc=Tconstr (p, _, _)})
334+
whenPath.same pPredef.path_result ->
335+
`Result
336+
|_ ->`Unknown
337+
in
338+
match kindwith
339+
|`Option ->
340+
fprintf ppf
341+
"\n\n\
342+
\ This @{<info>let?@} unwraps an @{<info>option@}; use it where the \
343+
enclosing function or let binding returns an @{<info>option@} so \
344+
@{<info>None@} can propagate.\n\n\
345+
\ Possible solutions:\n\
346+
\ - Change the enclosing function or let binding to return \
347+
@{<info>option<'t>@} and use @{<info>Some@} for success; \
348+
@{<info>let?@} will propagate @{<info>None@}.\n\
349+
\ - Replace @{<info>let?@} with a @{<info>switch@} and handle the \
350+
@{<info>None@} case explicitly.\n\
351+
\ - If you want a default value instead of early return, unwrap using \
352+
@{<info>Option.getOr(default)@}."
353+
|`Result ->
354+
fprintf ppf
355+
"\n\n\
356+
\ This @{<info>let?@} unwraps a @{<info>result@}; use it where the \
357+
enclosing function or let binding returns a @{<info>result@} so \
358+
@{<info>Error@} can propagate.\n\n\
359+
\ Possible solutions:\n\
360+
\ - Change the enclosing function or let binding to return \
361+
@{<info>result<'ok, 'error>@}; use @{<info>Ok@} for success, and \
362+
@{<info>let?@} will propagate @{<info>Error@}.\n\
363+
\ - Replace @{<info>let?@} with a @{<info>switch@} and handle the \
364+
@{<info>Error@} case explicitly.\n\
365+
\ - If you want a default value instead of early return, unwrap using \
366+
@{<info>Result.getOr(default)@}."
367+
|`Unknown ->
368+
fprintf ppf
369+
"\n\n\
370+
\ @{<info>let?@} can only be used in a context that expects \
371+
@{<info>option@} or @{<info>result@}.\n\n\
372+
\ Possible solutions:\n\
373+
\ - Change the enclosing function or let binding to return an \
374+
@{<info>option<'t>@} or @{<info>result<'ok, 'error>@} and propagate \
375+
with @{<info>Some/Ok@}.\n\
376+
\ - Replace @{<info>let?@} with a @{<info>switch@} and handle the \
377+
@{<info>None/Error@} case explicitly.\n\
378+
\ - If you want a default value instead of early return, unwrap using \
379+
@{<info>Option.getOr(default)@} or @{<info>Result.getOr(default)@}.")
327380
|SomeTryReturn,_ ->
328381
fprintf ppf
329382
"\n\n\

‎tests/build_tests/super_errors/expected/let_unwrap_return_type_mismatch.res.expected‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
8 │ }
1010

1111
This has type: option<'a>
12-
But this let? is usedin a context expecting the type: int
12+
But this let? is usedwhere this type is expected: int
1313

14-
let? can only be used in a context that expects option or result.
14+
This let? unwraps an option; use it where the enclosing function or let binding returns an option so None can propagate.
15+
16+
Possible solutions:
17+
- Change the enclosing function or let binding to return option<'t> and use Some for success; let? will propagate None.
18+
- Replace let? with a switch and handle the None case explicitly.
19+
- If you want a default value instead of early return, unwrap using Option.getOr(default).
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/let_unwrap_return_type_mismatch_block.res:10:12-18
4+
5+
8 ┆ 1
6+
9 ┆ } else {
7+
10 ┆ let? Some(x) = None
8+
11 ┆ Some(x)
9+
12 ┆ }
10+
11+
This has type: option<'a>
12+
But this let? is used where this type is expected: int
13+
14+
This let? unwraps an option; use it where the enclosing function or let binding returns an option so None can propagate.
15+
16+
Possible solutions:
17+
- Change the enclosing function or let binding to return option<'t> and use Some for success; let? will propagate None.
18+
- Replace let? with a switch and handle the None case explicitly.
19+
- If you want a default value instead of early return, unwrap using Option.getOr(default).
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/let_unwrap_return_type_mismatch_result.res:6:8-12
4+
5+
4 │
6+
5 │ let fn = (): int => {
7+
6 │ let? Ok(v) = Error("fail")
8+
7 │ 42
9+
8 │ }
10+
11+
This has type: result<'a, string>
12+
But this let? is used where this type is expected: int
13+
14+
This let? unwraps a result; use it where the enclosing function or let binding returns a result so Error can propagate.
15+
16+
Possible solutions:
17+
- Change the enclosing function or let binding to return result<'ok, 'error>; use Ok for success, and let? will propagate Error.
18+
- Replace let? with a switch and handle the Error case explicitly.
19+
- If you want a default value instead of early return, unwrap using Result.getOr(default).
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@@config({flags: ["-enable-experimental","LetUnwrap"]})
2+
3+
letx=Some(1)
4+
5+
letfn= ():int=> {
6+
letx= {
7+
if1 >2 {
8+
1
9+
}else {
10+
let?Some(x)=None
11+
Some(x)
12+
}
13+
}
14+
42
15+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@@config({flags: ["-enable-experimental","LetUnwrap"]})
2+
3+
letx=Ok(1)
4+
5+
letfn= ():int=> {
6+
let?Ok(v)=Error("fail")
7+
42
8+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp