Repository navigation
Commit 6ea63e5
Type a let destructuring a GADT without switch diagnostics (#9081)
* 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>
* Records show the changed operation before its consequences
The records skill asked for a block for each object a commit changes in
what the compiler does, and a record of #9081 met it with the diagnostic
alone, leaving the attribute the type checker adds to the synthesized
match in prose. A record now shows the representation, rule,
transformation or decision that changes, at its own level, and then its
consequences; a change the prose names is shown in a block, a change no
form prints is shown as a schematic, and a script or review fix that
changes behaviour gets blocks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
---------
Signed-off-by: Christoph Knittel <ck@cca.io>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>1 parent 9c4de0a commit 6ea63e5
5 files changed
Lines changed: 55 additions & 7 deletions
File tree
- .agents/skills/records
- changes
- compiler/ml
- tests/build_tests/super_errors
- expected
- fixtures
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
177 | 177 | | |
178 | 178 | | |
179 | 179 | | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
184 | 206 | | |
185 | 207 | | |
186 | 208 | | |
| |||
| 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