-
Notifications
You must be signed in to change notification settings - Fork 469
Fix issues with overlapping argument name and default value, using alias and default value together #5989
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
Conversation
, using alias with default value together
function make$1(_props) { | ||
while(true) { | ||
_props = {}; | ||
continue ; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why this js output diff has made after running make test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should not happen. Try make clean and make test again.
@@ -0,0 +1,18 @@ | |||
@@jsxConfig({version: 4}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add this under jscomp/test
instead? So it's compiler any time make lib
is run, and you get normal error messages instead of a failed build test.
It would look like this:
@@bs.config({
flags: ["-bs-jsx", "4"],
})
module C0 = {
@react.component
let make = (~a=2, ~b=a + 2) => {
React.int(a + b)
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me it gives "The module or file props can't be found.".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And same error if I write it in some other project that installs this version of the compiler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notice @@bs.config
, as @@jsxVersion
would not be picked up by a single bsc
invocation used to run tests.
let make = (props: props<'a, 'b>) => { | ||
let b = switch props.b { | ||
| Some(b) => b | ||
| None => a * 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you copy paste this, you'll get a a not found
.
The oder should be: first let a
then b
.
Also, it should not be let ... and
but let ... let
or it won't compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, a
should refer to the outside scope of make function. The original code is this:
@react.component
let make = (~a=2, ~b=a*2) => <div />
So, a
in (a* 2)
is referring to out of this make function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is quite tricky than I guess. It has to be affected by the order, but it should not.
let make = (props) => {
let a = 2 // 1
let b = a * 2 // <- a should be reference to the outside of make function, but it refers to 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We transform the optional labelled argument to nolabel argument props
. So there no where to handle the default value that is the root cause of this issue, I guess.
type props<'a, 'b> = {a?: 'a, b?: 'b} | ||
@react.component | ||
let make = (props: props<'a, 'b>) => { | ||
let b = switch props.b { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the error message I'm getting "The module or file props can't be found." this is probably a path A.foo
where A
happens to be props
and not a field access, which it should be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Field access is Pexp_field
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops! Correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments.
First, to move the test so you get normal user-level error messages.
Then the first error indicated props.b
is not done right.
Once that's fixed you should get "a not found".
Fixed now. |
module C0 = {
let a = 1 // 2
type props<'a, 'b> = {a?: 'a, b?: 'b}
let make = (props: props<'a, 'b>) => {
let b = switch props.b {
| Some(b) => b
| None => a * 2 // 1
}
and a = switch props.a {
| Some(a) => a
| None => 2
}
React.int(a + b)
}
let make = {
let \"DefaultValueProp$C0" = (props: props<_>) => make(props)
\"DefaultValueProp$C0"
}
} Due to the list of value bindings, module C0 = {
let a = 1 // 2
type props<'a, 'b> = {a?: 'a, b?: 'b}
let make = (props: props<'a, 'b>) => {
let a = switch props.a {
| Some(a) => a
| None => 2
}
and b = switch props.b {
| Some(b) => b
| None => a * 2 // 1
}
React.int(a + b)
}
let make = {
let \"DefaultValueProp$C0" = (props: props<_>) => make(props)
\"DefaultValueProp$C0"
}
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still does not apply the fix I was mentioning.
See how this compiles:
let foo = (~a=2, ~b=a * 2) => a + b
but this does not:
module C0 = {
@react.component
let make = (~a=2, ~b=a * 2) => {
React.int(a + b)
}
}
It's not true that a
comes from the outside. And the order does matter. First let a
then let b
.
That's how default args work.
Sorry, I didn't know how the default value works as same name of argument exactly before: let f = (~a=2, ~b=a*2, ()) => a + b
// vs.
let f = (~b=a*2, ~a=2, ()) => a + b // error: can't find a I fixed it edcf127 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great.
Added a couple of comments to the examples.
}) | ||
|
||
module C0 = { | ||
let a = 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove this line. as it's not needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it 6c0a0bb
@@ -0,0 +1,10 @@ | |||
module C0 = { | |||
let a = 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove this line, as it's not needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it 6c0a0bb
Now I understand that it is self-evident because it is curried.
|
This PR fixes #5977, #5979