Repository navigation
Fix coercion hint for parenthesized operands and aliased target types - #9118
Conversation
Changelog🐛 Bug fix
Semantic Diff1 commit · Full page Suggest a coercion only for an operand that parses and name the shown typedfe3118 · cknitt + Claude · Oct 28, 2026, 15:49 UTC
Diagnostic modified (coercion hint) type a = {x: int, y: int}
type b = {x: int}
let v: a = {x: 1, y: 2}
let w: b = v->(r => r)
-- These types are compatible at runtime. You can use the coercion operator to convert to the expected type: v->(r => r :> b)
+- These types are compatible at runtime. You can use the coercion operator to convert to the expected type: :>Diagnostic modified (coercion target) let f = (x: Generator.t<'a, unit, unit>): Iterable.t<'a> => x
But it's expected to have type: Iterable.t<'a> (defined as iterable<'a>)
…
-You can use the coercion operator to convert to the expected type: (x :> iterable<'a>)
+You can use the coercion operator to convert to the expected type: (x :> Iterable.t<'a>)Review
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #9118 +/- ##
=======================================
Coverage 81.46% 81.47%
=======================================
Files 460 460
Lines 64675 64692 +17
=======================================
+ Hits 52689 52707 +18
+ Misses 11986 11985 -1
🚀 New features to boost your workflow:
|
rescript
@rescript/belt
@rescript/darwin-arm64
@rescript/linux-arm64
@rescript/linux-x64
@rescript/runtime
@rescript/win32-x64
commit: |
|
Developer playground preview: https://rescript-lang.github.io/rescript/dev-playground/?version=pr-9118 |
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
33823be to
8c8747d
Compare
… type
Why:
The coercion hint wrapped the source text at the expression's location,
which leaves out the parentheses around a first or last operand, so the
suggestion did not compile (#9105). It also named the expanded target
type instead of the one the message shows.
Diagnostic modified (coercion hint):
Example:
type a = {x: int, y: int}
type b = {x: int}
let v: a = {x: 1, y: 2}
let w: b = v->(r => r)
Before (diagnostic):
- These types are compatible at runtime. You can use the coercion operator to convert to the expected type: v->(r => r :> b)
After (diagnostic):
- These types are compatible at runtime. You can use the coercion operator to convert to the expected type: :>
Diagnostic modified (coercion target):
Example:
let f = (x: Generator.t<'a, unit, unit>): Iterable.t<'a> => x
Before (diagnostic):
But it's expected to have type: Iterable.t<'a> (defined as iterable<'a>)
…
You can use the coercion operator to convert to the expected type: (x :> iterable<'a>)
After (diagnostic):
But it's expected to have type: Iterable.t<'a> (defined as iterable<'a>)
…
You can use the coercion operator to convert to the expected type: (x :> Iterable.t<'a>)
Review: Why not widen the location to the parentheses? The parser leaves
them out of locations on purpose, for comment placement, so a hint that
cannot rebuild the operand falls back to the bare operator.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Signed-off-by: Christoph Knittel <[email protected]>
8c8747d to
dfe3118
Compare
cristianoc
left a comment
There was a problem hiding this comment.
Reviewed the clean-parse guard for extracted expressions, target-type alias selection and regression fixtures. No blocking issues found. CI, including super_errors and super_errors_multi, passes; validation was source review and CI, not a local rerun.
The "use the coercion operator" hint could suggest a rewrite that does not compile, and it named a different type than the error message right above it.
Suggestion after a parenthesized operand. The hint wraps the source text at the expression's location in
(… :> T). The parser leaves the parentheses around an expression's first or last operand out of its location, so forv->(r => r)the text wasv->(r => rand the suggestionv->(r => r :> b)does not type check. With parentheses on both ends, as in(c ? v : v)->(r => r), the cut-off text even parses again once wrapped. The hint now offers a concrete rewrite only when the text at the location parses by itself as one expression, and the hint parser hook rejects text that only parses with errors. Otherwise it falls back to the bare:>it already shows when no rewrite is available. Widening the location to the parentheses would give(v->(r => r) :> b), but the parser leaves them out on purpose (comment placement), and changing that would affect locations everywhere.Expanded target type. The target type came from the expanded half of the trace pair, so
Iterable.t<'a>was suggested asiterable<'a>. It now uses the unexpanded type, the one the message shows.New super_errors fixtures:
coercion_hint_cut_off_operand.res: an operand cut off at its parentheses on both ends,(true ? v : v)->(r => r). Its wrapped text(true ? v : v)->(r => r :> b)parses, so it also rules out checking only the wrapped suggestion; the issue'sv->(r => r)takes the same path.coercion_hint_names_alias.res: theGenerator.ttoIterable.tcase, which should suggestIterable.t<'a>.Both fail without the fix.
For a cut-off operand, the hint falls back to the bare
:>rather than rebuilding the full expression; widening the parser location over the adjacent parentheses would change locations everywhere, so this is not done.Fixes #9105
🤖 Generated with Claude Code
https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP