Semantic Diff

#9118 Fix coercion hint for parenthesized operands and aliased target types

1 commit

85f31fbb15ef96bd168d6e99055ad4808810d6e0..pr-9118

dfe3118e2 · cknitt + Claude · Oct 28, 2026, 15:49 UTC

Suggest a coercion only for an operand that parses and name the shown 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.

modifiedDiagnostic 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)
diagnostic
Before
After
- 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: :>

modifiedDiagnostic coercion target

let f = (x: Generator.t<'a, unit, unit>): Iterable.t<'a> => x
diagnostic
Before
After
But it's expected to have type: Iterable.t<'a> (defined as iterable<'a>)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

  • 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.