2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
4 \section[CoreLint]{A ``lint'' pass to check for Core correctness}
12 #include "HsVersions.h"
14 import IO ( hPutStr, stderr )
16 import CmdLineOpts ( opt_D_show_passes, opt_DoCoreLinting )
20 import Kind ( hasMoreBoxityInfo, Kind{-instance-} )
21 import Literal ( literalType, Literal{-instance-} )
22 import Id ( idType, isBottomingId, dataConRepType, isDataCon, isNewCon, isAlgCon,
23 dataConArgTys, GenId{-instances-},
25 unionIdSets, elementOfIdSet, IdSet,
28 import Maybes ( catMaybes )
29 import Name ( isLocallyDefined, getSrcLoc, Name{-instance NamedThing-},
32 import ErrUtils ( doIfSet, ghcExit )
33 import PrimOp ( primOpType )
34 import PrimRep ( PrimRep(..) )
35 import SrcLoc ( SrcLoc )
36 import Type ( mkFunTy, splitFunTy_maybe, mkForAllTy,
38 isUnpointedType, typeKind, instantiateTy,
39 splitAlgTyConApp_maybe, Type
41 import TyCon ( TyCon, isPrimTyCon, isDataTyCon )
42 import TyVar ( TyVar, tyVarKind, mkTyVarEnv )
43 import ErrUtils ( ErrMsg )
44 import Unique ( Unique )
45 import Util ( zipEqual )
48 infixr 9 `thenL`, `seqL`, `thenMaybeL`
51 %************************************************************************
53 \subsection[lintCoreBindings]{@lintCoreBindings@: Top-level interface}
55 %************************************************************************
57 Checks that a set of core bindings is well-formed. The PprStyle and String
58 just control what we print in the event of an error. The Bool value
59 indicates whether we have done any specialisation yet (in which case we do
64 (b) Out-of-scope type variables
65 (c) Out-of-scope local variables
68 If we have done specialisation the we check that there are
69 (a) No top-level bindings of primitive (unboxed type)
74 -- Things are *not* OK if:
76 -- * Unsaturated type app before specialisation has been done;
78 -- * Oversaturated type app after specialisation (eta reduction
79 -- may well be happening...);
81 -- Note: checkTyApp is usually followed by a call to checkSpecTyApp.
85 lintCoreBindings :: String -> Bool -> [CoreBinding] -> IO ()
87 lintCoreBindings whoDunnit spec_done binds
88 | not opt_DoCoreLinting
91 lintCoreBindings whoDunnit spec_done binds
92 = case (initL (lint_binds binds) spec_done) of
93 Nothing -> doIfSet opt_D_show_passes
94 (hPutStr stderr ("*** Core Linted result of " ++ whoDunnit ++ "\n"))
96 Just bad_news -> printDump (display bad_news) >>
99 lint_binds [] = returnL ()
100 lint_binds (bind:binds)
101 = lintCoreBinding bind `thenL` \binders ->
102 addInScopeVars binders (lint_binds binds)
106 text ("*** Core Lint Errors: in result of " ++ whoDunnit ++ " ***"),
108 ptext SLIT("*** Offending Program ***"),
109 pprCoreBindings binds,
110 ptext SLIT("*** End of Offense ***")
114 %************************************************************************
116 \subsection[lintUnfolding]{lintUnfolding}
118 %************************************************************************
120 We use this to check all unfoldings that come in from interfaces
121 (it is very painful to catch errors otherwise):
124 lintUnfolding :: SrcLoc -> CoreExpr -> Maybe CoreExpr
126 lintUnfolding locn expr
128 (initL (addLoc (ImportedUnfolding locn) (lintCoreExpr expr))
129 True{-pretend spec done-})
133 pprTrace "WARNING: Discarded bad unfolding from interface:\n"
135 ptext SLIT("*** Bad unfolding ***"),
137 ptext SLIT("*** End unfolding ***")])
141 %************************************************************************
143 \subsection[lintCoreBinding]{lintCoreBinding}
145 %************************************************************************
147 Check a core binding, returning the list of variables bound.
150 lintCoreBinding :: CoreBinding -> LintM [Id]
152 lintCoreBinding (NonRec binder rhs)
153 = lintSingleBinding (binder,rhs) `seqL` returnL [binder]
155 lintCoreBinding (Rec pairs)
156 = addInScopeVars binders (
157 mapL lintSingleBinding pairs `seqL` returnL binders
160 binders = [b | (b,_) <- pairs]
162 lintSingleBinding (binder,rhs)
163 = addLoc (RhsOf binder) (
168 -- Check match to RHS type
170 Nothing -> returnL ()
171 Just ty -> checkTys (idType binder) ty (mkRhsMsg binder ty))
174 -- Check (not isUnpointedType)
175 checkIfSpecDoneL (not (isUnpointedType (idType binder)))
176 (mkRhsPrimMsg binder rhs)
178 -- We should check the unfolding, if any, but this is tricky because
179 -- the unfolding is a SimplifiableCoreExpr. Give up for now.
183 %************************************************************************
185 \subsection[lintCoreExpr]{lintCoreExpr}
187 %************************************************************************
190 lintCoreExpr :: CoreExpr -> LintM (Maybe Type) -- Nothing if error found
192 lintCoreExpr (Var var)
193 | isAlgCon var = returnL (Just (idType var))
194 -- Micro-hack here... Class decls generate applications of their
195 -- dictionary constructor, but don't generate a binding for the
196 -- constructor (since it would never be used). After a single round
197 -- of simplification, these dictionary constructors have been
198 -- inlined (from their UnfoldInfo) to CoCons. Just between
199 -- desugaring and simplfication, though, they appear as naked, unbound
200 -- variables as the function in an application.
201 -- The hack here simply doesn't check for out-of-scope-ness for
202 -- data constructors (at least, in a function position).
204 | otherwise = checkInScope var `seqL` returnL (Just (idType var))
206 lintCoreExpr (Lit lit) = returnL (Just (literalType lit))
208 lintCoreExpr (Note (Coerce to_ty from_ty) expr)
209 = lintCoreExpr expr `thenMaybeL` \ expr_ty ->
211 lintTy from_ty `seqL`
212 checkTys from_ty expr_ty (mkCoerceErr from_ty expr_ty) `seqL`
215 lintCoreExpr (Note other_note expr)
218 lintCoreExpr (Let binds body)
219 = lintCoreBinding binds `thenL` \binders ->
220 if (null binders) then
221 lintCoreExpr body -- Can't add a new source location
223 addLoc (BodyOfLetRec binders)
224 (addInScopeVars binders (lintCoreExpr body))
226 lintCoreExpr e@(Con con args)
227 = checkL (isDataCon con) (mkConErrMsg e) `seqL`
228 lintCoreArgs {-False-} e (dataConRepType con) args
229 -- Note: we don't check for primitive types in these arguments
231 lintCoreExpr e@(Prim op args)
232 = lintCoreArgs {-True-} e (primOpType op) args
233 -- Note: we do check for primitive types in these arguments
235 lintCoreExpr e@(App fun@(Var v) arg) | isBottomingId v
236 = lintCoreExpr fun `thenMaybeL` \ ty -> lintCoreArg {-False-} e ty arg
237 -- Note: we don't check for primitive types in argument to 'error'
239 lintCoreExpr e@(App fun arg)
240 = lintCoreExpr fun `thenMaybeL` \ty -> lintCoreArg {-True-} e ty arg
241 -- Note: we do check for primitive types in this argument
243 lintCoreExpr (Lam (ValBinder var) expr)
244 = addLoc (LambdaBodyOf var)
245 (addInScopeVars [var]
246 (lintCoreExpr expr `thenMaybeL` \ty ->
247 returnL (Just (mkFunTy (idType var) ty))))
249 lintCoreExpr (Lam (TyBinder tyvar) expr)
250 = lintCoreExpr expr `thenMaybeL` \ty ->
251 returnL (Just(mkForAllTy tyvar ty))
252 -- ToDo: Should add in-scope type variable at this point
254 lintCoreExpr e@(Case scrut alts)
255 = lintCoreExpr scrut `thenMaybeL` \ty ->
259 %************************************************************************
261 \subsection[lintCoreArgs]{lintCoreArgs}
263 %************************************************************************
265 The boolean argument indicates whether we should flag type
266 applications to primitive types as being errors.
269 lintCoreArgs :: {-Bool ->-} CoreExpr -> Type -> [CoreArg] -> LintM (Maybe Type)
271 lintCoreArgs _ ty [] = returnL (Just ty)
272 lintCoreArgs e ty (a : args)
273 = lintCoreArg e ty a `thenMaybeL` \ res ->
274 lintCoreArgs e res args
277 %************************************************************************
279 \subsection[lintCoreArg]{lintCoreArg}
281 %************************************************************************
284 lintCoreArg :: {-Bool ->-} CoreExpr -> Type -> CoreArg -> LintM (Maybe Type)
286 lintCoreArg e ty (LitArg lit)
287 = -- Make sure function type matches argument
288 case (splitFunTy_maybe ty) of
289 Just (arg,res) | (lit_ty == arg) -> returnL(Just res)
290 _ -> addErrL (mkAppMsg ty lit_ty e) `seqL` returnL Nothing
292 lit_ty = literalType lit
294 lintCoreArg e ty (VarArg v)
295 = -- Make sure variable is bound
296 checkInScope v `seqL`
297 -- Make sure function type matches argument
298 case (splitFunTy_maybe ty) of
299 Just (arg,res) | (var_ty == arg) -> returnL(Just res)
300 _ -> addErrL (mkAppMsg ty var_ty e) `seqL` returnL Nothing
304 lintCoreArg e ty a@(TyArg arg_ty)
305 = lintTy arg_ty `seqL`
307 case (splitForAllTy_maybe ty) of
308 Nothing -> addErrL (mkTyAppMsg SLIT("Illegal") ty arg_ty e) `seqL` returnL Nothing
312 tyvar_kind = tyVarKind tyvar
313 argty_kind = typeKind arg_ty
315 if argty_kind `hasMoreBoxityInfo` tyvar_kind
316 -- Arg type might be boxed for a function with an uncommitted
317 -- tyvar; notably this is used so that we can give
318 -- error :: forall a:*. String -> a
319 -- and then apply it to both boxed and unboxed types.
321 returnL(Just(instantiateTy (mkTyVarEnv [(tyvar,arg_ty)]) body))
323 pprTrace "lintCoreArg:kinds:" (hsep [ppr tyvar_kind, ppr argty_kind]) $
324 addErrL (mkKindErrMsg tyvar arg_ty e) `seqL` returnL Nothing
327 %************************************************************************
329 \subsection[lintCoreAlts]{lintCoreAlts}
331 %************************************************************************
334 lintCoreAlts :: CoreCaseAlts
335 -> Type -- Type of scrutinee
336 -- -> TyCon -- TyCon pinned on the case
337 -> LintM (Maybe Type) -- Type of alternatives
339 lintCoreAlts whole_alts@(AlgAlts alts deflt) ty --tycon
340 = -- Check tycon is not a primitive tycon
341 -- addErrIfL (isPrimTyCon tycon) (mkCasePrimMsg tycon)
343 -- Check we are scrutinising a proper datatype
345 -- addErrIfL (not (tyConFamilySize tycon >= 1)) (mkCaseAbstractMsg tycon)
348 `thenL` \maybe_deflt_ty ->
349 mapL (lintAlgAlt ty {-tycon-}) alts
350 `thenL` \maybe_alt_tys ->
351 -- Check the result types
352 case catMaybes (maybe_deflt_ty : maybe_alt_tys) of
353 [] -> returnL Nothing
355 (first_ty:tys) -> mapL check tys `seqL`
356 returnL (Just first_ty)
358 check ty = checkTys first_ty ty (mkCaseAltMsg whole_alts)
360 lintCoreAlts whole_alts@(PrimAlts alts deflt) ty --tycon
361 = -- Check tycon is a primitive tycon
362 -- addErrIfL (not (isPrimTyCon tycon)) (mkCaseNotPrimMsg tycon)
364 mapL (lintPrimAlt ty) alts
365 `thenL` \maybe_alt_tys ->
367 `thenL` \maybe_deflt_ty ->
368 -- Check the result types
369 case catMaybes (maybe_deflt_ty : maybe_alt_tys) of
370 [] -> returnL Nothing
372 (first_ty:tys) -> mapL check tys `seqL`
373 returnL (Just first_ty)
375 check ty = checkTys first_ty ty (mkCaseAltMsg whole_alts)
377 lintAlgAlt scrut_ty (con,args,rhs)
378 = (case splitAlgTyConApp_maybe scrut_ty of
379 Just (tycon, tys_applied, cons) | isDataTyCon tycon ->
381 arg_tys = dataConArgTys con tys_applied
383 checkL (con `elem` cons) (mkAlgAltMsg2 scrut_ty con) `seqL`
384 checkL (length arg_tys == length args) (mkAlgAltMsg3 con args)
386 mapL check (zipEqual "lintAlgAlt" arg_tys args) `seqL`
389 other -> addErrL (mkAlgAltMsg1 scrut_ty)
391 addInScopeVars args (
395 check (ty, arg) = checkTys ty (idType arg) (mkAlgAltMsg4 ty arg)
397 -- elem: yes, the elem-list here can sometimes be long-ish,
398 -- but as it's use-once, probably not worth doing anything different
399 -- We give it its own copy, so it isn't overloaded.
401 elem x (y:ys) = x==y || elem x ys
403 lintPrimAlt ty alt@(lit,rhs)
404 = checkTys (literalType lit) ty (mkPrimAltMsg alt) `seqL`
407 lintDeflt NoDefault _ = returnL Nothing
408 lintDeflt deflt@(BindDefault binder rhs) ty
409 = checkTys (idType binder) ty (mkDefltMsg deflt) `seqL`
410 addInScopeVars [binder] (lintCoreExpr rhs)
413 %************************************************************************
415 \subsection[lint-types]{Types}
417 %************************************************************************
420 lintTy :: Type -> LintM ()
421 lintTy ty = returnL ()
422 -- ToDo: Check that ty is well-kinded and has no unbound tyvars
426 %************************************************************************
428 \subsection[lint-monad]{The Lint monad}
430 %************************************************************************
433 type LintM a = Bool -- True <=> specialisation has been done
434 -> [LintLocInfo] -- Locations
435 -> IdSet -- Local vars in scope
436 -> Bag ErrMsg -- Error messages so far
437 -> (a, Bag ErrMsg) -- Result and error messages (if any)
440 = RhsOf Id -- The variable bound
441 | LambdaBodyOf Id -- The lambda-binder
442 | BodyOfLetRec [Id] -- One of the binders
443 | ImportedUnfolding SrcLoc -- Some imported unfolding (ToDo: say which)
445 instance Outputable LintLocInfo where
447 = ppr (getSrcLoc v) <> colon <+>
448 brackets (ptext SLIT("RHS of") <+> pp_binders [v])
451 = ppr (getSrcLoc b) <> colon <+>
452 brackets (ptext SLIT("in body of lambda with binder") <+> pp_binder b)
454 ppr (BodyOfLetRec bs)
455 = ppr (getSrcLoc (head bs)) <> colon <+>
456 brackets (ptext SLIT("in body of letrec with binders") <+> pp_binders bs)
458 ppr (ImportedUnfolding locn)
459 = ppr locn <> colon <+>
460 brackets (ptext SLIT("in an imported unfolding"))
462 pp_binders :: [Id] -> SDoc
463 pp_binders bs = sep (punctuate comma (map pp_binder bs))
465 pp_binder :: Id -> SDoc
466 pp_binder b = hsep [ppr b, text "::", ppr (idType b)]
470 initL :: LintM a -> Bool -> Maybe ErrMsg
472 = case (m spec_done [] emptyIdSet emptyBag) of { (_, errs) ->
473 if isEmptyBag errs then
476 Just (vcat (bagToList errs))
479 returnL :: a -> LintM a
480 returnL r spec loc scope errs = (r, errs)
482 thenL :: LintM a -> (a -> LintM b) -> LintM b
483 thenL m k spec loc scope errs
484 = case m spec loc scope errs of
485 (r, errs') -> k r spec loc scope errs'
487 seqL :: LintM a -> LintM b -> LintM b
488 seqL m k spec loc scope errs
489 = case m spec loc scope errs of
490 (_, errs') -> k spec loc scope errs'
492 thenMaybeL :: LintM (Maybe a) -> (a -> LintM (Maybe b)) -> LintM (Maybe b)
493 thenMaybeL m k spec loc scope errs
494 = case m spec loc scope errs of
495 (Nothing, errs2) -> (Nothing, errs2)
496 (Just r, errs2) -> k r spec loc scope errs2
498 mapL :: (a -> LintM b) -> [a] -> LintM [b]
499 mapL f [] = returnL []
502 mapL f xs `thenL` \ rs ->
505 mapMaybeL :: (a -> LintM (Maybe b)) -> [a] -> LintM (Maybe [b])
506 -- Returns Nothing if anything fails
507 mapMaybeL f [] = returnL (Just [])
509 = f x `thenMaybeL` \ r ->
510 mapMaybeL f xs `thenMaybeL` \ rs ->
511 returnL (Just (r:rs))
515 checkL :: Bool -> ErrMsg -> LintM ()
516 checkL True msg spec loc scope errs = ((), errs)
517 checkL False msg spec loc scope errs = ((), addErr errs msg loc)
519 checkIfSpecDoneL :: Bool -> ErrMsg -> LintM ()
520 checkIfSpecDoneL True msg spec loc scope errs = ((), errs)
521 checkIfSpecDoneL False msg True loc scope errs = ((), addErr errs msg loc)
522 checkIfSpecDoneL False msg False loc scope errs = ((), errs)
524 addErrL :: ErrMsg -> LintM ()
525 addErrL msg spec loc scope errs = ((), addErr errs msg loc)
527 addErr :: Bag ErrMsg -> ErrMsg -> [LintLocInfo] -> Bag ErrMsg
529 addErr errs_so_far msg locs
530 = ASSERT (not (null locs))
531 errs_so_far `snocBag` (hang (ppr (head locs)) 4 msg)
533 addLoc :: LintLocInfo -> LintM a -> LintM a
534 addLoc extra_loc m spec loc scope errs
535 = m spec (extra_loc:loc) scope errs
537 addInScopeVars :: [Id] -> LintM a -> LintM a
538 addInScopeVars ids m spec loc scope errs
539 = -- We check if these "new" ids are already
540 -- in scope, i.e., we have *shadowing* going on.
541 -- For now, it's just a "trace"; we may make
542 -- a real error out of it...
544 new_set = mkIdSet ids
546 -- shadowed = scope `intersectIdSets` new_set
548 -- After adding -fliberate-case, Simon decided he likes shadowed
549 -- names after all. WDP 94/07
550 -- (if isEmptyUniqSet shadowed
552 -- else pprTrace "Shadowed vars:" (ppr (uniqSetToList shadowed))) (
553 m spec loc (scope `unionIdSets` new_set) errs
558 checkInScope :: Id -> LintM ()
559 checkInScope id spec loc scope errs
563 if isLocallyDefined id_name && not (id `elementOfIdSet` scope) then
564 ((), addErr errs (hsep [ppr id, ptext SLIT("is out of scope")]) loc)
568 checkTys :: Type -> Type -> ErrMsg -> LintM ()
569 checkTys ty1 ty2 msg spec loc scope errs
570 = if ty1 == ty2 then ((), errs) else ((), addErr errs msg loc)
575 = ($$) (ptext SLIT("Application of newtype constructor:"))
579 mkCaseAltMsg :: CoreCaseAlts -> ErrMsg
581 = ($$) (ptext SLIT("Type of case alternatives not the same:"))
584 mkCaseAbstractMsg :: TyCon -> ErrMsg
585 mkCaseAbstractMsg tycon
586 = ($$) (ptext SLIT("An algebraic case on some weird type:"))
589 mkDefltMsg :: CoreCaseDefault -> ErrMsg
591 = ($$) (ptext SLIT("Binder in case default doesn't match type of scrutinee:"))
594 mkAppMsg :: Type -> Type -> CoreExpr -> ErrMsg
595 mkAppMsg fun arg expr
596 = vcat [ptext SLIT("Argument value doesn't match argument type:"),
597 hang (ptext SLIT("Fun type:")) 4 (ppr fun),
598 hang (ptext SLIT("Arg type:")) 4 (ppr arg),
599 hang (ptext SLIT("Expression:")) 4 (pprCoreExpr expr)]
601 mkKindErrMsg :: TyVar -> Type -> CoreExpr -> ErrMsg
602 mkKindErrMsg tyvar arg_ty expr
603 = vcat [ptext SLIT("Kinds don't match in type application:"),
604 hang (ptext SLIT("Type variable:"))
605 4 (ppr tyvar <+> ptext SLIT("::") <+> ppr (tyVarKind tyvar)),
606 hang (ptext SLIT("Arg type:"))
607 4 (ppr arg_ty <+> ptext SLIT("::") <+> ppr (typeKind arg_ty)),
608 hang (ptext SLIT("Expression:")) 4 (pprCoreExpr expr)]
610 mkTyAppMsg :: FAST_STRING -> Type -> Type -> CoreExpr -> ErrMsg
611 mkTyAppMsg msg ty arg expr
612 = vcat [hsep [ptext msg, ptext SLIT("type application:")],
613 hang (ptext SLIT("Exp type:"))
614 4 (ppr ty <+> ptext SLIT("::") <+> ppr (typeKind ty)),
615 hang (ptext SLIT("Arg type:"))
616 4 (ppr arg <+> ptext SLIT("::") <+> ppr (typeKind arg)),
617 hang (ptext SLIT("Expression:")) 4 (pprCoreExpr expr)]
619 mkAlgAltMsg1 :: Type -> ErrMsg
621 = ($$) (text "In some case statement, type of scrutinee is not a data type:")
624 mkAlgAltMsg2 :: Type -> Id -> ErrMsg
627 text "In some algebraic case alternative, constructor is not a constructor of scrutinee type:",
632 mkAlgAltMsg3 :: Id -> [Id] -> ErrMsg
633 mkAlgAltMsg3 con alts
635 text "In some algebraic case alternative, number of arguments doesn't match constructor:",
640 mkAlgAltMsg4 :: Type -> Id -> ErrMsg
643 text "In some algebraic case alternative, type of argument doesn't match data constructor:",
648 mkPrimAltMsg :: (Literal, CoreExpr) -> ErrMsg
651 (text "In a primitive case alternative, type of literal doesn't match type of scrutinee:")
654 mkRhsMsg :: Id -> Type -> ErrMsg
657 [hsep [ptext SLIT("The type of this binder doesn't match the type of its RHS:"),
659 hsep [ptext SLIT("Binder's type:"), ppr (idType binder)],
660 hsep [ptext SLIT("Rhs type:"), ppr ty]]
662 mkRhsPrimMsg :: Id -> CoreExpr -> ErrMsg
663 mkRhsPrimMsg binder rhs
664 = vcat [hsep [ptext SLIT("The type of this binder is primitive:"),
666 hsep [ptext SLIT("Binder's type:"), ppr (idType binder)]
669 mkCoerceErr from_ty expr_ty
670 = vcat [ptext SLIT("From-type of Coerce differs from type of enclosed expression"),
671 ptext SLIT("From-type:") <+> ppr from_ty,
672 ptext SLIT("Type of enclosed expr:") <+> ppr expr_ty