Check role declarations arity during type checking#4157
Conversation
|
I wonder, would it be simpler to position the role declarations after the data types in desugaring, insert the inferred roles into the environment when the type declaration is checked, and then update the environment when checking the role declaration for arity and mismatches? Then we wouldn't have to do as much fiddling with source spans and error hints; any issues with the role declaration would naturally arise while processing said declaration. |
3d2134d to
c66ae6d
Compare
|
|
||
| in role declaration for [33mIdentity[0m | ||
| in type constructor [33mIdentity[0m | ||
| in data binding group Identity |
There was a problem hiding this comment.
Having foreign data type declarations depend on their role declaration in the binding group desugaring step would complicate self cycles detection, but this leaks in error messages since we do display that role declarations of data types belong to a binding group here. Is there a reason for not eliminating the hint for singleton binding groups?
There was a problem hiding this comment.
I might even go further and suggest that it should be eliminated whenever another hint narrows down the error to one declaration. Maybe there should be a hint category for top-level declarations or something?
There was a problem hiding this comment.
I introduced a category for declaration hints.
|
I applied your suggestion. This was slightly more involved than expected because we need to know all the role declarations of data binding groups when inferring roles of mutually recursive data types, but it is nice to remove declared roles from the environment and to position RoleMismatch errors accurately! |
|
This now has a merge conflict: |
…ations-arity-during-typechecking
|
CI builds again. Any other feedback on this PR? |
JordanMartinez
left a comment
There was a problem hiding this comment.
I think this is good to go aside from the one issue raised below.
| -> m () | ||
| checkRoles tyArgs declaredRoles = do | ||
| let k (var, _, inf) dec = | ||
| when (inf < dec) . throwError . errorMessage $ RoleMismatch var inf dec |
There was a problem hiding this comment.
I think this error message could be improved to indicate which type parameter's role was wrong in a declaration with 2+ role annotations. For example, looking at this error message
... the source spans indicates the entire role declaration. They do not indicate which role declaration has the issue.
If I have the following example,
data Foo a b c d = Foo a b c
type role Foo representational phantom representational phantomand b is the one with the bad role, the error message wouldn't tell me which of the four values above is wrong.
There was a problem hiding this comment.
On second thought, the issue above is a separate issue. This PR AFAICT accomplishes its goal of checking for arity. I'll retract this.
Description of the change
As Jordan noticed in #4121 (comment) we incorrectly infer the arity of foreign data types whose kind contains parens (and type synonyms) while checking their role declaration arity. We ought to check role declarations arity during type checking, so that parens and type synonyms are desugared away.
Checklist:
Added myself to CONTRIBUTORS.md (if this is my first contribution)Linked any existing issues or proposals that this pull request should closeUpdated or added relevant documentation