diff options
author | Thomas Winant <thomas.winant@cs.kuleuven.be> | 2015-07-20 15:43:53 +0200 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2015-07-20 16:43:34 +0200 |
commit | 49373ffe4cbc87b46468d2372e850138e151a9ae (patch) | |
tree | c5b5f74bc06eb924b4d75f10b370a3b3e49a972b /compiler/deSugar/DsMeta.hs | |
parent | 82ffc80df573512f788524c4616db3c08fc9f125 (diff) | |
download | haskell-49373ffe4cbc87b46468d2372e850138e151a9ae.tar.gz |
Support wild cards in TH splices
- Declaration splices: partial type signatures are fully supported in TH
declaration splices.
For example, the wild cards in the example below will unify with `Eq
a`
and `a -> a -> Bool`, as expected:
```
[d| foo :: _ => _
foo x y = x == y |]
```
- Expression splices: anonymous and named wild cards are supported in
expression signatures, but extra-constraints wild cards aren't. Just
as is the case for regular expression signatures.
```
[e | Just True :: _a _ |]
```
- Typed expression splices: the same wildcards as in (untyped)
expression splices are supported.
- Pattern splices: TH doesn't support type signatures in pattern
splices, consequently, partial type signatures aren't supported
either.
- Type splices: partial type signatures are only partially supported in
type splices, specifically: only anonymous wild cards are allowed.
So `[t| _ |]`, `[t| _ -> Maybe _ |]` will work, but `[t| _ => _ |]` or
`[| _a |]` won't (without `-XNamedWildCards`, the latter will work as
the named wild card is treated as a type variable).
Normally, named wild cards are collected before renaming a (partial)
type signature. However, TH type splices are run during renaming, i.e.
after the initial traversal, leading to out of scope errors for named
wild cards. We can't just extend the initial traversal to collect the
named wild cards in TH type splices, as we'd need to expand them,
which is supposed to happen only once, during renaming.
Similarly, the extra-constraints wild card is handled right before
renaming too, and is therefore also not supported in a TH type splice.
Another reason not to support extra-constraints wild cards in TH type
splices is that a single signature can contain many TH type splices,
whereas it mustn't contain more than one extra-constraints wild card.
Enforcing would this be hard the way things are currently organised.
Anonymous wild cards pose no problem, because they start without names
and are given names during renaming. These names are collected right
after renaming. The names generated for anonymous wild cards in TH
type splices will thus be collected as well.
With a more invasive refactoring of the renaming, partial type
signatures could be fully supported in TH type splices. As only
anonymous wild cards have been requested so far, these small changes
satisfying this request will do for now. Also don't forget that a TH
declaration splices support all kinds of wild cards.
- Extra-constraints wild cards were silently ignored in expression and
pattern signatures, appropriate error messages are now generated.
Test Plan: run new tests
Reviewers: austin, goldfire, adamgundry, bgamari
Reviewed By: goldfire, adamgundry, bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D1048
GHC Trac Issues: #10094, #10548
Diffstat (limited to 'compiler/deSugar/DsMeta.hs')
-rw-r--r-- | compiler/deSugar/DsMeta.hs | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs index b9805ac58b..d9dc02f82b 100644 --- a/compiler/deSugar/DsMeta.hs +++ b/compiler/deSugar/DsMeta.hs @@ -847,11 +847,26 @@ repLTy :: LHsType Name -> DsM (Core TH.TypeQ) repLTy (L _ ty) = repTy ty repTy :: HsType Name -> DsM (Core TH.TypeQ) -repTy (HsForAllTy _ _ tvs ctxt ty) = +repTy (HsForAllTy _ extra tvs ctxt ty) = addTyVarBinds tvs $ \bndrs -> do - ctxt1 <- repLContext ctxt + ctxt1 <- repLContext ctxt' ty1 <- repLTy ty repTForall bndrs ctxt1 ty1 + where + -- If extra is not Nothing, an extra-constraints wild card was removed + -- (just) before renaming. It must be put back now, otherwise the + -- represented type won't include this extra-constraints wild card. + ctxt' + | Just loc <- extra + = let uniq = panic "addExtraCtsWC" + -- This unique will be discarded by repLContext, but is required + -- to make a Name + name = mkInternalName uniq (mkTyVarOcc "_") loc + in (++ [L loc (HsWildCardTy (AnonWildCard name))]) `fmap` ctxt + | otherwise + = ctxt + + repTy (HsTyVar n) | isTvOcc occ = do tv1 <- lookupOcc n @@ -910,11 +925,10 @@ repTy (HsExplicitTupleTy _ tys) = do repTy (HsTyLit lit) = do lit' <- repTyLit lit repTLit lit' -repTy (HsWildCardTy wc) = do - let name = HsSyn.wildCardName wc - putSrcSpanDs (nameSrcSpan name) $ - failWithDs $ text "Unexpected wild card:" <+> - quotes (ppr name) +repTy (HsWildCardTy (AnonWildCard _)) = repTWildCard +repTy (HsWildCardTy (NamedWildCard n)) = do + nwc <- lookupOcc n + repTNamedWildCard nwc repTy ty = notHandled "Exotic form of type" (ppr ty) @@ -1910,6 +1924,13 @@ repTPromotedList (t:ts) = do { tcon <- repPromotedConsTyCon repTLit :: Core TH.TyLitQ -> DsM (Core TH.TypeQ) repTLit (MkC lit) = rep2 litTName [lit] +repTWildCard :: DsM (Core TH.TypeQ) +repTWildCard = rep2 wildCardTName [] + +repTNamedWildCard :: Core TH.Name -> DsM (Core TH.TypeQ) +repTNamedWildCard (MkC s) = rep2 namedWildCardTName [s] + + --------- Type constructors -------------- repNamedTyCon :: Core TH.Name -> DsM (Core TH.TypeQ) |