[project @ 1997-06-18 23:52:36 by simonpj]
authorsimonpj <unknown>
Wed, 18 Jun 1997 23:53:03 +0000 (23:53 +0000)
committersimonpj <unknown>
Wed, 18 Jun 1997 23:53:03 +0000 (23:53 +0000)
A raft of small bug-fixes to 2.05 by SLPJ

24 files changed:
ghc/compiler/absCSyn/PprAbsC.lhs
ghc/compiler/basicTypes/Name.lhs
ghc/compiler/hsSyn/HsBinds.lhs
ghc/compiler/hsSyn/HsTypes.lhs
ghc/compiler/main/Main.lhs
ghc/compiler/nativeGen/MachRegs.lhs
ghc/compiler/parser/hsparser.y
ghc/compiler/reader/RdrHsSyn.lhs
ghc/compiler/rename/RnEnv.lhs
ghc/compiler/rename/RnMonad.lhs
ghc/compiler/rename/RnNames.lhs
ghc/compiler/rename/RnSource.lhs
ghc/compiler/tests/rename/rn019.hs [new file with mode: 0644]
ghc/compiler/tests/rename/rn020.hs [new file with mode: 0644]
ghc/compiler/tests/rename/rn021.hs [new file with mode: 0644]
ghc/compiler/tests/typecheck/should_fail/tcfail072.hs [new file with mode: 0644]
ghc/compiler/tests/typecheck/should_succeed/Makefile
ghc/compiler/tests/typecheck/should_succeed/tc086.hs [new file with mode: 0644]
ghc/compiler/tests/typecheck/should_succeed/tc087.hs [new file with mode: 0644]
ghc/compiler/tests/typecheck/should_succeed/tc088.hs [new file with mode: 0644]
ghc/compiler/typecheck/Inst.lhs
ghc/compiler/typecheck/TcInstDcls.lhs
ghc/compiler/typecheck/TcMatches.lhs
ghc/compiler/utils/FiniteMap.lhs

index 6d4f3ba..3454645 100644 (file)
@@ -954,7 +954,7 @@ ppr_amode sty (CAddr reg_rel)
 
 ppr_amode sty (CReg magic_id) = pprMagicId sty magic_id
 
-ppr_amode sty (CTemp uniq kind) = pprUnique uniq
+ppr_amode sty (CTemp uniq kind) = pprUnique uniq <> char '_'
 
 ppr_amode sty (CLbl label kind) = pprCLabel sty label
 
@@ -1214,7 +1214,7 @@ labelSeenTE label env@(seen_uniqs, seen_labels)
 \begin{code}
 pprTempDecl :: Unique -> PrimRep -> Doc
 pprTempDecl uniq kind
-  = hcat [ pprPrimKind PprDebug kind, space, pprUnique uniq, semi ]
+  = hcat [ pprPrimKind PprDebug kind, space, pprUnique uniq, ptext SLIT("_;") ]
 
 pprExternDecl :: CLabel -> PrimRep -> Doc
 
index 89fe135..198fc42 100644 (file)
@@ -256,9 +256,12 @@ mkInstDeclName uniq mod occ loc from_here
          | otherwise = Implicit
 
 
-setNameProvenance :: Name -> Provenance -> Name                -- Implicit Globals only
-setNameProvenance (Global uniq mod occ def Implicit) prov = Global uniq mod occ def prov
-setNameProvenance other_name                        prov = other_name
+setNameProvenance :: Name -> Provenance -> Name        
+       -- setNameProvenance used to only change the provenance of Implicit-provenance things,
+       -- but that gives bad error messages for names defined twice in the same
+       -- module, so I changed it to set the proveance of *any* global (SLPJ Jun 97)
+setNameProvenance (Global uniq mod occ def _) prov = Global uniq mod occ def prov
+setNameProvenance other_name                 prov = other_name
 
 getNameProvenance :: Name -> Provenance
 getNameProvenance (Global uniq mod occ def prov) = prov
index 1f32b3e..f28cff8 100644 (file)
@@ -261,27 +261,25 @@ instance (NamedThing name, Outputable name) => Outputable (Sig name) where
 
 
 ppr_sig sty (Sig var ty _)
-      = hang (hsep [ppr sty var, ptext SLIT("::")])
-            4 (ppr sty ty)
+      = sep [ppr sty var <+> ptext SLIT("::"),
+            nest 4 (ppr sty ty)]
 
 ppr_sig sty (ClassOpSig var _ ty _)
-      = hang (hsep [ppr sty (getOccName var), ptext SLIT("::")])
-            4 (ppr sty ty)
+      = sep [ppr sty (getOccName var) <+> ptext SLIT("::"),
+            nest 4 (ppr sty ty)]
 
 ppr_sig sty (DeforestSig var _)
-      = hang (hsep [text "{-# DEFOREST", ppr sty var])
-                  4 (text "#-")
+      = hsep [text "{-# DEFOREST", ppr sty var, text "#-}"]
 
 ppr_sig sty (SpecSig var ty using _)
-      = hang (hsep [text "{-# SPECIALIZE", ppr sty var, ptext SLIT("::")])
-            4 (hsep [ppr sty ty, pp_using using, text "#-}"])
-
+      = sep [ hsep [text "{-# SPECIALIZE", ppr sty var, ptext SLIT("::")],
+             nest 4 (hsep [ppr sty ty, pp_using using, text "#-}"])
+       ]
       where
        pp_using Nothing   = empty
        pp_using (Just me) = hsep [char '=', ppr sty me]
 
 ppr_sig sty (InlineSig var _)
-
         = hsep [text "{-# INLINE", ppr sty var, text "#-}"]
 
 ppr_sig sty (MagicUnfoldingSig var str _)
