Skip to content

Hint about coercion in error msg #7505

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 23, 2025
Merged

Hint about coercion in error msg #7505

merged 5 commits into from
May 23, 2025

Conversation

zth
Copy link
Collaborator

@zth zth commented May 22, 2025

This is something I've been wanting to do for a long time - hint in error messages when types are subtypes, and because of that can be coerced to the appropriate type.

I think this is going to improve the discoverability of coercion a ton, by that improve its usability.

@tsnobip @cknitt a round of message feedback please.

@zth zth requested review from cknitt and tsnobip May 22, 2025 18:38
Copy link

pkg-pr-new bot commented May 22, 2025

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript-lang/rescript@7505

@rescript/darwin-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-x64@7505

@rescript/darwin-arm64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-arm64@7505

@rescript/linux-arm64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-arm64@7505

@rescript/linux-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-x64@7505

@rescript/win32-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/win32-x64@7505

commit: fb546a2

Copy link
Member

@cknitt cknitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff, not sure about the cases for literals though.

@@ -9,5 +9,11 @@
This has type: int
But it's expected to have type: float

Possible solutions:
- These types are compatible at runtime. You can use the coercion operator :> to convert to the expected type float.
If you want to use coercion, rewrite the highlighted code to: (2 :> float)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really a good suggestion for literals?

Wouldn't I want to write 2. + 2. rather than 2. + (2 :> float) to fix the error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we could ignore these cases, agreed. The int/float/string suggestions need a refactor as well now that we have new capabilities, but we can save that for later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow, the penny didn't yet drop for me that you can write:

let x = 4.
let y = 5
let z = x + (y :> float)

Really cool!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nojaf yeah coercion (especially in v12) opens up a ton of cool possibilities actually. One example is that you can (together with variant type spreads) easily create fully type driven decoders:

@unboxed
type someType = One | Two | Three | Four | Five

@unboxed
type someTypeStr = | ...someType | OtherString(string)

let someTypeFromString = (s: string) =>
  switch (s :> someTypeStr) {
  | ...someType as someType => Some(someType)
  | OtherString(_) => None
  }
function someTypeFromString(s) {
  if (s === "One" || s === "Five" || s === "Two" || s === "Four" || s === "Three") {
    return s;
  } 
}

Can easily just add new cases to someType and have them automatically accounted for. Works because of the unboxed variant version of someType that has the OtherString(string) case, which covers any string that isn't already covered by the rest of the constructors.

Playground: https://rescript-lang.org/try?version=v12.0.0-alpha.13&module=esmodule&code=AIVwdgRg9gHgpgEwFABcCeAHOACAzlAWzgBVMcBebAeTBwB9tiB3KbB4gCwCc57sAxKCC5sBASwBucJElCRYiVGTyESZAMooRlBgDp9+IqSyiqKDnC6auYsAHMAFLi227AShkAbOChVGy-FyE1q7YlE4AXHgu9m5hAHxI2HhMYigAxhzYTtgR8X5qWNZxAN5Jovq6hoU4AIa4BcYU+eqqTqpNHskMZhZWMY4A+nHk+QByULTlAL5IQA

Copy link
Member

@tsnobip tsnobip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great @zth!
I'd just simplify the wording a bit to have less repetitions and as @cknitt said, I'd remove it for int literals.
Thanks a lot!

Comment on lines 14 to 15
- These types are compatible at runtime. You can use the coercion operator :> to convert to the expected type string.
If you want to use coercion, rewrite the highlighted code to: (One :> string)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great! But I'd simplify the wording a bit, it feels a bit verbose:

Suggested change
- These types are compatible at runtime. You can use the coercion operator �[1;33m:>�[0m to convert to the expected type �[1;33mstring�[0m.
If you want to use coercion, rewrite the highlighted code to: �[1;33m(One :> string)
- These types are compatible at runtime. You can use the coercion operator to convert to the expected type with �[1;33m(One :> string)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tsnobip how would you simplify the wording? Can't see anything along those lines in the diff above.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see now.

@zth zth requested a review from tsnobip May 23, 2025 09:33
@zth
Copy link
Collaborator Author

zth commented May 23, 2025

@tsnobip look at the last commit please.

Copy link
Member

@tsnobip tsnobip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks perfect now @zth!

Comment on lines +14 to +15
- These types are compatible at runtime. You can use the coercion operator to convert to the expected type: (One :> string)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect!

@zth zth merged commit 01ee097 into master May 23, 2025
16 checks passed
@zth zth deleted the hint-coercion-in-error-msg branch May 23, 2025 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants