-
Notifications
You must be signed in to change notification settings - Fork 455
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
Fix super error mishandling uncurried function #6694
Fix super error mishandling uncurried function #6694
Conversation
This value might need to be [1;33mwrapped in a function that takes an extra | ||
parameter[0m of type unit | ||
|
||
[1;33mHere's the original error message[0m | ||
This has type: [1;31moption<'a>[0m | ||
But it's expected to have type: [1;33m(. unit) => option<int>[0m |
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 now matches the super error that was outputted when a curried function was defined
let typeIsUncurriedFun = Ast_uncurried_utils.typeIsUncurriedFun | ||
|
||
let typeExtractUncurriedFun (typ : Parsetree.core_type) = | ||
let coreTypeExtractUncurriedFun (typ : Parsetree.core_type) = |
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.
Renamed from typeExtractUncurriedFun coreTypeExtractUncurriedFun to follow naming convention in this file. I I have redefined typeExtractUncurriedFun below. (coreTypeIsUncurriedFun is named above fore the same paramater type, and for functions with Types.type_expr as a param use typeIsUncurredFun and typeExtractUncurriedFun respectively)
&& Path.same expectedPath Predef.path_option = false | ||
&& Path.same expectedPath Predef.path_uncurried = false -> |
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.
Here was another gremlin I came across where you get a suggestion to unwrap your option. For the example in the tests/descriptioon you get:
This value might need to be wrapped in a function that takes an extra
parameter of type unit
Here's the original error message
This has type: option<'a>
But it's expected to have type: (. unit) => option<int>
Possible solutions:
- Unwrap the option to its underlying value using `yourValue->Belt.Option.getWithDefault(someDefaultValue)`
Where the possible solution is not meant to be for functions but uncurried functions still pattern match on this case.
(p0, p, {type_kind=Type_variant cstrs}) | ||
when not (Ast_uncurried.typeIsUncurriedFun ty) | ||
-> (p0, p, cstrs) |
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 was the first issue, leading to the initial bad super error being displayed. The uncurried function type would extract as a concrete variant since it matched this case when it should not.
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.
I'm sure you've read and know more about this, but instead of throwing an exception with Not_found if uncurried, what about an implementation that extracts the uncurried case? Something like this.
if Ast_uncurried_utils.typeIsUncurriedFun ty then
extract_concrete_variant env (Ast_uncurried.typeExtractUncurriedFun ty)
else (p0, p, cstrs)
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.
Hey @mununki thanks for the comment! Yes I think that feel a lot nicer except that in practice it would make no difference to this function since if it is an uncurried function the extracted type would not be Type_variant? So happy to add the refactor to make it more future proof but otherwise it should never hit a case where it is an uncurried function and it can extract a concrete variant
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.
Sorry for my misunderstanding, if so why do we need that when clause by then?
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.
Sorry for my misunderstanding, if so why do we need that when clause by then?
It's because an uncurried function is represented by this pattern
Tconstr (Pident {name = "function$"}, [tArg; _], _)
where tArg is the underlying type of Tarrow
So when trying to extract the concrete type as a variant, it matches the case of Tconstr, but is not actually variant it's essentially just a wrapper around the underlying function. So we get a false positive.
jscomp/ml/typecore.ml
Outdated
| t when Ast_uncurried_utils.typeIsUncurriedFun t -> | ||
let typ = Ast_uncurried.typeExtractUncurriedFun t in | ||
collect_missing_arguments env typ type2 |
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 was the second issue where it should have given the suggestion:
This value might need to be wrapped in a function that takes an extra
parameter of type unit
Here's the original error message
This has type: option<'a>
But it's expected to have type: (. unit) => option<int>
it only outputted
This has type: option<'a>
But it's expected to have type: (. unit) => option<int>
since it would not match on the cases which treat it as a function. We first need to extract the type of the uncurried function.
889c2d8
to
2b74747
Compare
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.
Thanks for the fix. This looks great!
Looks like something went off when updating the changelog.
0a38ecf
to
6b9d9dc
Compare
Thanks @cristianoc, I think there was an issue when I rebased on GH and then added another commit locally. I've fixed up the commit rebased and pushed. |
@JonoPrest impressive work, well done! 😄 |
Closes #6662
Super errors were not handling uncurried functions properly.
outputted:
whereas it should have outputted
There were a number of place where uncurried functions were not being handled here and I suspect there's a number of gremlins still around.