Refactor wild card renaming
Imported from #9922 (closed), comment #5 (closed):
Austin: let's merge this to 7.10.1.
Thomas: I'm not very happy with the way that wild-card error reporting is done. I think we discussed this before, but left it on one side until it was all working. Which it now is. What I suggest is this:
Things I dislike:
- I dislike the
checkParitalTypeSignatureandcheckNoPartialTypestuff inRdrHsSyn. The only checks that belong inRdrHsSymare ones that prevent you building a syntax tree at all. All other checks are best done later, when good error reporting is easier, and you can recover from errors. - I particularly hate the
RnTypes.extractWildcardsstuff. It's like a whole extra renaming pass over the type, changingHsWildCardTytoHsNamedWildCardTywith anExactRdrNamein it. Yuk!
Here is a possible plan:
-
Remove all the checking from
RdrHsSyn, unless we can't build a syntax tree without it. -
Collapse
HsWildcardTyandHsNamedWildcardTyinto one, with a boolean (or aNamed/Anonymousflag) to distinguish. -
Provide a specialised version of
rnLHsType, perhpasrnLHsTypeWithWildCards, that does the inital pass to find the named wildcards and bring them into scope. This version is called in the places where you can have a type with wildcards, namely*
TypeSig*
ExprWithTySig*
rnHsBndrSig -
rnLHsTypeWithWildCardscan work like this:-
Collect all the named wildcards, and bring them into scope. This is a simple, pure function.
-
Call
rnLHsType. WhenrnLHsTypefinds an anonymous wildcard, just make up a fresh name, rather than looking it up. -
Collect all the wildcards (named or anonymous) to get a
[Name]; again a pure function -
Return the renamed type and the wildcard names
That makes three passes, but each is simple. In fact (1) and (4) could perhaps be the same function, with a boolean flag to say which wildcards to return.
-
-
All this means that when
rnLHsTypeis called directly (not viarnLHsTypeWithWildCards) on a type like_ -> Int, it will succeed, generateing a fresh name for the_. That's fine. Intc_hs_typewe will find it is not in scope, so we can say "Unexpected wildcard in type", and the enclosing location information will nail down the details. -
There are, I think, three places where
HsWithBndrsis used:HsDecls.HsTyPats,HsDecls.RuleBndr,HsPat.SigPatIn. In the latter two I think that wildcards should be legal; in the first not so. (Do you have tests for all three?) So the caller ofrnHsBndrSigshould check for empty wildcards in the cases where there shouldn't be any. I this this is just in type/data family patterns.
I have not throught throught the extra-constraints wild card, but I think a similar plan should work.
Does this make sense? Might you do it? (To HEAD, of course.)
Thanks
Simon
Trac metadata
| Trac field | Value |
|---|---|
| Version | 7.11 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonpj |
| Operating system | |
| Architecture |