2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
4 \section[CoreLint]{A ``lint'' pass to check for Core correctness}
7 #include "HsVersions.h"
16 import CmdLineOpts ( opt_PprUserLength )
20 import Kind ( hasMoreBoxityInfo, Kind{-instance-},
21 isTypeKind, isBoxedTypeKind {- TEMP --SOF -} )
22 import Literal ( literalType, Literal{-instance-} )
23 import Id ( idType, isBottomingId, dataConRepType, isDataCon, isNewCon,
24 dataConArgTys, GenId{-instances-},
25 emptyIdSet, mkIdSet, intersectIdSets,
26 unionIdSets, elementOfIdSet, SYN_IE(IdSet),
29 import Maybes ( catMaybes )
30 import Name ( isLocallyDefined, getSrcLoc, Name{-instance NamedThing-},
33 import Outputable ( PprStyle(..), Outputable(..) )
34 import PprType ( GenType, GenTyVar, TyCon )
36 import PrimOp ( primOpType, PrimOp(..) )
37 import PrimRep ( PrimRep(..) )
38 import SrcLoc ( SrcLoc )
39 import Type ( mkFunTy,getFunTy_maybe,mkForAllTy,mkForAllTys,getForAllTy_maybe,
40 getFunTyExpandingDicts_maybe,
41 getForAllTyExpandingDicts_maybe,
42 isPrimType,typeKind,instantiateTy,splitSigmaTy,
43 mkForAllUsageTy,getForAllUsageTy,instantiateUsage,
44 maybeAppDataTyConExpandingDicts, eqTy, SYN_IE(Type)
46 import TyCon ( isPrimTyCon, isDataTyCon )
47 import TyVar ( tyVarKind, GenTyVar{-instances-} )
48 import Unique ( Unique )
49 import Usage ( GenUsage, SYN_IE(Usage) )
50 import Util ( zipEqual, pprTrace, pprPanic, assertPanic, panic )
52 infixr 9 `thenL`, `seqL`, `thenMaybeL`, `seqMaybeL`
55 %************************************************************************
57 \subsection[lintCoreBindings]{@lintCoreBindings@: Top-level interface}
59 %************************************************************************
61 Checks that a set of core bindings is well-formed. The PprStyle and String
62 just control what we print in the event of an error. The Bool value
63 indicates whether we have done any specialisation yet (in which case we do
68 (b) Out-of-scope type variables
69 (c) Out-of-scope local variables
72 If we have done specialisation the we check that there are
73 (a) No top-level bindings of primitive (unboxed type)
78 -- Things are *not* OK if:
80 -- * Unsaturated type app before specialisation has been done;
82 -- * Oversaturated type app after specialisation (eta reduction
83 -- may well be happening...);
85 -- Note: checkTyApp is usually followed by a call to checkSpecTyApp.
90 :: PprStyle -> String -> Bool -> [CoreBinding] -> [CoreBinding]
92 lintCoreBindings sty whoDunnit spec_done binds
93 = case (initL (lint_binds binds) spec_done) of
97 text ("*** Core Lint Errors: in " ++ whoDunnit ++ " ***"),
99 ptext SLIT("*** Offending Program ***"),
100 vcat (map (pprCoreBinding sty) binds),
101 ptext SLIT("*** End of Offense ***")
104 lint_binds [] = returnL ()
105 lint_binds (bind:binds)
106 = lintCoreBinding bind `thenL` \binders ->
107 addInScopeVars binders (lint_binds binds)
110 %************************************************************************
112 \subsection[lintUnfolding]{lintUnfolding}
114 %************************************************************************
116 We use this to check all unfoldings that come in from interfaces
117 (it is very painful to catch errors otherwise):
120 lintUnfolding :: SrcLoc -> CoreExpr -> Maybe CoreExpr
122 lintUnfolding locn expr
124 (initL (addLoc (ImportedUnfolding locn) (lintCoreExpr expr))
125 True{-pretend spec done-})
129 pprTrace "WARNING: Discarded bad unfolding from interface:\n"
130 (vcat [msg (PprForUser opt_PprUserLength),
131 ptext SLIT("*** Bad unfolding ***"),
133 ptext SLIT("*** End unfolding ***")])
137 %************************************************************************
139 \subsection[lintCoreBinding]{lintCoreBinding}
141 %************************************************************************
143 Check a core binding, returning the list of variables bound.
146 lintCoreBinding :: CoreBinding -> LintM [Id]
148 lintCoreBinding (NonRec binder rhs)
149 = lintSingleBinding (binder,rhs) `seqL` returnL [binder]
151 lintCoreBinding (Rec pairs)
152 = addInScopeVars binders (
153 mapL lintSingleBinding pairs `seqL` returnL binders
156 binders = [b | (b,_) <- pairs]
158 lintSingleBinding (binder,rhs)
159 = addLoc (RhsOf binder) (
164 -- Check match to RHS type
166 Nothing -> returnL ()
167 Just ty -> checkTys (idType binder) ty (mkRhsMsg binder ty))
170 -- Check (not isPrimType)
171 checkIfSpecDoneL (not (isPrimType (idType binder)))
172 (mkRhsPrimMsg binder rhs)
174 -- We should check the unfolding, if any, but this is tricky because
175 -- the unfolding is a SimplifiableCoreExpr. Give up for now.
179 %************************************************************************
181 \subsection[lintCoreExpr]{lintCoreExpr}
183 %************************************************************************
186 lintCoreExpr :: CoreExpr -> LintM (Maybe Type) -- Nothing if error found
188 lintCoreExpr (Var var) = checkInScope var `seqL` returnL (Just (idType var))
189 lintCoreExpr (Lit lit) = returnL (Just (literalType lit))
190 lintCoreExpr (SCC _ expr) = lintCoreExpr expr
191 lintCoreExpr e@(Coerce coercion ty expr)
192 = lintCoercion e coercion `seqL`
193 lintCoreExpr expr `seqL` returnL (Just ty)
195 lintCoreExpr (Let binds body)
196 = lintCoreBinding binds `thenL` \binders ->
197 if (null binders) then
198 lintCoreExpr body -- Can't add a new source location
200 addLoc (BodyOfLetRec binders)
201 (addInScopeVars binders (lintCoreExpr body))
203 lintCoreExpr e@(Con con args)
204 = checkL (isDataCon con) (mkConErrMsg e) `seqL`
205 lintCoreArgs {-False-} e (dataConRepType con) args
206 -- Note: we don't check for primitive types in these arguments
208 lintCoreExpr e@(Prim op args)
209 = lintCoreArgs {-True-} e (primOpType op) args
210 -- Note: we do check for primitive types in these arguments
212 lintCoreExpr e@(App fun@(Var v) arg) | isBottomingId v
213 = lintCoreExpr fun `thenMaybeL` \ ty -> lintCoreArg {-False-} e ty arg
214 -- Note: we don't check for primitive types in argument to 'error'
216 lintCoreExpr e@(App fun arg)
217 = lintCoreExpr fun `thenMaybeL` \ty -> lintCoreArg {-True-} e ty arg
218 -- Note: we do check for primitive types in this argument
220 lintCoreExpr (Lam (ValBinder var) expr)
221 = addLoc (LambdaBodyOf var)
222 (addInScopeVars [var]
223 (lintCoreExpr expr `thenMaybeL` \ty ->
224 returnL (Just (mkFunTy (idType var) ty))))
226 lintCoreExpr (Lam (TyBinder tyvar) expr)
227 = lintCoreExpr expr `thenMaybeL` \ty ->
228 returnL (Just(mkForAllTy tyvar ty))
229 -- ToDo: Should add in-scope type variable at this point
231 lintCoreExpr e@(Case scrut alts)
232 = lintCoreExpr scrut `thenMaybeL` \ty ->
236 %************************************************************************
238 \subsection[lintCoreArgs]{lintCoreArgs}
240 %************************************************************************
242 The boolean argument indicates whether we should flag type
243 applications to primitive types as being errors.
246 lintCoreArgs :: {-Bool ->-} CoreExpr -> Type -> [CoreArg] -> LintM (Maybe Type)
248 lintCoreArgs _ ty [] = returnL (Just ty)
249 lintCoreArgs e ty (a : args)
250 = lintCoreArg e ty a `thenMaybeL` \ res ->
251 lintCoreArgs e res args
254 %************************************************************************
256 \subsection[lintCoreArg]{lintCoreArg}
258 %************************************************************************
261 lintCoreArg :: {-Bool ->-} CoreExpr -> Type -> CoreArg -> LintM (Maybe Type)
263 lintCoreArg e ty (LitArg lit)
264 = -- Make sure function type matches argument
265 case (getFunTyExpandingDicts_maybe False{-no peeking in newtypes-} ty) of
266 Just (arg,res) | (lit_ty `eqTy` arg) -> returnL(Just res)
267 _ -> addErrL (mkAppMsg ty lit_ty e) `seqL` returnL Nothing
269 lit_ty = literalType lit
271 lintCoreArg e ty (VarArg v)
272 = -- Make sure variable is bound
273 checkInScope v `seqL`
274 -- Make sure function type matches argument
275 case (getFunTyExpandingDicts_maybe False{-as above-} ty) of
276 Just (arg,res) | (var_ty `eqTy` arg) -> returnL(Just res)
277 _ -> addErrL (mkAppMsg ty var_ty e) `seqL` returnL Nothing
281 lintCoreArg e ty a@(TyArg arg_ty)
282 = -- ToDo: Check that ty is well-kinded and has no unbound tyvars
283 case (getForAllTyExpandingDicts_maybe ty) of
284 Nothing -> addErrL (mkTyAppMsg SLIT("Illegal") ty arg_ty e) `seqL` returnL Nothing
288 tyvar_kind = tyVarKind tyvar
289 argty_kind = typeKind arg_ty
291 if argty_kind `hasMoreBoxityInfo` tyvar_kind
292 -- Arg type might be boxed for a function with an uncommitted
293 -- tyvar; notably this is used so that we can give
294 -- error :: forall a:*. String -> a
295 -- and then apply it to both boxed and unboxed types.
297 returnL(Just(instantiateTy [(tyvar,arg_ty)] body))
299 pprTrace "lintCoreArg:kinds:" (hsep [ppr PprDebug tyvar_kind, ppr PprDebug argty_kind]) $
300 addErrL (mkTyAppMsg SLIT("Kinds not right in") ty arg_ty e) `seqL` returnL Nothing
302 lintCoreArg e ty (UsageArg u)
303 = -- ToDo: Check that usage has no unbound usage variables
304 case (getForAllUsageTy ty) of
305 Just (uvar,bounds,body) ->
306 -- ToDo: Check argument satisfies bounds
307 returnL(Just(panic "lintCoreArg:instantiateUsage uvar u body"))
308 _ -> addErrL (mkUsageAppMsg ty u e) `seqL` returnL Nothing
311 %************************************************************************
313 \subsection[lintCoreAlts]{lintCoreAlts}
315 %************************************************************************
318 lintCoreAlts :: CoreCaseAlts
319 -> Type -- Type of scrutinee
320 -- -> TyCon -- TyCon pinned on the case
321 -> LintM (Maybe Type) -- Type of alternatives
323 lintCoreAlts whole_alts@(AlgAlts alts deflt) ty --tycon
324 = -- Check tycon is not a primitive tycon
325 -- addErrIfL (isPrimTyCon tycon) (mkCasePrimMsg tycon)
327 -- Check we are scrutinising a proper datatype
329 -- addErrIfL (not (tyConFamilySize tycon >= 1)) (mkCaseAbstractMsg tycon)
332 `thenL` \maybe_deflt_ty ->
333 mapL (lintAlgAlt ty {-tycon-}) alts
334 `thenL` \maybe_alt_tys ->
335 -- Check the result types
336 case catMaybes (maybe_deflt_ty : maybe_alt_tys) of
337 [] -> returnL Nothing
339 (first_ty:tys) -> mapL check tys `seqL`
340 returnL (Just first_ty)
342 check ty = checkTys first_ty ty (mkCaseAltMsg whole_alts)
344 lintCoreAlts whole_alts@(PrimAlts alts deflt) ty --tycon
345 = -- Check tycon is a primitive tycon
346 -- addErrIfL (not (isPrimTyCon tycon)) (mkCaseNotPrimMsg tycon)
348 mapL (lintPrimAlt ty) alts
349 `thenL` \maybe_alt_tys ->
351 `thenL` \maybe_deflt_ty ->
352 -- Check the result types
353 case catMaybes (maybe_deflt_ty : maybe_alt_tys) of
354 [] -> returnL Nothing
356 (first_ty:tys) -> mapL check tys `seqL`
357 returnL (Just first_ty)
359 check ty = checkTys first_ty ty (mkCaseAltMsg whole_alts)
361 lintAlgAlt scrut_ty (con,args,rhs)
362 = (case maybeAppDataTyConExpandingDicts scrut_ty of
363 Just (tycon, tys_applied, cons) | isDataTyCon tycon ->
365 arg_tys = dataConArgTys con tys_applied
367 checkL (con `elem` cons) (mkAlgAltMsg2 scrut_ty con) `seqL`
368 checkL (length arg_tys == length args) (mkAlgAltMsg3 con args)
370 mapL check (zipEqual "lintAlgAlt" arg_tys args) `seqL`
373 other -> addErrL (mkAlgAltMsg1 scrut_ty)
375 addInScopeVars args (
379 check (ty, arg) = checkTys ty (idType arg) (mkAlgAltMsg4 ty arg)
381 -- elem: yes, the elem-list here can sometimes be long-ish,
382 -- but as it's use-once, probably not worth doing anything different
383 -- We give it its own copy, so it isn't overloaded.
385 elem x (y:ys) = x==y || elem x ys
387 lintPrimAlt ty alt@(lit,rhs)
388 = checkTys (literalType lit) ty (mkPrimAltMsg alt) `seqL`
391 lintDeflt NoDefault _ = returnL Nothing
392 lintDeflt deflt@(BindDefault binder rhs) ty
393 = checkTys (idType binder) ty (mkDefltMsg deflt) `seqL`
394 addInScopeVars [binder] (lintCoreExpr rhs)
397 %************************************************************************
399 \subsection[lint-coercion]{Coercion}
401 %************************************************************************
404 lintCoercion e (CoerceIn con) = check_con e con
405 lintCoercion e (CoerceOut con) = check_con e con
407 check_con e con = checkL (isNewCon con)
412 %************************************************************************
414 \subsection[lint-monad]{The Lint monad}
416 %************************************************************************
419 type LintM a = Bool -- True <=> specialisation has been done
420 -> [LintLocInfo] -- Locations
421 -> IdSet -- Local vars in scope
422 -> Bag ErrMsg -- Error messages so far
423 -> (a, Bag ErrMsg) -- Result and error messages (if any)
425 type ErrMsg = PprStyle -> Doc
428 = RhsOf Id -- The variable bound
429 | LambdaBodyOf Id -- The lambda-binder
430 | BodyOfLetRec [Id] -- One of the binders
431 | ImportedUnfolding SrcLoc -- Some imported unfolding (ToDo: say which)
433 instance Outputable LintLocInfo where
435 = hcat [ppr sty (getSrcLoc v), ptext SLIT(": [RHS of "), pp_binders sty [v], char ']']
437 ppr sty (LambdaBodyOf b)
438 = hcat [ppr sty (getSrcLoc b),
439 ptext SLIT(": [in body of lambda with binder "), pp_binder sty b, char ']']
441 ppr sty (BodyOfLetRec bs)
442 = hcat [ppr sty (getSrcLoc (head bs)),
443 ptext SLIT(": [in body of letrec with binders "), pp_binders sty bs, char ']']
445 ppr sty (ImportedUnfolding locn)
446 = (<>) (ppr sty locn) (ptext SLIT(": [in an imported unfolding]"))
448 pp_binders :: PprStyle -> [Id] -> Doc
449 pp_binders sty bs = sep (punctuate comma (map (pp_binder sty) bs))
451 pp_binder :: PprStyle -> Id -> Doc
452 pp_binder sty b = hsep [ppr sty b, text "::", ppr sty (idType b)]
456 initL :: LintM a -> Bool -> Maybe ErrMsg
458 = case (m spec_done [] emptyIdSet emptyBag) of { (_, errs) ->
459 if isEmptyBag errs then
463 vcat [ msg sty | msg <- bagToList errs ]
467 returnL :: a -> LintM a
468 returnL r spec loc scope errs = (r, errs)
470 thenL :: LintM a -> (a -> LintM b) -> LintM b
471 thenL m k spec loc scope errs
472 = case m spec loc scope errs of
473 (r, errs') -> k r spec loc scope errs'
475 seqL :: LintM a -> LintM b -> LintM b
476 seqL m k spec loc scope errs
477 = case m spec loc scope errs of
478 (_, errs') -> k spec loc scope errs'
480 thenMaybeL :: LintM (Maybe a) -> (a -> LintM (Maybe b)) -> LintM (Maybe b)
481 thenMaybeL m k spec loc scope errs
482 = case m spec loc scope errs of
483 (Nothing, errs2) -> (Nothing, errs2)
484 (Just r, errs2) -> k r spec loc scope errs2
486 seqMaybeL :: LintM (Maybe a) -> LintM (Maybe b) -> LintM (Maybe b)
487 seqMaybeL m k spec loc scope errs
488 = case m spec loc scope errs of
489 (Nothing, errs2) -> (Nothing, errs2)
490 (Just _, errs2) -> k spec loc scope errs2
492 mapL :: (a -> LintM b) -> [a] -> LintM [b]
493 mapL f [] = returnL []
496 mapL f xs `thenL` \ rs ->
499 mapMaybeL :: (a -> LintM (Maybe b)) -> [a] -> LintM (Maybe [b])
500 -- Returns Nothing if anything fails
501 mapMaybeL f [] = returnL (Just [])
503 = f x `thenMaybeL` \ r ->
504 mapMaybeL f xs `thenMaybeL` \ rs ->
505 returnL (Just (r:rs))
509 checkL :: Bool -> ErrMsg -> LintM ()
510 checkL True msg spec loc scope errs = ((), errs)
511 checkL False msg spec loc scope errs = ((), addErr errs msg loc)
513 checkIfSpecDoneL :: Bool -> ErrMsg -> LintM ()
514 checkIfSpecDoneL True msg spec loc scope errs = ((), errs)
515 checkIfSpecDoneL False msg True loc scope errs = ((), addErr errs msg loc)
516 checkIfSpecDoneL False msg False loc scope errs = ((), errs)
519 = if pred then addErrL spec else returnL ()
521 addErrL :: ErrMsg -> LintM ()
522 addErrL msg spec loc scope errs = ((), addErr errs msg loc)
524 addErr :: Bag ErrMsg -> ErrMsg -> [LintLocInfo] -> Bag ErrMsg
526 addErr errs_so_far msg locs
527 = ASSERT (not (null locs))
528 errs_so_far `snocBag` ( \ sty ->
529 hang (ppr sty (head locs)) 4 (msg sty)
532 addLoc :: LintLocInfo -> LintM a -> LintM a
533 addLoc extra_loc m spec loc scope errs
534 = m spec (extra_loc:loc) scope errs
536 addInScopeVars :: [Id] -> LintM a -> LintM a
537 addInScopeVars ids m spec loc scope errs
538 = -- We check if these "new" ids are already
539 -- in scope, i.e., we have *shadowing* going on.
540 -- For now, it's just a "trace"; we may make
541 -- a real error out of it...
543 new_set = mkIdSet ids
545 -- shadowed = scope `intersectIdSets` new_set
547 -- After adding -fliberate-case, Simon decided he likes shadowed
548 -- names after all. WDP 94/07
549 -- (if isEmptyUniqSet shadowed
551 -- else pprTrace "Shadowed vars:" (ppr PprDebug (uniqSetToList shadowed))) (
552 m spec loc (scope `unionIdSets` new_set) errs
557 checkInScope :: Id -> LintM ()
558 checkInScope id spec loc scope errs
562 if isLocallyDefined id_name && not (id `elementOfIdSet` scope) then
563 ((),addErr errs (\sty -> hsep [ppr sty id, ptext SLIT("is out of scope")]) loc)
567 checkTys :: Type -> Type -> ErrMsg -> LintM ()
568 checkTys ty1 ty2 msg spec loc scope errs
569 = if ty1 `eqTy` ty2 then ((), errs) else ((), addErr errs msg loc)
574 = ($$) (ptext SLIT("Application of newtype constructor:"))
578 = ($$) (ptext SLIT("Coercion using a datatype constructor:"))
582 mkCaseAltMsg :: CoreCaseAlts -> ErrMsg
583 mkCaseAltMsg alts sty
584 = ($$) (ptext SLIT("Type of case alternatives not the same:"))
587 mkCaseDataConMsg :: CoreExpr -> ErrMsg
588 mkCaseDataConMsg expr sty
589 = ($$) (ptext SLIT("A case scrutinee not of data constructor type:"))
592 mkCaseNotPrimMsg :: TyCon -> ErrMsg
593 mkCaseNotPrimMsg tycon sty
594 = ($$) (ptext SLIT("A primitive case on a non-primitive type:"))
597 mkCasePrimMsg :: TyCon -> ErrMsg
598 mkCasePrimMsg tycon sty
599 = ($$) (ptext SLIT("An algebraic case on a primitive type:"))
602 mkCaseAbstractMsg :: TyCon -> ErrMsg
603 mkCaseAbstractMsg tycon sty
604 = ($$) (ptext SLIT("An algebraic case on some weird type:"))
607 mkDefltMsg :: CoreCaseDefault -> ErrMsg
609 = ($$) (ptext SLIT("Binder in case default doesn't match type of scrutinee:"))
612 mkAppMsg :: Type -> Type -> CoreExpr -> ErrMsg
613 mkAppMsg fun arg expr sty
614 = vcat [ptext SLIT("Argument value doesn't match argument type:"),
615 hang (ptext SLIT("Fun type:")) 4 (ppr sty fun),
616 hang (ptext SLIT("Arg type:")) 4 (ppr sty arg),
617 hang (ptext SLIT("Expression:")) 4 (pp_expr sty expr)]
619 mkTyAppMsg :: FAST_STRING -> Type -> Type -> CoreExpr -> ErrMsg
620 mkTyAppMsg msg ty arg expr sty
621 = vcat [hsep [ptext msg, ptext SLIT("type application:")],
622 hang (ptext SLIT("Exp type:")) 4 (ppr sty ty),
623 hang (ptext SLIT("Arg type:")) 4 (ppr sty arg),
624 hang (ptext SLIT("Expression:")) 4 (pp_expr sty expr)]
626 mkUsageAppMsg :: Type -> Usage -> CoreExpr -> ErrMsg
627 mkUsageAppMsg ty u expr sty
628 = vcat [ptext SLIT("Illegal usage application:"),
629 hang (ptext SLIT("Exp type:")) 4 (ppr sty ty),
630 hang (ptext SLIT("Usage exp:")) 4 (ppr sty u),
631 hang (ptext SLIT("Expression:")) 4 (pp_expr sty expr)]
633 mkAlgAltMsg1 :: Type -> ErrMsg
635 = ($$) (text "In some case statement, type of scrutinee is not a data type:")
637 -- (($$) (ppr sty ty) (ppr sty (expandTy ty))) -- ToDo: rm
639 mkAlgAltMsg2 :: Type -> Id -> ErrMsg
640 mkAlgAltMsg2 ty con sty
642 text "In some algebraic case alternative, constructor is not a constructor of scrutinee type:",
647 mkAlgAltMsg3 :: Id -> [Id] -> ErrMsg
648 mkAlgAltMsg3 con alts sty
650 text "In some algebraic case alternative, number of arguments doesn't match constructor:",
655 mkAlgAltMsg4 :: Type -> Id -> ErrMsg
656 mkAlgAltMsg4 ty arg sty
658 text "In some algebraic case alternative, type of argument doesn't match data constructor:",
663 mkPrimAltMsg :: (Literal, CoreExpr) -> ErrMsg
666 (text "In a primitive case alternative, type of literal doesn't match type of scrutinee:")
669 mkRhsMsg :: Id -> Type -> ErrMsg
670 mkRhsMsg binder ty sty
672 [hsep [ptext SLIT("The type of this binder doesn't match the type of its RHS:"),
674 hsep [ptext SLIT("Binder's type:"), ppr sty (idType binder)],
675 hsep [ptext SLIT("Rhs type:"), ppr sty ty]]
677 mkRhsPrimMsg :: Id -> CoreExpr -> ErrMsg
678 mkRhsPrimMsg binder rhs sty
679 = vcat [hsep [ptext SLIT("The type of this binder is primitive:"),
681 hsep [ptext SLIT("Binder's type:"), ppr sty (idType binder)]
684 mkSpecTyAppMsg :: CoreArg -> ErrMsg
685 mkSpecTyAppMsg arg sty
687 (ptext SLIT("Unboxed types in a type application (after specialisation):"))
690 pp_expr :: PprStyle -> CoreExpr -> Doc
692 = pprCoreExpr sty (pprBigCoreBinder sty) (pprTypedCoreBinder sty) (pprTypedCoreBinder sty) expr