index 25c1999..b83f4b8 100644 (file)
@@ -24,7 +24,7 @@ module HsTypes (
 IMP_Ubiq()
 
 import CmdLineOpts      ( opt_PprUserLength )
-import Outputable      ( Outputable(..), PprStyle(..), interppSP, ifnotPprForUser )
+import Outputable      ( Outputable(..), PprStyle(..), pprQuote, interppSP )
 import Kind            ( Kind {- instance Outputable -} )
 import Name            ( nameOccName )
 import Pretty
@@ -100,20 +100,12 @@ replaceTyVarName (IfaceTyVar n k) n' = IfaceTyVar n' k
 \begin{code}
 
 instance (Outputable name) => Outputable (HsType name) where
-    ppr = pprHsType
+    ppr sty ty = pprQuote sty $ \ sty -> pprHsType sty ty
 
 instance (Outputable name) => Outputable (HsTyVar name) where
-    ppr sty (UserTyVar name) = ppr_hs_tyname sty name
-    ppr sty (IfaceTyVar name kind) = hsep [ppr_hs_tyname sty name, ptext SLIT("::"), ppr sty kind]
-
-
--- Here comes a rather gross hack.  
--- We want to print data and class decls in interface files, from the original source
--- When we do, we want the type variables to come out with their original names, not
--- some new unique (or else interfaces wobble too much).  So when we come to one of
--- these type variables we sneakily change the style to PprForUser!
-ppr_hs_tyname PprInterface tv_name = ppr (PprForUser opt_PprUserLength) tv_name
-ppr_hs_tyname other_sty    tv_name = ppr other_sty tv_name
+    ppr sty (UserTyVar name)       = ppr sty name
+    ppr sty (IfaceTyVar name kind) = pprQuote sty $ \ sty ->
+                                    hsep [ppr sty name, ptext SLIT("::"), ppr sty kind]
 
 ppr_forall sty ctxt_prec [] [] ty
    = ppr_mono_ty sty ctxt_prec ty
@@ -150,7 +142,7 @@ pprParendHsType sty ty = ppr_mono_ty sty pREC_CON ty
 ppr_mono_ty sty ctxt_prec (HsPreForAllTy ctxt ty)     = ppr_forall sty ctxt_prec [] ctxt ty
 ppr_mono_ty sty ctxt_prec (HsForAllTy tvs ctxt ty)    = ppr_forall sty ctxt_prec tvs ctxt ty
 
-ppr_mono_ty sty ctxt_prec (MonoTyVar name) = ppr_hs_tyname sty name
+ppr_mono_ty sty ctxt_prec (MonoTyVar name) = ppr sty name
 
 ppr_mono_ty sty ctxt_prec (MonoFunTy ty1 ty2)
   = let p1 = ppr_mono_ty sty pREC_FUN ty1
@@ -170,8 +162,7 @@ ppr_mono_ty sty ctxt_prec (MonoTyApp fun_ty arg_ty)
               (hsep [ppr_mono_ty sty pREC_FUN fun_ty, ppr_mono_ty sty pREC_CON arg_ty])
 
 ppr_mono_ty sty ctxt_prec (MonoDictTy clas ty)
-  = braces (hsep [ppr sty clas, ppr_mono_ty sty pREC_CON ty])
-       -- Curlies are temporary
+  = hsep [ppr sty clas, ppr_mono_ty sty pREC_CON ty]
 \end{code}
 
 
index afd2617..2ed03b4 100644 (file)
@@ -74,7 +74,7 @@ main =
 doIt :: ([CoreToDo], [StgToDo]) -> String -> IO ()
 
 doIt (core_cmds, stg_cmds) input_pgm
-  = doDump opt_Verbose "Glasgow Haskell Compiler, version 2.03, for Haskell 1.4" "" >>
+  = doDump opt_Verbose "Glasgow Haskell Compiler, version 2.04, for Haskell 1.4" "" >>
 
     -- ******* READER
     show_pass "Reader" >>
index 5beabc1..a2af742 100644 (file)
@@ -80,6 +80,7 @@ import Unique         ( mkPseudoUnique1, mkPseudoUnique2, mkPseudoUnique3,
                          Unique{-instance Ord3-}
                        )
 import UniqSupply      ( getUnique, returnUs, thenUs, SYN_IE(UniqSM) )
+import UniqFM          ( Uniquable(..) )
 import Util            ( panic, Ord3(..) )
 \end{code}
 
index 5203c1e..58db2df 100644 (file)
@@ -475,12 +475,12 @@ topdecls:  topdecl
                }
         ;
 
-topdecl        :  typed                                { $$ = $1; }
-       |  datad                                { $$ = $1; }
-       |  newtd                                { $$ = $1; }
-       |  classd                               { $$ = $1; }
-       |  instd                                { $$ = $1; }
-       |  defaultd                             { $$ = $1; }
+topdecl        :  typed                                { $$ = $1; FN = NULL; SAMEFN = 0; }
+       |  datad                                { $$ = $1; FN = NULL; SAMEFN = 0; }
+       |  newtd                                { $$ = $1; FN = NULL; SAMEFN = 0; }
+       |  classd                               { $$ = $1; FN = NULL; SAMEFN = 0; }
+       |  instd                                { $$ = $1; FN = NULL; SAMEFN = 0; }
+       |  defaultd                             { $$ = $1; FN = NULL; SAMEFN = 0; }
        |  decl                                 { $$ = $1; }
        ;
 
index f7d4e92..9f4aa00 100644 (file)
@@ -124,9 +124,17 @@ extractHsTyVars ty
     get (MonoFunTy ty1 ty2)     acc = get ty1 (get ty2 acc)
     get (MonoDictTy cls ty)     acc = get ty acc
     get (MonoTyVar tv)                  acc = insert tv acc
-    get (HsPreForAllTy ctxt ty)  acc = foldr (get . snd) (get ty acc) ctxt
-    get (HsForAllTy tvs ctxt ty) acc = filter (`notElem` locals) $
-                                      foldr (get . snd) (get ty acc) ctxt
+
+       -- In (All a => a -> a) -> Int, there are no free tyvars
+       -- We just assume that we quantify over all type variables mentioned in the context.
+    get (HsPreForAllTy ctxt ty)  acc = filter (`notElem` locals) (get ty [])
+                                      ++ acc
+                                    where
+                                      locals = foldr (get . snd) [] ctxt
+
+    get (HsForAllTy tvs ctxt ty) acc = (filter (`notElem` locals) $
+                                       foldr (get . snd) (get ty []) ctxt)
+                                      ++ acc
                                     where
                                       locals = map getTyVarName tvs
 
index 2844c72..d926583 100644 (file)
@@ -31,7 +31,7 @@ import TysWiredIn     ( tupleTyCon, listTyCon, charTyCon, intTyCon )
 import FiniteMap
 import Outputable
 import Unique          ( Unique, unboundKey )
-import UniqFM           ( Uniquable(..) )
+import UniqFM           ( Uniquable(..), listToUFM, plusUFM_C )
 import Maybes          ( maybeToBool )
 import UniqSupply
 import SrcLoc          ( SrcLoc, noSrcLoc )
@@ -88,26 +88,29 @@ newLocallyDefinedGlobalName mod occ rec_exp_fn loc
        -- If it's not in the cache we put it there with the correct provenance.
        -- The idea is that, after all this, the cache
        -- will contain a Name with the correct Provenance (i.e. Local)
+
+       -- OLD (now wrong) COMMENT:
+       --   "Actually, there's a catch.  If this is the *second* binding for something
+       --    we want to allocate a *fresh* unique, rather than using the same Name as before.
+       --    Otherwise we don't detect conflicting definitions of the same top-level name!
+       --    So the only time we re-use a Name already in the cache is when it's one of
+       --    the Implicit magic-unique ones mentioned in the previous para"
+
+       -- This (incorrect) patch doesn't work for record decls, when we have
+       -- the same field declared in multiple constructors.   With the above patch,
+       -- each occurrence got a new Name --- aargh!
        --
-       -- Actually, there's a catch.  If this is the *second* binding for something
-       -- we want to allocate a *fresh* unique, rather than using the same Name as before.
-       -- Otherwise we don't detect conflicting definitions of the same top-level name!
-       -- So the only time we re-use a Name already in the cache is when it's one of
-       -- the Implicit magic-unique ones mentioned in the previous para
+       -- So I reverted to the simple caching method (no "second-binding" thing)
+       -- The multiple-local-binding case is now handled by improving the conflict
+       -- detection in plusNameEnv.
     let
        provenance = LocalDef (rec_exp_fn new_name) loc
        (us', us1) = splitUniqSupply us
        uniq       = getUnique us1
         key        = (mod,occ)
        new_name   = case lookupFM cache key of
-                        Just name | is_implicit_prov
-                                  -> setNameProvenance name provenance
-                                  where
-                                     is_implicit_prov = case getNameProvenance name of
-                                                           Implicit -> True
-                                                           other    -> False
-                        other   -> mkGlobalName uniq mod occ VanillaDefn provenance
-
+                        Just name -> setNameProvenance name provenance
+                        other     -> mkGlobalName uniq mod occ VanillaDefn provenance
        new_cache  = addToFM cache key new_name
     in
     setNameSupplyRn (us', inst_ns, new_cache)          `thenRn_`
@@ -358,17 +361,28 @@ plusRnEnv (RnEnv n1 f1) (RnEnv n2 f2)
 ===============  NameEnv  ================
 \begin{code}
 plusNameEnvRn :: NameEnv -> NameEnv -> RnM s d NameEnv
-plusNameEnvRn n1 n2
-  = mapRn (addErrRn.nameClashErr) (conflictsFM (/=) n1 n2)             `thenRn_`
-    returnRn (n1 `plusFM` n2)
+plusNameEnvRn env1 env2
+  = mapRn (addErrRn.nameClashErr) (conflictsFM conflicting_name env1 env2)             `thenRn_`
+    returnRn (env1 `plusFM` env2)
 
 addOneToNameEnv :: NameEnv -> RdrName -> Name -> RnM s d NameEnv
 addOneToNameEnv env rdr_name name
  = case lookupFM env rdr_name of
-       Nothing    -> returnRn (addToFM env rdr_name name)
-       Just name2 -> addErrRn (nameClashErr (rdr_name, (name, name2))) `thenRn_`
+       Just name2 | conflicting_name name name2
+                  -> addErrRn (nameClashErr (rdr_name, (name, name2))) `thenRn_`
                      returnRn env
 
+       Nothing    -> returnRn (addToFM env rdr_name name)
+
+conflicting_name n1 n2 = (n1 /= n2) || (isLocallyDefinedName n1 && isLocallyDefinedName n2)
+       -- We complain of a conflict if one RdrName maps to two different Names,
+       -- OR if one RdrName maps to the same *locally-defined* Name.  The latter
+       -- case is to catch two separate, local definitions of the same thing.
+       --
+       -- If a module imports itself then there might be a local defn and an imported
+       -- defn of the same name; in this case the names will compare as equal, but
+       -- will still have different provenances.
+
 lookupNameEnv :: NameEnv -> RdrName -> Maybe Name
 lookupNameEnv = lookupFM
 
@@ -400,13 +414,20 @@ pprFixityProvenance sty (fixity, prov) = pprProvenance sty prov
 
 ===============  Avails  ================
 \begin{code}
-emptyModuleAvails :: ModuleAvails
-plusModuleAvails ::  ModuleAvails ->  ModuleAvails ->  ModuleAvails
-lookupModuleAvails :: ModuleAvails -> Module -> Maybe [AvailInfo]
+mkExportAvails :: Bool -> Module -> [AvailInfo] -> ExportAvails
+mkExportAvails unqualified_import mod_name avails
+  = (mod_avail_env, entity_avail_env)
+  where
+       -- The "module M" syntax only applies to *unqualified* imports (1.4 Report, Section 5.1.1)
+    mod_avail_env | unqualified_import = unitFM mod_name avails 
+                 | otherwise          = emptyFM
+   
+    entity_avail_env = listToUFM [ (name,avail) | avail <- avails, 
+                                                 name  <- availEntityNames avail]
 
-emptyModuleAvails = emptyFM
-plusModuleAvails  = plusFM_C (++)
-lookupModuleAvails = lookupFM
+plusExportAvails ::  ExportAvails ->  ExportAvails ->  ExportAvails
+plusExportAvails (m1, e1) (m2, e2)
+  = (plusFM_C (++) m1 m2, plusUFM_C plusAvail e1 e2)
 \end{code}
 
 
index f1d6f45..dcdc718 100644 (file)
@@ -55,6 +55,7 @@ import Pretty
 import Outputable      ( PprStyle(..) )
 import SrcLoc          ( SrcLoc, mkGeneratedSrcLoc )
 import Unique          ( Unique )
+import UniqFM          ( UniqFM )
 import FiniteMap       ( FiniteMap, emptyFM, bagToFM )
 import Bag             ( Bag, mapBag, emptyBag, isEmptyBag, snocBag )
 import UniqSet
@@ -185,7 +186,15 @@ type Fixities              = [(OccName, (Fixity, Provenance))]
        -- or the same type/class/id, more than once.   Hence a boring old list.
        -- This allows us to report duplicates in just one place, namely plusRnEnv.
        
-type ModuleAvails      = FiniteMap Module Avails
+type ExportAvails      = (FiniteMap Module Avails,     -- Used to figure out "module M" export specifiers
+                                                       -- Includes avails only from *unqualified* imports
+                                                       -- (see 1.4 Report Section 5.1.1)
+
+                          UniqFM AvailInfo)            -- Used to figure out all other export specifiers.
+                                                       -- Maps a Name to the AvailInfo that contains it
+                                                       -- NB: Contain bindings for class ops but 
+                                                       -- not constructors (see defn of availEntityNames)
+
 
 data AvailInfo         = NotAvailable 
                        | Avail Name            -- An ordinary identifier
index beca595..4e745f1 100644 (file)
@@ -72,13 +72,13 @@ getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
       else
 
        -- COMBINE RESULTS
-       -- We put the local env first, so that a local provenance
+       -- We put the local env second, so that a local provenance
        -- "wins", even if a module imports itself.
       foldlRn plusRnEnv emptyRnEnv imp_rn_envs         `thenRn` \ imp_rn_env ->
-      plusRnEnv local_rn_env imp_rn_env                        `thenRn` \ rn_env ->
+      plusRnEnv imp_rn_env local_rn_env                        `thenRn` \ rn_env ->
       let
-        all_avails :: ModuleAvails
-        all_avails = foldr plusModuleAvails local_mod_avails imp_avails_s
+        export_avails :: ExportAvails
+        export_avails = foldr plusExportAvails local_mod_avails imp_avails_s
 
         explicit_names :: NameSet      -- locally defined or explicitly imported
         explicit_names = foldr add_on emptyNameSet (local_avails : explicit_imports_s)
@@ -86,7 +86,7 @@ getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
       in
   
        -- PROCESS EXPORT LISTS
-      exportsFromAvail this_mod exports all_avails rn_env      
+      exportsFromAvail this_mod exports export_avails rn_env   
                                                        `thenRn` \ (export_fn, export_env) ->
 
        -- RECORD THAT LOCALLY DEFINED THINGS ARE AVAILABLE
@@ -145,7 +145,7 @@ checkEarlyExit mod
 
 \begin{code}
 importsFromImportDecl :: RdrNameImportDecl
-                     -> RnMG (RnEnv, ModuleAvails, [AvailInfo])
+                     -> RnMG (RnEnv, ExportAvails, [AvailInfo])
 
 importsFromImportDecl (ImportDecl mod qual_only as_source as_mod import_spec loc)
   = pushSrcLocRn loc $
@@ -277,7 +277,7 @@ qualifyImports :: Module                            -- Imported module
               -> Maybe Module                          -- Optional "as M" part 
               -> ExportEnv                             -- What's imported
               -> [AvailInfo]                           -- What's to be hidden
-              -> RnMG (RnEnv, ModuleAvails)
+              -> RnMG (RnEnv, ExportAvails)
 
 qualifyImports this_mod qual_imp unqual_imp as_mod (ExportEnv avails fixities) hides
   = 
@@ -292,11 +292,10 @@ qualifyImports this_mod qual_imp unqual_imp as_mod (ExportEnv avails fixities) h
        -- Create the fixity env
        fixity_env = foldl (add_fixity name_env2) emptyFixityEnv fixities
 
-       -- The "module M" syntax only applies to *unqualified* imports (1.4 Report, Section 5.1.1)
-       mod_avail_env | unqual_imp = unitFM qual_mod avails
-                     | otherwise  = emptyFM
+       -- Create the export-availability info
+       export_avails = mkExportAvails unqual_imp qual_mod avails
     in
-    returnRn (RnEnv name_env2 fixity_env, mod_avail_env)
+    returnRn (RnEnv name_env2 fixity_env, export_avails)
   where
     qual_mod = case as_mod of
                  Nothing           -> this_mod
@@ -395,15 +394,17 @@ includes ConcBase.StateAndSynchVar#, and so on...
 \begin{code}
 exportsFromAvail :: Module
                 -> Maybe [RdrNameIE]   -- Export spec
-                -> ModuleAvails
+                -> ExportAvails
                 -> RnEnv
                 -> RnMG (Name -> ExportFlag, ExportEnv)
        -- Complains if two distinct exports have same OccName
        -- Complains about exports items not in scope
-exportsFromAvail this_mod Nothing all_avails rn_env
-  = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) all_avails rn_env
+exportsFromAvail this_mod Nothing export_avails rn_env
+  = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) export_avails rn_env
 
-exportsFromAvail this_mod (Just export_items) all_avails (RnEnv name_env fixity_env)
+exportsFromAvail this_mod (Just export_items) 
+                (mod_avail_env, entity_avail_env)
+                (RnEnv name_env fixity_env)
   = mapRn exports_from_item export_items               `thenRn` \ avail_envs ->
     foldlRn plusAvailEnv emptyAvailEnv avail_envs      `thenRn` \ export_avail_env -> 
     let
@@ -414,18 +415,9 @@ exportsFromAvail this_mod (Just export_items) all_avails (RnEnv name_env fixity_
     returnRn (export_fn, ExportEnv export_avails export_fixities)
 
   where
-    full_avail_env :: UniqFM AvailInfo
-    full_avail_env = addListToUFM_C plusAvail emptyUFM
-                          [(name, avail) | avail <- concat (eltsFM all_avails),
-                                           name  <- availEntityNames avail 
-                          ]
-
-       -- NB: full_avail_env will contain bindings for class ops but not constructors
-       -- (see defn of availEntityNames)
-
     exports_from_item :: RdrNameIE -> RnMG AvailEnv
     exports_from_item ie@(IEModuleContents mod)
-       = case lookupFM all_avails mod of
+       = case lookupFM mod_avail_env mod of
                Nothing     -> failWithRn emptyAvailEnv (modExportErr mod)
                Just avails -> listToAvailEnv ie avails
 
@@ -449,7 +441,7 @@ exportsFromAvail this_mod (Just export_items) all_avails (RnEnv name_env fixity_
        where
           maybe_in_scope  = lookupNameEnv name_env (ieName ie)
          Just name       = maybe_in_scope
-         maybe_avail     = lookupUFM full_avail_env name
+         maybe_avail     = lookupUFM entity_avail_env name
          Just avail      = maybe_avail
          export_avail    = filterAvail ie avail
          enough_avail    = case export_avail of {NotAvailable -> False; other -> True}
index 7affaf0..ff3620e 100644 (file)
@@ -57,8 +57,8 @@ import SrcLoc         ( SrcLoc )
 import Unique          ( Unique )
 import UniqSet         ( SYN_IE(UniqSet) )
 import UniqFM          ( UniqFM, lookupUFM )
-import Util    {-      ( isIn, isn'tIn, thenCmp, removeDups, cmpPString,
-                         panic, assertPanic{- , pprTrace ToDo:rm-} ) -}
+import Util
+IMPORT_1_3(List(nub))
 \end{code}
 
 rnDecl `renames' declarations.
@@ -213,11 +213,6 @@ rnDecl (ClD (ClassDecl context cname tyvar sigs mbinds pragmas src_loc))
                (classTyVarNotInOpTyErr clas_tyvar sig)
                                                         `thenRn_`
 
-               -- Check that class tyvar *doesn't* appear in the sig's context
-        checkRn (not (clas_tyvar `elemNameSet` ctxt_fvs))
-               (classTyVarInOpCtxtErr clas_tyvar sig)
-                                                        `thenRn_`
-
        returnRn (ClassOpSig op_name dm_name new_ty locn)
 \end{code}
 
@@ -398,25 +393,34 @@ rnHsSigType :: (PprStyle -> Doc) -> RdrNameHsType -> RnMS s RenamedHsType
        -- rnHsSigType is used for source-language type signatures,
        -- which use *implicit* universal quantification.
 
+-- Given the signature  C => T  we universally quantify over FV(T) \ {in-scope-tyvars} 
+-- 
+-- We insist that the universally quantified type vars is a superset of FV(C)
+-- It follows that FV(T) is a superset of FV(C), so that the context constrains
+-- no type variables that don't appear free in the tau-type part.
+
 rnHsSigType doc_str full_ty@(HsPreForAllTy ctxt ty)    -- From source code (no kinds on tyvars)
   = getNameEnv         `thenRn` \ name_env ->
     let
-       mentioned_tyvars = extractHsTyVars full_ty
-       forall_tyvars    = filter not_in_scope mentioned_tyvars
-       not_in_scope tv  = case lookupFM name_env tv of
-                                   Nothing -> True
-                                   Just _  -> False
-
-       non_foralld_constrained = [tv | (clas, ty) <- ctxt,
-                                       tv <- extractHsTyVars ty,
-                                       not (tv `elem` forall_tyvars)
-                                 ]
+       mentioned_tyvars = extractHsTyVars ty
+       forall_tyvars    = filter (not . in_scope) mentioned_tyvars
+       in_scope tv      = maybeToBool (lookupFM name_env tv)
+
+       constrained_tyvars            = nub (concat (map (extractHsTyVars . snd) ctxt))
+       constrained_and_in_scope      = filter in_scope constrained_tyvars
+       constrained_and_not_mentioned = filter (not . (`elem` mentioned_tyvars)) constrained_tyvars
+
+       -- Zap the context if there's a problem, to avoid duplicate error message.
+       ctxt' | null constrained_and_in_scope && null constrained_and_not_mentioned = ctxt
+             | otherwise = []
     in
-    checkRn (null non_foralld_constrained)
-           (ctxtErr sig_doc non_foralld_constrained)   `thenRn_`
+    checkRn (null constrained_and_in_scope)
+           (ctxtErr1 sig_doc constrained_and_in_scope) `thenRn_`
+    checkRn (null constrained_and_not_mentioned)
+           (ctxtErr2 sig_doc constrained_and_not_mentioned ty) `thenRn_`
 
     (bindTyVarsRn sig_doc (map UserTyVar forall_tyvars)        $ \ new_tyvars ->
-     rnContext ctxt                                    `thenRn` \ new_ctxt ->
+     rnContext ctxt'                                   `thenRn` \ new_ctxt ->
      rnHsType ty                                       `thenRn` \ new_ty ->
      returnRn (HsForAllTy new_tyvars new_ctxt new_ty)
     )
@@ -693,17 +697,12 @@ rnCorePrim (UfCCallOp str casm gc arg_tys res_ty)
 
 \begin{code}
 derivingNonStdClassErr clas sty
-  = hsep [ptext SLIT("non-standard class in deriving:"), ppr sty clas]
+  = hsep [ptext SLIT("non-standard class"), ppr sty clas, ptext SLIT("in deriving clause")]
 
 classTyVarNotInOpTyErr clas_tyvar sig sty
-  = hang (hcat [ptext SLIT("Class type variable `"), 
+  = hang (hsep [ptext SLIT("Class type variable"), 
                       ppr sty clas_tyvar, 
-                      ptext SLIT("' does not appear in method signature:")])
-        4 (ppr sty sig)
-
-classTyVarInOpCtxtErr clas_tyvar sig sty
-  = hang (hcat [ ptext SLIT("Class type variable `"), ppr sty clas_tyvar, 
-                       ptext SLIT("' present in method's local overloading context:")])
+                      ptext SLIT("does not appear in method signature")])
         4 (ppr sty sig)
 
 dupClassAssertWarn ctxt dups sty
@@ -718,8 +717,16 @@ badDataCon name sty
 allOfNonTyVar ty sty
   = hsep [ptext SLIT("`All' applied to a non-type variable:"), ppr sty ty]
 
-ctxtErr doc tyvars sty
-  = hsep [ptext SLIT("Context constrains type variable(s)"), 
+ctxtErr1 doc tyvars sty
+  = hsep [ptext SLIT("Context constrains in-scope type variable(s)"), 
          hsep (punctuate comma (map (ppr sty) tyvars))]
-    $$ nest 4 (ptext SLIT("in") <+> doc sty)
+    $$
+    nest 4 (ptext SLIT("in") <+> doc sty)
+
+ctxtErr2 doc tyvars ty sty
+  = (ptext SLIT("Context constrains type variable(s)")
+       <+> hsep (punctuate comma (map (ppr sty) tyvars)))
+    $$
+    nest 4 (vcat [ptext SLIT("that do not appear in") <+> ppr sty ty,
+                 ptext SLIT("in") <+> doc sty])
 \end{code}
diff --git a/ghc/compiler/tests/rename/rn019.hs b/ghc/compiler/tests/rename/rn019.hs
new file mode 100644 (file)
index 0000000..4ff7c0d
--- /dev/null
@@ -0,0 +1,4 @@
+module Silly (
+       Array.accum
+  ) where
+import qualified Array
diff --git a/ghc/compiler/tests/rename/rn020.hs b/ghc/compiler/tests/rename/rn020.hs
new file mode 100644 (file)
index 0000000..4b9dbde
--- /dev/null
@@ -0,0 +1,11 @@
+-- Duplicate fields in record decls
+
+module OK where
+
+data X = A {a :: Int} | B {a :: Int}
+
+f x = x
+
+-- data Y = V {a :: Int}
+
+-- f y = y
diff --git a/ghc/compiler/tests/rename/rn021.hs b/ghc/compiler/tests/rename/rn021.hs
new file mode 100644 (file)
index 0000000..a9074e2
--- /dev/null
@@ -0,0 +1,17 @@
+{- Check that the context of a type does not
+   constrain any in-scope variables, and only constrains
+   type variables free in the type.
+-}
+
+module Foo where
+
+instance Eq a => Eq Bool where
+  (==) = error "help"
+
+
+f :: Eq a => Int -> Int
+f x = x
+
+
+class Foo a where
+  op :: Eq a => a -> a
diff --git a/ghc/compiler/tests/typecheck/should_fail/tcfail072.hs b/ghc/compiler/tests/typecheck/should_fail/tcfail072.hs
new file mode 100644 (file)
index 0000000..f7f57a7
--- /dev/null
@@ -0,0 +1,24 @@
+{- This program crashed GHC 2.03
+
+   From: Marc van Dongen <dongen@cs.ucc.ie>
+   Date: Sat, 31 May 1997 14:35:40 +0100 (BST)
+
+  zonkIdOcc: g_aoQ
+
+  panic! (the `impossible' happened):
+          lookupBindC:no info!
+  for: g_aoQ
+  (probably: data dependencies broken by an optimisation pass)
+  static binds for:
+  Tmp.$d1{-rmM,x-}
+  local binds for:
+-}
+
+module Tmp( g ) where
+
+data AB p q = A
+            | B p q
+
+g :: (Ord p,Ord q) => (AB p q) -> Bool
+g (B _ _) = g A
+
index ce60b0c..faa1911 100644 (file)
@@ -6,13 +6,14 @@ HS_SRCS = $(wildcard *.hs)
 SRC_RUNTEST_OPTS += -o1 $*.stdout -o2 $*.stderr -x 0
 HC_OPTS += -noC -ddump-tc -dcore-lint -hi
 
+# Expect failure.  Why aren't they in "should-fail"?
 tc075_RUNTEST_OPTS += -x 1
 tc080_RUNTEST_OPTS += -x 1
 
 %.o : %.hs
 
 %.o : %.hs
-       $(RUNTEST) $(HC) $(RUNTEST_OPTS) -- $(HC_OPTS) -c $< -o $@ -osuf $(subst .,,$(suffix $@)) 
+       $(RUNTEST) $(HC) $(RUNTEST_OPTS) -- $(HC_OPTS) -c $< -o $@ 
 
 all :: $(HS_OBJS)
 
diff --git a/ghc/compiler/tests/typecheck/should_succeed/tc086.hs b/ghc/compiler/tests/typecheck/should_succeed/tc086.hs
new file mode 100644 (file)
index 0000000..4d9ba6e
--- /dev/null
@@ -0,0 +1,60 @@
+{-
+  From: Marc van Dongen <dongen@cs.ucc.ie>
+  Date: Sat, 31 May 1997 19:57:46 +0100 (BST)
+
+   panic! (the `impossible' happened):
+           tcLookupTyVar:a_r6F
+
+   Please report it as a compiler bug to glasgow-haskell-bugs@dcs.gla.ac.uk.
+
+
+If the instance definition for (*) at the end of this toy module
+is replaced by the definition that is commented, this all compiles
+fine. Strange, because the two implementations are equivalent modulo
+the theory {(*) = multiply}.
+
+Remove the `multiply :: a -> a -> a' part, and it compiles without
+problems.
+
+
+SPJ note: the type signature on "multiply" should be
+       multiply :: Group a => a -> a -> a
+
+-}
+
+module Rings( Group, Ring ) where
+
+import qualified Prelude( Ord(..), Eq(..), Num(..) )
+import Prelude hiding( Ord(..), Eq(..), Num(..), MonadZero( zero ) )
+
+class Group a where
+  compare     :: a -> a -> Prelude.Ordering
+  fromInteger :: Integer -> a
+  (+) :: a -> a -> a
+  (-) :: a -> a -> a
+  zero :: a
+  one  :: a
+  zero = fromInteger 0
+  one  = fromInteger 1
+
+-- class (Group a) => Ring a where
+-- (*) :: a -> a -> a
+-- (*) a b =
+--                  case (compare a zero) of
+--                    EQ -> zero
+--                    LT -> zero - ((*) (zero - a) b)
+--                    GT -> case compare a one of
+--                            EQ -> b
+--                            _  -> b + ((*) (a - one) b)
+
+class (Group a) => Ring a where
+  (*) :: a -> a -> a
+  (*) a b = multiply a b
+          where multiply :: Group a => a -> a ->a 
+                multiply a b
+                  = case (compare a zero) of
+                      EQ -> zero
+                      LT -> zero - (multiply (zero - a) b)
+                      GT -> case compare a one of
+                              EQ -> b
+                              _  -> b + (multiply (a - one) b)
diff --git a/ghc/compiler/tests/typecheck/should_succeed/tc087.hs b/ghc/compiler/tests/typecheck/should_succeed/tc087.hs
new file mode 100644 (file)
index 0000000..8477427
--- /dev/null
@@ -0,0 +1,32 @@
+module SOL where
+
+import GlaExts
+
+data SeqView t a              =  Null
+                              |  Cons a (t a)
+
+class PriorityQueue q where
+    empty                      :: (Ord a) => q a
+    single                     :: (Ord a) => a -> q a
+    insert                     :: (Ord a) => a -> q a -> q a
+    meld                       :: (Ord a) => q a -> q a -> q a
+    splitMin                   :: (Ord a) => q a -> SeqView q a
+    insert a q         =  single a `meld` q
+
+toOrderedList q                =  case splitMin q of
+   Null                        -> []
+   Cons a q            -> a : toOrderedList q
+
+insertMany x q         =  foldr insert q x
+pqSort q x             =  toOrderedList (insertMany x q)
+
+check                  :: (PriorityQueue q) => (Ord a => q a) -> IO ()
+check empty            =  do
+    putStr "*** sorting\n"
+    out (pqSort empty [1 .. 99])
+    out (pqSort empty [1.0, 1.1 ..99.9])
+
+out                            :: (Num a) => [a] -> IO ()
+out x | sum x == 0             =  putStr "ok\n"
+      | otherwise              =  putStr "ok\n"
+
diff --git a/ghc/compiler/tests/typecheck/should_succeed/tc088.hs b/ghc/compiler/tests/typecheck/should_succeed/tc088.hs
new file mode 100644 (file)
index 0000000..e1b8b88
--- /dev/null
@@ -0,0 +1,18 @@
+-- Check that "->" is an instance of Eval
+
+module Foo where
+
+instance (Eq b) => Eq (a -> b) where
+       (==) f g = error "attempt to compare functions"
+
+       -- Since Eval is a superclass of Num this fails 
+       -- unless -> is an instance of Eval
+instance (Num b) => Num (a -> b) where
+    f + g                     =  \a -> f a + g a
+    f - g                     =  \a -> f a - g a
+    f * g                     =  \a -> f a * g a
+    negate f                  =  \a -> negate (f a)
+    abs f                     =  \a -> abs (f a)
+    signum f                  =  \a -> signum (f a)
+    fromInteger n             =  \a -> fromInteger n
+    fromInt n                 =  \a -> fromInt n
index 6e07406..9e23da4 100644 (file)
@@ -380,11 +380,14 @@ ppr_inst sty ppr_orig (LitInst u lit ty orig loc)
 
 ppr_inst sty ppr_orig (Dict u clas ty orig loc)
   = hang (ppr_orig orig loc)
-        4 (hsep [ppr sty clas, pprParendGenType sty ty, show_uniq sty u])
+        4 (pprQuote sty $ \ sty -> 
+           hsep [ppr sty clas, pprParendGenType sty ty, show_uniq sty u])
 
 ppr_inst sty ppr_orig (Method u id tys rho orig loc)
   = hang (ppr_orig orig loc)
-        4 (hsep [ppr sty id, ptext SLIT("at"), interppSP sty tys, show_uniq sty u])
+        4 (hsep [ppr sty id, ptext SLIT("at"), 
+                 pprQuote sty $ \ sty -> interppSP sty tys,
+                 show_uniq sty u])
 
 show_uniq PprDebug u = ppr PprDebug u
 show_uniq sty     u = empty
index 6aaedcd..8d988ab 100644 (file)
@@ -239,7 +239,7 @@ tcInstDecl1 mod_name (InstDecl poly_ty binds uprags (Just dfun_name) src_loc)
                                        other                      -> ([],  [],  poly_ty)
     (class_name, inst_ty) = case dict_ty of
                                MonoDictTy cls ty -> (cls,ty)
-                               other -> pprPanic "Malformed intance decl" (ppr PprDebug poly_ty)
+                               other -> pprPanic "Malformed instance decl" (ppr PprDebug poly_ty)
 \end{code}
 
 
index a5ca1dd..be45c99 100644 (file)
@@ -16,8 +16,9 @@ IMPORT_DELOOPER(TcLoop)               ( tcGRHSsAndBinds )
 import {-# SOURCE #-} TcGRHSs ( tcGRHSsAndBinds )
 #endif
 
-import HsSyn           ( Match(..), GRHSsAndBinds(..), GRHS(..), InPat,
-                         HsExpr, HsBinds, OutPat, Fake, Stmt,
+import HsSyn           ( Match(..), GRHSsAndBinds(..), GRHS(..), InPat, 
+                         HsExpr(..), HsBinds(..), MonoBinds(..), OutPat, Fake, Stmt,
+                         Sig, HsLit, DoOrListComp, Fixity, HsType, ArithSeqInfo, 
                          collectPatBinders, pprMatch )
 import RnHsSyn         ( SYN_IE(RenamedMatch) )
 import TcHsSyn         ( TcIdOcc(..), SYN_IE(TcMatch) )
@@ -27,12 +28,13 @@ import Inst         ( Inst, SYN_IE(LIE), plusLIE )
 import TcEnv           ( newMonoIds )
 import TcPat           ( tcPat )
 import TcType          ( SYN_IE(TcType), TcMaybe, zonkTcType )
+import TcSimplify      ( bindInstsOfLocalFuns )
 import Unify           ( unifyTauTy, unifyTauTyList )
 import Name            ( Name {- instance Outputable -} )
 
 import Kind            ( Kind, mkTypeKind )
 import Pretty
-import Type            ( isTyVarTy, mkFunTy, getFunTy_maybe )
+import Type            ( isTyVarTy, isTauTy, mkFunTy, getFunTy_maybe )
 import Util
 import Outputable
 #if __GLASGOW_HASKELL__ >= 202
@@ -149,16 +151,38 @@ tcMatchExpected expected_ty the_match@(PatMatch pat match)
        Just (arg_ty,rest_ty) ->        -- It's a function type!
            let binders = collectPatBinders pat
            in
-           newMonoIds binders mkTypeKind (\ _ ->
+           newMonoIds binders mkTypeKind (\ mono_ids ->
                tcPat pat                       `thenTc` \ (pat', lie_pat, pat_ty) ->
                unifyTauTy pat_ty arg_ty        `thenTc_`
                tcMatchExpected rest_ty  match  `thenTc` \ (match', lie_match) ->
-               returnTc (PatMatch pat' match',
-                         plusLIE lie_pat lie_match)
+
+                       -- In case there are any polymorpic, overloaded binders in the pattern
+                       -- (which can happen in the case of rank-2 type signatures, or data constructors
+                       -- with polymorphic arguments), we must dd a bindInstsOfLocalFns here
+                       --
+                       -- 99% of the time there are no bindings.  In the unusual case we
+                       -- march down the match to dump them in the right place (boring but easy).
+               bindInstsOfLocalFuns lie_match mono_ids         `thenTc` \ (lie_match', inst_mbinds) ->
+               let
+                  inst_binds = MonoBind inst_mbinds [] False
+                  match'' = case inst_mbinds of
+                               EmptyMonoBinds -> match'
+                               other          -> glue_on match'
+                  glue_on (PatMatch p m) = PatMatch p (glue_on m)
+                  glue_on (GRHSMatch (GRHSsAndBindsOut grhss binds ty))
+                       = (GRHSMatch (GRHSsAndBindsOut grhss 
+                                                      (inst_binds `ThenBinds` binds)
+                                                      ty))
+                  glue_on (SimpleMatch expr) = SimpleMatch (HsLet inst_binds expr)
+               in              
+               returnTc (PatMatch pat' match'',
+                         plusLIE lie_pat lie_match')
            )
 
 tcMatchExpected expected_ty (GRHSMatch grhss_and_binds)
   = tcGRHSsAndBinds grhss_and_binds    `thenTc` \ (grhss_and_binds', lie, grhss_ty) ->
+    checkTc (isTauTy expected_ty)
+           lurkingRank2SigErr          `thenTc_`
     unifyTauTy expected_ty grhss_ty    `thenTc_`
     returnTc (GRHSMatch grhss_and_binds', lie)
 
@@ -230,4 +254,7 @@ matchCtxt (MFun fun) match sty
 \begin{code}
 varyingArgsErr name matches sty
   = sep [ptext SLIT("Varying number of arguments for function"), ppr sty name]
+
+lurkingRank2SigErr sty
+  = ptext SLIT("Too few explicit arguments when defining a function with a rank-2 type")
 \end{code}
index 319e386..e550d1e 100644 (file)
@@ -303,6 +303,7 @@ plusFM_C combiner fm1 (Branch split_key elt2 _ left right)
 
 -- It's worth doing plusFM specially, because we don't need
 -- to do the lookup in fm1.
+-- FM2 over-rides FM1.
 
 plusFM EmptyFM fm2 = fm2
 plusFM fm1 EmptyFM = fm1