rescript-lang / rescript

ReScript is a robustly typed language that compiles to efficient and human-readable JavaScript.
https://rescript-lang.org
Other
6.77k stars 453 forks source link

Polymorphic variant coercion to string: add warning/docs. #6903

Open remitbri opened 4 months ago

remitbri commented 4 months ago

Hi

ReScript version: v11.x.x

When using plain variants with an @as, coercing to string produces the expected result. E.g

type plain = 
  | Foo 
  | @as("js") ReScript
let plainToJs = (x: plain) => (x :> string)
let plainOk = plainToJs(ReScript) // "js"

When using polymorphic variants with an @as, coercing to string produces an unexpected result

type poly = [#foo | @as("js") #rescript]
let polyToJs1 = (x: poly) => (x :> string)
let poly1NotOk = polyToJs1(#rescript) // "rescript" 

I'm not sure whether this is expected or if I'm supposed to write

let polyToJs2 = (x: poly) =>
  switch x {
  | #rescript => "js"
  | _ => (x :> string)
  }

Playground here

cristianoc commented 4 months ago

There's no as support in poly variants, because they are inferred, and the declaration can't be a source of truth.

DZakh commented 4 months ago

I also remember struggling with assuming that polymorphic variants support @as. Maybe there should be a compiler error when trying to apply as to a polymorphic variant instead of silently ignoring the attribute.

cristianoc commented 4 months ago

Yes adding at least a warning would be good.

cknitt commented 4 months ago

The compiler already has a mechanism for detecting unused attributes. However, it got broken when moving from @bs.xxx to @xxx.

We already fixed that on master. So in ReScript 12, unused @as will be detected. ReScript 11, unfortunately, only detects unused @bs.as (see Playground).