Refactor wild card renaming
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
RdrHsSyn. The only checks that belong in
RdrHsSymare 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, changing
RdrNamein it. Yuk!
Here is a possible plan:
Remove all the checking from
RdrHsSyn, unless we can't build a syntax tree without it.
HsNamedWildcardTyinto one, with a boolean (or a
Anonymousflag) to distinguish.
Provide a specialised version of
rnLHsTypeWithWildCards, 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
rnLHsTypeWithWildCardscan work like this:
Collect all the named wildcards, and bring them into scope. This is a simple, pure function.
rnLHsTypefinds 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 via
rnLHsTypeWithWildCards) on a type like
_ -> Int, it will succeed, generateing a fresh name for the
_. That's fine. In
tc_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
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 of
rnHsBndrSigshould 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.)