Give lookupGRE_Name a better API
authorSimon Peyton Jones <simonpj@microsoft.com>
Thu, 23 Jun 2016 07:47:31 +0000 (08:47 +0100)
committerSimon Peyton Jones <simonpj@microsoft.com>
Thu, 23 Jun 2016 08:22:53 +0000 (09:22 +0100)
lookupGRE_Name should return either zero or one GREs, never
several. This is a consequence of INVARIANT 1 on GlobalRdrEnv.

So it's better if it returns a Maybe; the panic on multiple results
is put in one place, instead of being scattered or ignored.

Just refactoring, no change in behaviour

compiler/basicTypes/RdrName.hs
compiler/main/InteractiveEval.hs
compiler/rename/RnEnv.hs
compiler/rename/RnNames.hs
compiler/rename/RnPat.hs
compiler/rename/RnSource.hs
compiler/typecheck/FamInst.hs
compiler/typecheck/TcDeriv.hs
compiler/typecheck/TcErrors.hs
compiler/typecheck/TcForeign.hs

index 0856597..592ee92 100644 (file)
@@ -734,10 +734,14 @@ lookupGRE_RdrName rdr_name env
     Nothing   -> []
     Just gres -> pickGREs rdr_name gres
 
-lookupGRE_Name :: GlobalRdrEnv -> Name -> [GlobalRdrElt]
+lookupGRE_Name :: GlobalRdrEnv -> Name -> Maybe GlobalRdrElt
 lookupGRE_Name env name
-  = [ gre | gre <- lookupGlobalRdrEnv env (nameOccName name),
-            gre_name gre == name ]
+  = case [ gre | gre <- lookupGlobalRdrEnv env (nameOccName name)
+               , gre_name gre == name ] of
+      []    -> Nothing
+      [gre] -> Just gre
+      gres  -> pprPanic "lookupGRE_Name" (ppr name $$ ppr gres)
+               -- See INVARIANT 1 on GlobalRdrEnv
 
 lookupGRE_Field_Name :: GlobalRdrEnv -> Name -> FastString -> [GlobalRdrElt]
 -- Used when looking up record fields, where the selector name and
@@ -751,8 +755,10 @@ getGRE_NameQualifier_maybes :: GlobalRdrEnv -> Name -> [Maybe [ModuleName]]
 -- Returns all the qualifiers by which 'x' is in scope
 -- Nothing means "the unqualified version is in scope"
 -- [] means the thing is not in scope at all
-getGRE_NameQualifier_maybes env
-  = map (qualifier_maybe) . lookupGRE_Name env
+getGRE_NameQualifier_maybes env name
+  = case lookupGRE_Name env name of
+      Just gre -> [qualifier_maybe gre]
+      Nothing  -> []
   where
     qualifier_maybe (GRE { gre_lcl = lcl, gre_imp = iss })
       | lcl       = Nothing
index 5d0d7e7..6c95dc3 100644 (file)
@@ -793,8 +793,7 @@ getInfo allInfo name
                        -- The one we looked for in the first place!
                | pretendNameIsInScope n = True
                | isBuiltInSyntax n      = True
-               | isExternalName n       = any ((== n) . gre_name)
-                                              (lookupGRE_Name rdr_env n)
+               | isExternalName n       = isJust (lookupGRE_Name rdr_env n)
                | otherwise              = True
 
 -- | Returns all names in scope in the current interactive context
index 4ab67ad..b0a7281 100644 (file)
@@ -1018,7 +1018,7 @@ addUsedDataCons :: GlobalRdrEnv -> TyCon -> RnM ()
 addUsedDataCons rdr_env tycon
   = addUsedGREs [ gre
                 | dc <- tyConDataCons tycon
-                , gre : _ <- [lookupGRE_Name rdr_env (dataConName dc) ] ]
+                , Just gre <- [lookupGRE_Name rdr_env (dataConName dc)] ]
 
 addUsedGRE :: Bool -> GlobalRdrElt -> RnM ()
 -- Called for both local and imported things
index 2fc6263..3803f58 100644 (file)
@@ -1973,8 +1973,8 @@ exportClashErr global_env name1 name2 ie1 ie2
     -- get_gre finds a GRE for the Name, so that we can show its provenance
     get_gre name
         = case lookupGRE_Name global_env name of
