[commit: ghc] wip/orf-reboot: Tidy up disambiguateRecordFields (dec2c1f)

git at git.haskell.org git at git.haskell.org
Mon Oct 12 06:37:16 UTC 2015


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/orf-reboot
Link       : http://ghc.haskell.org/trac/ghc/changeset/dec2c1fc410bd5bfe191fda3ea4fa8957a246838/ghc

>---------------------------------------------------------------

commit dec2c1fc410bd5bfe191fda3ea4fa8957a246838
Author: Adam Gundry <adam at well-typed.com>
Date:   Tue Oct 6 16:17:54 2015 +0100

    Tidy up disambiguateRecordFields


>---------------------------------------------------------------

dec2c1fc410bd5bfe191fda3ea4fa8957a246838
 compiler/typecheck/TcExpr.hs | 82 ++++++++++++++++++++++----------------------
 1 file changed, 41 insertions(+), 41 deletions(-)

diff --git a/compiler/typecheck/TcExpr.hs b/compiler/typecheck/TcExpr.hs
index 9b97192..3b57e00 100644
--- a/compiler/typecheck/TcExpr.hs
+++ b/compiler/typecheck/TcExpr.hs
@@ -1398,33 +1398,37 @@ signature to be omitted.
 disambiguateRecordBinds :: LHsExpr Name -> [LHsRecUpdField Name] -> Type
                                  -> TcM [LHsRecField' (AmbiguousFieldOcc Id) (LHsExpr Name)]
 disambiguateRecordBinds record_expr rbnds res_ty
-  | Just rbnds' <- unambiguous = mapM look rbnds' -- Always the case if DuplicateRecordFields is off
-  | otherwise   = do
+  = case mapM isUnambiguous rbnds of
+                     -- Always the case if DuplicateRecordFields is off
+     Just rbnds' -> lookupSelectors rbnds'
+     Nothing     -> do
       { fam_inst_envs      <- tcGetFamInstEnvs
       ; rbnds_with_parents <- fmap (zip rbnds) $ mapM getParents rbnds
-      ; case possibleParents rbnds_with_parents of
-          []  -> failWithTc (noPossibleParents rbnds)
-          [p] -> chooseParent p rbnds_with_parents
-          _ | Just p <- tyConOf fam_inst_envs res_ty -> chooseParent p rbnds_with_parents
-          _ | Just sig_ty <- obviousSig (unLoc record_expr) ->
+      ; p <- case possibleParents rbnds_with_parents of
+               []  -> failWithTc (noPossibleParents rbnds)
+               [p] -> return p
+               _ | Just p <- tyConOf fam_inst_envs res_ty -> return p
+               _ | Just sig_ty <- obviousSig (unLoc record_expr) ->
                  do { sig_tc_ty <- tcHsSigType ExprSigCtxt sig_ty
                     ; case tyConOf fam_inst_envs sig_tc_ty of
-                        Just p  -> chooseParent p rbnds_with_parents
+                        Just p  -> return p
                         Nothing -> failWithTc badOverloadedUpdate }
-          _ -> failWithTc badOverloadedUpdate }
+               _ -> failWithTc badOverloadedUpdate
+      ; assignParent p rbnds_with_parents }
   where
-    unambiguous = mapM isSingle rbnds
+    isUnambiguous :: LHsRecUpdField Name -> Maybe (LHsRecUpdField Name, Name)
+    isUnambiguous x = case unLoc (hsRecFieldLbl (unLoc x)) of
+                        Unambiguous _ sel_name -> Just (x, sel_name)
+                        Ambiguous{}            -> Nothing
 
