Check role declarations make sense#3881
Conversation
|
Thanks! I will review after the other roles PRs are merged. |
d407cbc to
5c9559d
Compare
|
The grouping code you have here feels like a bit of a code smell to me, since we're already doing grouping based on which declarations refer to each other in the BindingGroups desugaring step. It feels to me like these checks ought to be relatively easy to implement alongside the existing BindingGroups desugaring step:
so perhaps we should have all of the above in the BindingGroups step and only have the arity check in the type checker? I think if we were to go ahead and implement the first refactoring I discussed in #3910 (comment) that might simplify this code as well. Would you mind if I took a stab at that refactoring first? |
|
Sure, go ahead! |
|
I had a go at doing that refactoring and had some thoughts: The graph in the BindingGroups step is already very subtle in terms of what the vertices are and which vertices should depend on which, especially in the presence of kind declarations and type synonyms, and I think introducing roles into the mix as well is likely to make that code quite brittle and difficult to change. On reflection, the current approach of putting all the role declarations before any data declarations at the very end of the desugaring phase and then storing roles temporarily in the Environment when we encounter those role declarations during type checking isn't really all that bad. I think if I was going to try to refactor this to remove the need to put role declarations in the environment, then I'd modify the AST so that we can store role annotation data directly in the I also realised that the three checks for role declarations which I recommended adding to the BindingGroups step (must refer to a declaration in the same module, must refer to a data or foreign import data declaration, must not be duplicated) are really more analogous to the checks in the Sugar.TypeDeclarations step, which perform those same checks for type and kind signatures, so I think they would be best off going there. I think the simplest way of doing that would be to require that a role annotation directly follows the data type it describes, like how we require that type and kind signatures directly precede the declarations they describe. That does make things more restrictive than they are now, but I suspect most of the code which has been written already follows this rule, and I think it's a sensible rule to impose. |
b41a9e6 to
fd994c9
Compare
|
I moved the checks back to |
hdgarrood
left a comment
There was a problem hiding this comment.
Looks great, just a couple of grammar comments regarding one of the errors
src/Language/PureScript/Errors.hs
Outdated
| , markCode (runProperName name) | ||
| , "expects" | ||
| , T.pack (show expected) | ||
| , if expected > 1 then "arguments" else "argument" |
There was a problem hiding this comment.
When there are no arguments, the word "argument" should be pluralized, so I think the condition we want here is if expected == 1 then "argument" else "arguments"
src/Language/PureScript/Errors.hs
Outdated
| , "expects" | ||
| , T.pack (show expected) | ||
| , if expected > 1 then "arguments" else "argument" | ||
| , "but its role declaration list" |
There was a problem hiding this comment.
To make the verb "list" agree, it should be written "lists", so for example: "but its role declaration lists only 3 roles".
| , T.pack (show expected) | ||
| , if expected > 1 then "arguments" else "argument" | ||
| , "but its role declaration list" | ||
| <> if actual > expected then "" else " only" |
There was a problem hiding this comment.
Adding "only" when there are not enough roles is a nice touch 👍
There was a problem hiding this comment.
This is something I picked up from the ClassInstanceArityMismatch error ^^
fd994c9 to
d4819ed
Compare
|
I applied your suggestions. |
hdgarrood
left a comment
There was a problem hiding this comment.
Thanks! Just for future reference, would you mind pushing new commits and leaving the existing commits alone when responding to code review feedback? It makes it easier for reviewers to see what has changed since the last review. The commit history will be tidied up automatically by the "Squash and merge" button.
|
Sorry about that, I’m trying to get into the habit of pushing fixup commits instead. In the case of whole commits, do you prefer them to be removed from the history or reverted by new commits? |
|
No worries - it's not a big deal, so don't worry if you forget. I think pushing new commits which revert the old unwanted ones is preferable, as that makes it easier to see what changed since the last time you looked. |
This PR enforces the following checks:
I’m unsure about the locations of those checks. Should they be inI’ve moved those checks to the type checker.Language.PureScript.Sugar.RoleDeclarationsrather thanLanguage.PureScript.Sugar.TypeDeclarations? Role declarations are not desugared to anything though, so maybe they should be inLanguage.PureScript.TypeCheckerinstead?Close #3870 and close #3876.