Wibbles to field-label puns
authorsimonpj@microsoft.com <unknown>
Fri, 21 Aug 2009 09:06:37 +0000 (09:06 +0000)
committersimonpj@microsoft.com <unknown>
Fri, 21 Aug 2009 09:06:37 +0000 (09:06 +0000)
compiler/hsSyn/HsPat.lhs
compiler/parser/Parser.y.pp
compiler/parser/RdrHsSyn.lhs

index 84eadb7..c886766 100644 (file)
@@ -177,13 +177,21 @@ data HsRecFields id arg   -- A bunch of record fields
                                --      { x = 3, y = True }
        -- Used for both expressions and patterns
   = HsRecFields { rec_flds   :: [HsRecField id arg],
-                 rec_dotdot :: Maybe Int }
-       -- Nothing => the normal case
-       -- Just n  => the group uses ".." notation, 
-       --              and the first n elts of rec_flds
-       --              were the user-written ones
-       -- (In the latter case, the remaining elts of
-       --  rec_flds are the non-user-written ones)
+                 rec_dotdot :: Maybe Int }  -- Note [DotDot fields]
+
+-- Note [DotDot fields]
+-- ~~~~~~~~~~~~~~~~~~~~
+-- The rec_dotdot field means this:
+--   Nothing => the normal case
+--   Just n  => the group uses ".." notation, 
+--
+-- In the latter case: 
+--
+--   *before* renamer: rec_flds are exactly the n user-written fields
+--
+--   *after* renamer:  rec_flds includes *all* fields, with 
+--                    the first 'n' being the user-written ones
+--                    and the remainder being 'filled in' implicitly
 
 data HsRecField id arg = HsRecField {
        hsRecFieldId  :: Located id,
@@ -196,9 +204,12 @@ data HsRecField id arg = HsRecField {
 -- If you write T { x, y = v+1 }, the HsRecFields will be
 --     HsRecField x x True ...
 --     HsRecField y (v+1) False ...
--- That is, for "punned" field x is immediately expanded to x=x
--- but with a punning flag so we can detect it later
+-- That is, for "punned" field x is expanded (in the renamer) 
+-- to x=x; but with a punning flag so we can detect it later
 -- (e.g. when pretty printing)
+--
+-- If the original field was qualified, we un-qualify it, thus
+--    T { A.x } means T { A.x = x }
 
 hsRecFields :: HsRecFields id arg -> [id]
 hsRecFields rbinds = map (unLoc . hsRecFieldId) (rec_flds rbinds)
index c2b6aee..a9b96a0 100644 (file)
@@ -1639,7 +1639,7 @@ fbinds1   :: { ([HsRecField RdrName (LHsExpr RdrName)], Bool) }
   
 fbind  :: { HsRecField RdrName (LHsExpr RdrName) }
        : qvar '=' exp  { HsRecField $1 $3 False }
-       | qvar          { HsRecField $1 (L (getLoc $1) (HsVar (unLoc $1))) True }
+        | qvar          { HsRecField $1 (L (getLoc $1) placeHolderPunRhs) True }
                        -- Here's where we say that plain 'x'
                        -- means exactly 'x = x'.  The pun-flag boolean is
                        -- there so we can still print it right
index 59dfe02..e8d00a2 100644 (file)
@@ -19,6 +19,7 @@ module RdrHsSyn (
         cvBindsAndSigs,
        cvTopDecls,
        findSplice, checkDecBrGroup,
+        placeHolderPunRhs,
 
        -- Stuff to do with Foreign declarations
        mkImport,
@@ -789,9 +790,15 @@ checkAPat dynflags loc e = case e of
    HsType ty          -> return (TypePat ty) 
    _                  -> patFail loc
 
-plus_RDR, bang_RDR :: RdrName
+placeHolderPunRhs :: HsExpr RdrName
+-- The RHS of a punned record field will be filled in by the renamer
+-- It's better not to make it an error, in case we want to print it when debugging
+placeHolderPunRhs = HsVar pun_RDR
+
+plus_RDR, bang_RDR, pun_RDR :: RdrName
 plus_RDR = mkUnqual varName (fsLit "+")        -- Hack
 bang_RDR = mkUnqual varName (fsLit "!")        -- Hack
+pun_RDR  = mkUnqual varName (fsLit "pun-right-hand-side")
 
 checkPatField :: HsRecField RdrName (LHsExpr RdrName) -> P (HsRecField RdrName (LPat RdrName))
 checkPatField fld = do { p <- checkLPat (hsRecFieldArg fld)