Semantic Diff

#9125 Refuse coercing another type into a private record or variant

1 commit

799a82f05acda24ba672ceef431b2ac99b418995..pr-9125

052d3cca9 · cknitt + Claude · Oct 29, 2026, 10:11 UTC

Refuse coercing another type into a private record or variant

Why

A private type's values can only be built in the module that defines it, but structural coercion built them anywhere: a plain record, another module's private record with the same fields, a variant, a polymorphic variant or a string coerced into a private record or variant (#9124).

subtype_rec refuses a coercion whose target's definition is a private record or variant unless the source is that same type. Coercing out of a private type is unchanged.

modifiedTyping coercion into a private type

module Blob: { type t = private {size: float} } = { type t = {size: float} }type plain = {size: float}let fake = (p: plain) => (p :> Blob.t)
rule
Before a record coerces into a record with compatible fields,
private or not
After a record or variant coerces into a private record or variant
only from that same type

addedDiagnostic coercion into a private type

let fake = (p: plain) => (p :> Blob.t)
diagnostic
Before
After
none Type plain is not a subtype of Blob.tBlob.t is private: its values can only be built in the module thatdefines it, so another type cannot be coerced to it.