-             (gre:_) -> gre
-             []      -> pprPanic "exportClashErr" (ppr name)
+             Just gre -> gre
+             Nothing  -> pprPanic "exportClashErr" (ppr name)
     get_loc name = greSrcSpan (get_gre name)
     (name1', ie1', name2', ie2') = if get_loc name1 < get_loc name2
                                    then (name1, ie1, name2, ie2)
index d252f7f..8c78314 100644 (file)
@@ -637,12 +637,13 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot })
     -- (that is, the parent of the data constructor),
     -- or 'Nothing' if it is a pattern synonym or not in scope.
     -- That's the parent to use for looking up record fields.
-    find_tycon env con
-      | Just (AConLike (RealDataCon dc)) <- wiredInNameTyThing_maybe con
+    find_tycon env con_name
+      | Just (AConLike (RealDataCon dc)) <- wiredInNameTyThing_maybe con_name
       = Just (tyConName (dataConTyCon dc))
         -- Special case for [], which is built-in syntax
         -- and not in the GlobalRdrEnv (Trac #8448)
-      | [gre] <- lookupGRE_Name env con
+
+      | Just gre <- lookupGRE_Name env con_name
       = case gre_par gre of
           ParentIs p -> Just p
           _          -> Nothing
index f16da6d..3b23bb6 100644 (file)
@@ -1358,11 +1358,11 @@ toParents rdr_env ns
 getParent :: GlobalRdrEnv -> Name -> Name
 getParent rdr_env n
   = case lookupGRE_Name rdr_env n of
-      gre : _ -> case gre_par gre of
-                   ParentIs  { par_is = p } -> p
-                   FldParent { par_is = p } -> p
-                   _                        -> n
-      _ -> n
+      Just gre -> case gre_par gre of
+                    ParentIs  { par_is = p } -> p
+                    FldParent { par_is = p } -> p
+                    _                        -> n
+      Nothing -> n
 
 
 {- Note [Extra dependencies from .hs-boot files]
index 39cd1a5..434f1f3 100644 (file)
@@ -322,7 +322,7 @@ tcTopNormaliseNewTypeTF_maybe faminsts rdr_env ty
         (not (isAbstractTyCon tc) && all in_scope data_con_names)
       where
         data_con_names = map dataConName (tyConDataCons tc)
-        in_scope dc    = not $ null $ lookupGRE_Name rdr_env dc
+        in_scope dc    = isJust (lookupGRE_Name rdr_env dc)
 
 {-
 ************************************************************************
index 1a93687..fc4fb45 100644 (file)
@@ -901,7 +901,7 @@ mkEqnHelp overlap_mode tvs cls cls_tys tycon tc_args mtheta
              hidden_data_cons = not (isWiredInName (tyConName rep_tc)) &&
                                 (isAbstractTyCon rep_tc ||
                                  any not_in_scope data_con_names)
-             not_in_scope dc  = null (lookupGRE_Name rdr_env dc)
+             not_in_scope dc  = isNothing (lookupGRE_Name rdr_env dc)
 
        ; addUsedDataCons rdr_env rep_tc
        ; unless (isNothing mtheta || not hidden_data_cons)
index 2a87975..3a0b02b 100644 (file)
@@ -1244,7 +1244,7 @@ mkCoercibleExplanation rdr_env fam_envs ty1 ty2
         | isNewTyCon tc
         , [data_con] <- tyConDataCons tc
         , let dc_name = dataConName data_con
-        , null (lookupGRE_Name rdr_env dc_name)
+        , isNothing (lookupGRE_Name rdr_env dc_name)
         = Just $ hang (text "The data constructor" <+> quotes (ppr dc_name))
                     2 (sep [ text "of newtype" <+> quotes (pprSourceTyCon tc)
                            , text "is not in scope" ])
index 02227c7..aef1e9c 100644 (file)
@@ -189,7 +189,7 @@ normaliseFfiType' env ty0 = go initRecTc ty0
 checkNewtypeFFI :: GlobalRdrEnv -> TyCon -> Maybe GlobalRdrElt
 checkNewtypeFFI rdr_env tc
   | Just con <- tyConSingleDataCon_maybe tc
-  , [gre] <- lookupGRE_Name rdr_env (dataConName con)
+  , Just gre <- lookupGRE_Name rdr_env (dataConName con)
   = Just gre    -- See Note [Newtype constructor usage in foreign declarations]
   | otherwise
   = Nothing