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
checkParitalTypeSignature
andcheckNoPartialType
stuff inRdrHsSyn
. The only checks that belong inRdrHsSym
are 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.extractWildcards
stuff. It's like a whole extra renaming pass over the type, changingHsWildCardTy
toHsNamedWildCardTy
with anExact
RdrName
in it. Yuk!
Here is a possible plan:
-
Remove all the checking from
RdrHsSyn
, unless we can't build a syntax tree without it. -
Collapse
HsWildcardTy
andHsNamedWildcardTy
into one, with a boolean (or aNamed
/Anonymous
flag) 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
-
rnLHsTypeWithWildCards
can work like this:-
Collect all the named wildcards, and bring them into scope. This is a simple, pure function.
-
Call
rnLHsType
. WhenrnLHsType
finds 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
rnLHsType
is called directly (not viarnLHsTypeWithWildCards
) on a type like_ -> Int
, it will succeed, generateing a fresh name for the_
. That's fine. Intc_hs_type
we 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
HsWithBndrs
is 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 ofrnHsBndrSig
should 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 |