Skip to content

Uncurried breaks @obj when used with @as #6517

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

Closed
TheSpyder opened this issue Dec 8, 2023 · 0 comments · Fixed by #6527
Closed

Uncurried breaks @obj when used with @as #6517

TheSpyder opened this issue Dec 8, 2023 · 0 comments · Fixed by #6527

Comments

@TheSpyder
Copy link
Contributor

TheSpyder commented Dec 8, 2023

One of the features of the @as decorator in externals is it can inject and erase function arguments, filling them with a value. This leads to an interesting (but niche) side-effect, where using @as within an @obj decorator allows object properties to be erased and filled with a value. Or at least it used to; uncurried mode breaks this.

One of the libraries I work on makes use of the technique, to model a NodeJS API that changes type based on a config option. The details are a bit complicated so I built a simplified playground example.

Change that to v11 and it prints a very strange error where more arguments are "required" than the type it prints:

This uncurried function has type
    (
  ~read: (t, ~size: Js.nullable<int>) => unit,
  ~autoDestroy: bool=?,
  unit,
) => configObj
  It is applied with 2 arguments but it requires 4.

It seems that while @as does still inject the argument, in uncurried mode it fails to completely erase it. A further effect of this is to break optional argument handling (when this first happened I thought uncurried @obj no longer supported optional arguments).

Further discussion on the forum
https://forum.rescript-lang.org/t/the-big-migration-thread-for-rescript-v11-and-uncurried-mode/4769/37?u=spyder

cristianoc added a commit that referenced this issue Dec 13, 2023
Examples like this:
```
@obj
external makeOptions: (
  ~objectMode: @as(json`false`) _,
  ~name: string,
  unit,
) => int = ""
```

change the arity of the function.
The arity of uncurried functions is determined at parsing type.
This means that this peculiarity of externals affects parsing.
This PR gives an approximate workaround based on the labelled arg having `@as`, and the type being `_` (the any type).

Fixes #6517
cristianoc added a commit that referenced this issue Dec 14, 2023
* Workaround for `@as`in labels in uncurried externals.

Examples like this:
```
@obj
external makeOptions: (
  ~objectMode: @as(json`false`) _,
  ~name: string,
  unit,
) => int = ""
```

change the arity of the function.
The arity of uncurried functions is determined at parsing type.
This means that this peculiarity of externals affects parsing.
This PR gives an approximate workaround based on the labelled arg having `@as`, and the type being `_` (the any type).

Fixes #6517

* Example with 2 default args.

* Add example outside externals, which should not fail.

* Restrict workaround to only fire inside an external.
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 a pull request may close this issue.

1 participant