Repository navigation
Commit 6612b69
Type a let destructuring a GADT without switch diagnostics
Why:
A `let` whose pattern contains a GADT constructor is typed as a
one-case match, and that match took the diagnostic context of a
`switch` in the source: a type error in the rest of the block said
"But this switch is expected to return" and added the hint about
switch branches, although the source has no switch. The match now
carries `#let_gadt_pattern`, and its cases, like those of the match
for an optional argument default, get function-style diagnostics.
Typedtree modified (let destructuring a GADT constructor):
Example:
type rec any = Any('a, 'a => string): any
let get = value => {
let Any(x, f) = value
f(x)
}
Before (typed):
expression
Texp_match
expression
Texp_ident "value/1004"
[
<case>
pattern
Tpat_construct "Any"
…
expression
Texp_apply
…
]
After (typed):
expression
attribute "#let_gadt_pattern"
[]
Texp_match
expression
Texp_ident "value/1004"
[
<case>
pattern
Tpat_construct "Any"
…
expression
Texp_apply
…
]
Decision modified (diagnostic context of a match's cases):
Before (text): `call_context` in `Typecore.type_expect_`
match with @let.unwrap ↦ LetUnwrap
match with #optional_arg_default ↦ Function
match typed for a let with a GADT pattern ↦ Switch
any other match ↦ Switch
After (text):
match with @let.unwrap ↦ LetUnwrap
match with #optional_arg_default ↦ Function
match with #let_gadt_pattern ↦ Function
any other match ↦ Switch
Diagnostic modified (type error in the body of a let destructuring a GADT):
Example:
type rec any = Any('a, 'a => string): any
let get = value => {
let Any(x, _) = value
x
}
Before (diagnostic):
This has type: $a
But this switch is expected to return: 'a
$a is an existential type bound by the constructor Any.
It is only known in the scope of the pattern that matches Any.
All branches in a switch must return the same type.
To fix this, change your branch to return the expected type.
After (diagnostic):
This has type: $a
But it's expected to have type: 'a
$a is an existential type bound by the constructor Any.
It is only known in the scope of the pattern that matches Any.
Fixes: #9069
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>1 parent 139986d commit 6612b69
4 files changed
Lines changed: 29 additions & 3 deletions
File tree
- changes
- compiler/ml
- tests/build_tests/super_errors
- expected
- fixtures
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2644 | 2644 | | |
2645 | 2645 | | |
2646 | 2646 | | |
| 2647 | + | |
| 2648 | + | |
2647 | 2649 | | |
2648 | 2650 | | |
2649 | 2651 | | |
| |||
2832 | 2834 | | |
2833 | 2835 | | |
2834 | 2836 | | |
2835 | | - | |
2836 | | - | |
| 2837 | + | |
| 2838 | + | |
| 2839 | + | |
| 2840 | + | |
2837 | 2841 | | |
2838 | | - | |
| 2842 | + | |
| 2843 | + | |
2839 | 2844 | | |
2840 | 2845 | | |
2841 | 2846 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
0 commit comments