-    isSingle :: LHsRecUpdField Name -> Maybe (LHsRecUpdField Name, Name)
-    isSingle x = case unLoc (hsRecFieldLbl (unLoc x)) of
-                   Unambiguous _ sel_name -> Just (x, sel_name)
-                   Ambiguous{}            -> Nothing
-
-    look :: (LHsRecUpdField Name, Name) -> TcM (LHsRecField' (AmbiguousFieldOcc Id) (LHsExpr Name))
-    look (L l x, n) = do i <- tcLookupId n
-                         let L loc af = hsRecFieldLbl x
-                             lbl      = rdrNameAmbiguousFieldOcc af
-                         return $ L l x { hsRecFieldLbl = L loc (Unambiguous lbl i) }
+    lookupSelectors :: [(LHsRecUpdField Name, Name)] -> TcM [LHsRecField' (AmbiguousFieldOcc Id) (LHsExpr Name)]
+    lookupSelectors = mapM look
+      where
+        look :: (LHsRecUpdField Name, Name) -> TcM (LHsRecField' (AmbiguousFieldOcc Id) (LHsExpr Name))
+        look (L l x, n) = do i <- tcLookupId n
+                             let L loc af = hsRecFieldLbl x
+                                 lbl      = rdrNameAmbiguousFieldOcc af
+                             return $ L l x { hsRecFieldLbl = L loc (Unambiguous lbl i) }
 
     -- Extract the outermost TyCon of a type, if there is one; for
     -- data families this is the representation tycon (because that's
@@ -1440,40 +1444,36 @@ disambiguateRecordBinds record_expr rbnds res_ty
 
     -- Look up the parent tycon for each candidate record selector.
     getParents :: LHsRecUpdField Name -> RnM [(TyCon, Name)]
-    getParents x = case unLoc (hsRecFieldLbl (unLoc x)) of
-                    Unambiguous _ sel_name -> fmap return $ lookupParent sel_name
+    getParents (L _ fld) = case unLoc (hsRecFieldLbl fld) of
+                    Unambiguous _ sel_name -> fmap singleton $ lookupParent sel_name
                     Ambiguous   _ _        -> do {
-           Just (Right xs) <- lookupGlobalOccRn_overloaded True (unLoc (hsRecUpdFieldRdr (unLoc x)))
+           Just (Right xs) <- lookupGlobalOccRn_overloaded True (unLoc (hsRecUpdFieldRdr fld))
          ; mapM (lookupParent . selectorFieldOcc) xs }
-      where
-        lookupParent name = do { id <- tcLookupId name
-                               ; ASSERT (isRecordSelector id)
-                                 return (recordSelectorTyCon id, name) }
+
+    lookupParent :: Name -> RnM (TyCon, Name)
+    lookupParent name = do { id <- tcLookupId name
+                           ; ASSERT (isRecordSelector id)
+                             return (recordSelectorTyCon id, name) }
 
     -- Make all the fields unambiguous by choosing the given parent.
     -- Fails with an error if any of the ambiguous fields cannot have
     -- that parent, e.g. if the user writes
     --     r { x = e } :: T
     -- where T does not have field x.
-    chooseParent :: TyCon -> [(LHsRecUpdField Name, [(TyCon, Name)])] -> RnM [LHsRecField' (AmbiguousFieldOcc Id) (LHsExpr Name)]
-    chooseParent p rbnds | null orphans = mapM foo rbnds'
+    assignParent :: TyCon -> [(LHsRecUpdField Name, [(TyCon, Name)])]
+                 -> RnM [LHsRecField' (AmbiguousFieldOcc Id) (LHsExpr Name)]
+    assignParent p rbnds | null orphans = lookupSelectors rbnds'
                          | otherwise    = failWithTc (orphanFields p orphans)
       where
         (orphans, rbnds') = partitionWith pickParent rbnds
 
-        foo :: (LHsRecUpdField Name, Name) -> RnM (LHsRecField' (AmbiguousFieldOcc Id) (LHsExpr Name))
-        foo (L l fld, name) = do id <- tcLookupId name
-                                 let L loc lbl = hsRecUpdFieldRdr fld
-                                 return $ L l fld { hsRecFieldLbl = L loc (Unambiguous lbl id) }
-
-        -- Returns Right fld' if fld can have parent p, or Left lbl if not.
-        -- TODO refactor
-        pickParent :: (LHsRecUpdField Name, [(TyCon, Name)]) ->
-                          Either (Located RdrName) (LHsRecUpdField Name, Name)
-        pickParent (L l fld, xs)
+        -- Returns Right if fld can have parent p, or Left lbl if not.
+        pickParent :: (LHsRecUpdField Name, [(TyCon, Name)])
+                   -> Either (Located RdrName) (LHsRecUpdField Name, Name)
+        pickParent (fld, xs)
             = case lookup p xs of
-                  Just name -> Right (L l fld, name)
-                  Nothing   -> Left (fmap rdrNameAmbiguousFieldOcc (hsRecFieldLbl fld))
+                  Just name -> Right (fld, name)
+                  Nothing   -> Left (hsRecUpdFieldRdr (unLoc fld))
 
     -- A type signature on the record expression must be "obvious",
     -- i.e. the outermost constructor ignoring parentheses.



More information about the ghc-commits mailing list