-
Notifications
You must be signed in to change notification settings - Fork 468
Pipe expression for optional record fields expects non-optional type #5627
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
Comments
Do you have a repro that does not use the |
Possibly related? rescript-lang/syntax#203 |
Maybe? #5585 |
Tried on master and this issue is still there. |
Here’s some extra cases. Not sure if you meant that for repro: type t = {
optValue?: int,
explicit: option<int>,
}
let x = Some(3)
let s1 = {explicit: (x->Belt.Option.map(a => a+1))} // <-- No error
let s2 = {explicit: None, optValue: @optional (x->Belt.Option.map(a => a+1))} // <-- Error
I thought about it, but arguably no. I’ve put parens around the expression to exclude |
Let's see what the parser does. Input: type t = {optValue?: int}
let x = Some(3)
let s1 = {optValue: ? (x->Belt.Option.map(a => a + 1)) } // <-- Type error
let s2 = {optValue: ? (Belt.Option.map(x, a => a + 1))} Result: type nonrec t = {
optValue: int [@ns.optional ]}
let x = Some 3
let s1 = { optValue = ((x |. (Belt.Option.map (fun a -> a + 1)))[@ns.optional ]) }
let s2 = { optValue = ((Belt.Option.map x (fun a -> a + 1))[@ns.optional ]) } |
That looks fine. It seems likely, the annotation is moved around during the processing of pipe in the compiler. |
Let's do a formatting test now. This: let s1 = {optValue: @foo (x->Belt.Option.map(a => a + 1))}
let s2 = {optValue: @foo (Belt.Option.map(x, a => a + 1))} Gets formatted to: let s1 = {optValue: x->Belt.Option.map(a => a + 1)}
let s2 = {optValue: @foo Belt.Option.map(x, a => a + 1)} so the annotation is eaten up in the first case |
So it seems that the situation is:
Next up: investigate the reformatting issue. |
The formatting issue affects |
This works fine: let s1 = {optValue: ?((a => a+1) |> Belt.Option.map(x))} bringing more credibility to the red herring hypothesis. |
No I didn't. |
@cristianoc Sorry to bother you here, but this is still not valid: price: ?variant.price.amount->Float.fromString
// instead I need to do
price: ?Float.fromString(variant.price.amount) Is the first line supposed to work? |
Can you give a self-contained example, e.g. a link to the playground. |
My fault, the version of ReScript I looked at was 10.0.0. 🤦🏻♂️ My apologies... |
Experimenting with Playground. The following compiles with an error:
Screenshot:
So, the pipe expression highlighted has indeed type
option<int>
but the compiler wants a plainint
for some reason.Interesting, the same expression without the pipe compiles just fine.
The text was updated successfully, but these errors were encountered: