[project @ 1996-07-25 20:43:49 by partain]
[ghc-hetmet.git] / ghc / compiler / coreSyn / CoreLint.lhs
index 304b30e..99afabc 100644 (file)
@@ -11,18 +11,20 @@ module CoreLint (
        lintUnfolding
     ) where
 
-import Ubiq
+IMP_Ubiq()
 
 import CoreSyn
 
 import Bag
-import Kind            ( Kind{-instance-} )
+import Kind            ( hasMoreBoxityInfo, Kind{-instance-} )
 import Literal         ( literalType, Literal{-instance-} )
-import Id              ( idType, isBottomingId,
-                         dataConArgTys, GenId{-instances-}
+import Id              ( idType, isBottomingId, dataConRepType,
+                         dataConArgTys, GenId{-instances-},
+                         emptyIdSet, mkIdSet, intersectIdSets,
+                         unionIdSets, elementOfIdSet, SYN_IE(IdSet)
                        )
 import Maybes          ( catMaybes )
-import Name            ( isLocallyDefined, getSrcLoc )
+import Name            ( isLocallyDefined, getSrcLoc, Name{-instance NamedThing-} )
 import Outputable      ( Outputable(..){-instance * []-} )
 import PprCore
 import PprStyle                ( PprStyle(..) )
@@ -33,6 +35,7 @@ import PrimRep                ( PrimRep(..) )
 import SrcLoc          ( SrcLoc )
 import Type            ( mkFunTy,getFunTy_maybe,mkForAllTy,mkForAllTys,getForAllTy_maybe,
                          getFunTyExpandingDicts_maybe,
+                         getForAllTyExpandingDicts_maybe,
                          isPrimType,typeKind,instantiateTy,splitSigmaTy,
                          mkForAllUsageTy,getForAllUsageTy,instantiateUsage,
                          maybeAppDataTyConExpandingDicts, eqTy
@@ -40,11 +43,8 @@ import Type          ( mkFunTy,getFunTy_maybe,mkForAllTy,mkForAllTys,getForAllTy_maybe,
                        )
 import TyCon           ( isPrimTyCon )
 import TyVar           ( tyVarKind, GenTyVar{-instances-} )
-import UniqSet         ( emptyUniqSet, mkUniqSet, intersectUniqSets,
-                         unionUniqSets, elementOfUniqSet, UniqSet(..)
-                       )
 import Unique          ( Unique )
-import Usage           ( GenUsage )
+import Usage           ( GenUsage, SYN_IE(Usage) )
 import Util            ( zipEqual, pprTrace, pprPanic, assertPanic, panic )
 
 infixr 9 `thenL`, `seqL`, `thenMaybeL`, `seqMaybeL`
@@ -187,8 +187,7 @@ lintCoreExpr (Var var) = checkInScope var `seqL` returnL (Just (idType var))
 lintCoreExpr (Lit lit) = returnL (Just (literalType lit))
 lintCoreExpr (SCC _ expr) = lintCoreExpr expr
 lintCoreExpr (Coerce _ ty expr)
-  = _trace "lintCoreExpr:Coerce" $
-    lintCoreExpr expr `seqL` returnL (Just ty)
+  = lintCoreExpr expr `seqL` returnL (Just ty)
 
 lintCoreExpr (Let binds body)
   = lintCoreBinding binds `thenL` \binders ->
@@ -199,14 +198,8 @@ lintCoreExpr (Let binds body)
        (addInScopeVars binders (lintCoreExpr body))
 
 lintCoreExpr e@(Con con args)
-  = lintCoreArgs {-False-} e unoverloaded_ty args
+  = lintCoreArgs {-False-} e (dataConRepType con) args
     -- Note: we don't check for primitive types in these arguments
-  where
-       -- Constructors are special in that they aren't passed their
-       -- dictionary arguments, so we swizzle them out of the
-       -- constructor type before handing over to lintCorArgs
-    unoverloaded_ty = mkForAllTys tyvars tau
-    (tyvars, theta, tau) = splitSigmaTy (idType con)
 
 lintCoreExpr e@(Prim op args)
   = lintCoreArgs {-True-} e (primOpType op) args
@@ -265,7 +258,7 @@ lintCoreArg :: {-Bool ->-} CoreExpr -> Type -> CoreArg -> LintM (Maybe Type)
 
 lintCoreArg e ty (LitArg lit)
   = -- Make sure function type matches argument
-    case (getFunTyExpandingDicts_maybe ty) of
+    case (getFunTyExpandingDicts_maybe False{-no peeking in newtypes-} ty) of
       Just (arg,res) | (lit_ty `eqTy` arg) -> returnL(Just res)
       _ -> addErrL (mkAppMsg ty lit_ty e) `seqL` returnL Nothing
   where
@@ -275,7 +268,7 @@ lintCoreArg e ty (VarArg v)
   = -- Make sure variable is bound
     checkInScope v `seqL`
     -- Make sure function type matches argument
-    case (getFunTyExpandingDicts_maybe ty) of
+    case (getFunTyExpandingDicts_maybe False{-as above-} ty) of
       Just (arg,res) | (var_ty `eqTy` arg) -> returnL(Just res)
       _ -> addErrL (mkAppMsg ty var_ty e) `seqL` returnL Nothing
   where
@@ -285,7 +278,7 @@ lintCoreArg e ty a@(TyArg arg_ty)
   = -- ToDo: Check that ty is well-kinded and has no unbound tyvars
     checkIfSpecDoneL (not (isPrimType arg_ty)) (mkSpecTyAppMsg a)
     `seqL`
-    case (getForAllTy_maybe ty) of
+    case (getForAllTyExpandingDicts_maybe ty) of
       Nothing -> addErrL (mkTyAppMsg SLIT("Illegal") ty arg_ty e) `seqL` returnL Nothing
 
       Just (tyvar,body) ->
@@ -293,9 +286,11 @@ lintCoreArg e ty a@(TyArg arg_ty)
            tyvar_kind = tyVarKind tyvar
            argty_kind = typeKind arg_ty
        in
-       if tyvar_kind == argty_kind
--- SUSPICIOUS! (tyvar_kind `isSubKindOf` argty_kind
---              || argty_kind `isSubKindOf` tyvar_kind)
+       if argty_kind `hasMoreBoxityInfo` tyvar_kind
+               -- Arg type might be boxed for a function with an uncommitted
+               -- tyvar; notably this is used so that we can give
+               --      error :: forall a:*. String -> a
+               -- and then apply it to both boxed and unboxed types.
         then
            returnL(Just(instantiateTy [(tyvar,arg_ty)] body))
        else
@@ -406,7 +401,7 @@ lintDeflt deflt@(BindDefault binder rhs) ty
 \begin{code}
 type LintM a = Bool            -- True <=> specialisation has been done
            -> [LintLocInfo]    -- Locations
-           -> UniqSet Id       -- Local vars in scope
+           -> IdSet            -- Local vars in scope
            -> Bag ErrMsg       -- Error messages so far
            -> (a, Bag ErrMsg)  -- Result and error messages (if any)
 
@@ -443,7 +438,7 @@ pp_binder sty b = ppCat [ppr sty b, ppStr "::", ppr sty (idType b)]
 \begin{code}
 initL :: LintM a -> Bool -> Maybe ErrMsg
 initL m spec_done
-  = case (m spec_done [] emptyUniqSet emptyBag) of { (_, errs) ->
+  = case (m spec_done [] emptyIdSet emptyBag) of { (_, errs) ->
     if isEmptyBag errs then
        Nothing
     else
@@ -528,24 +523,27 @@ addInScopeVars ids m spec loc scope errs
     -- For now, it's just a "trace"; we may make
     -- a real error out of it...
     let
-       new_set = mkUniqSet ids
+       new_set = mkIdSet ids
 
-       shadowed = scope `intersectUniqSets` new_set
+--     shadowed = scope `intersectIdSets` new_set
     in
 --  After adding -fliberate-case, Simon decided he likes shadowed
 --  names after all.  WDP 94/07
 --  (if isEmptyUniqSet shadowed
 --  then id
 --  else pprTrace "Shadowed vars:" (ppr PprDebug (uniqSetToList shadowed))) (
-    m spec loc (scope `unionUniqSets` new_set) errs
+    m spec loc (scope `unionIdSets` new_set) errs
 --  )
 \end{code}
 
 \begin{code}
 checkInScope :: Id -> LintM ()
 checkInScope id spec loc scope errs
-  = if isLocallyDefined id && not (id `elementOfUniqSet` scope) then
-      ((),addErr errs (\sty -> ppCat [ppr sty id,ppStr "is out of scope"]) loc)
+  = let
+       id_name = getName id
+    in
+    if isLocallyDefined id_name && not (id `elementOfIdSet` scope) then
+      ((),addErr errs (\sty -> ppCat [ppr sty id, ppStr "is out of scope"]) loc)
     else
       ((),errs)