Semantic Diff

#9009 Compare the @as tags of variant cases with payloads across signatures

1 commit

d8db3c6ebb93d50ae095b58c670b79cd388988b4..pr-9009

ed8d4a46c · cknitt + Claude · Oct 24, 2026, 06:14 UTC

Compare the @as tags of variant cases with payloads across signatures

Why

Interface inclusion compared the @as literal of nullary cases only. An implementation could swap the tags of two cases with payloads, and its clients then matched M.A(_) as C (#8956).

The tags of tagged cases with a payload are compared as those of nullary cases are. An untagged case's @as does not change its representation and is not compared. Type declarations in messages now print the @as of a tagged case with a payload too, so the mismatch shows.

addedDiagnostic

module M: {  type t = A({x: int}) | C({x: int})} = {  type t = | @as("C") A({x: int}) | @as("A") C({x: int})}
diagnostic
After
Type declarations do not match:  type t = @as("C") A({x: int}) | @as("A") C({x: int})is not included in  type t = A({x: int}) | C({x: int})The internal representations for case A are not equal.