Skip to content
Snippets Groups Projects
Commit 8e3bfa9b authored by Simon Peyton Jones's avatar Simon Peyton Jones
Browse files

[project @ 1998-01-27 14:53:40 by simonpj]

Fix misleading type checker error msgs; fix broken floatBind in Simplify.lhs
parent 23e7d765
No related merge requests found
...@@ -947,7 +947,8 @@ simplNonRec env binder@(id,occ_info) rhs body_c body_ty ...@@ -947,7 +947,8 @@ simplNonRec env binder@(id,occ_info) rhs body_c body_ty
-- Try let-from-let -- Try let-from-let
simpl_bind env (Let bind rhs) | let_floating_ok simpl_bind env (Let bind rhs) | let_floating_ok
= tick LetFloatFromLet `thenSmpl_` = tick LetFloatFromLet `thenSmpl_`
simplBind env (fix_up_demandedness will_be_demanded bind) simplBind env (if will_be_demanded then bind
else un_demandify_bind bind)
(\env -> simpl_bind env rhs) body_ty (\env -> simpl_bind env rhs) body_ty
-- Try case-from-let; this deals with a strict let of error too -- Try case-from-let; this deals with a strict let of error too
...@@ -1276,7 +1277,8 @@ floatBind env top_level bind ...@@ -1276,7 +1277,8 @@ floatBind env top_level bind
returnSmpl binds' returnSmpl binds'
where where
(binds', _, n_extras) = fltBind bind binds' = fltBind bind
n_extras = sum (map no_of_binds binds') - no_of_binds bind
float_lets = switchIsSet env SimplFloatLetsExposingWHNF float_lets = switchIsSet env SimplFloatLetsExposingWHNF
always_float_let_from_let = switchIsSet env SimplAlwaysFloatLetsFromLets always_float_let_from_let = switchIsSet env SimplAlwaysFloatLetsFromLets
...@@ -1284,27 +1286,22 @@ floatBind env top_level bind ...@@ -1284,27 +1286,22 @@ floatBind env top_level bind
-- fltBind guarantees not to return leaky floats -- fltBind guarantees not to return leaky floats
-- and all the binders of the floats have had their demand-info zapped -- and all the binders of the floats have had their demand-info zapped
fltBind (NonRec bndr rhs) fltBind (NonRec bndr rhs)
= (binds ++ [NonRec (un_demandify bndr) rhs'], = binds ++ [NonRec bndr rhs']
leakFree bndr rhs',
length binds)
where where
(binds, rhs') = fltRhs rhs (binds, rhs') = fltRhs rhs
fltBind (Rec pairs) fltBind (Rec pairs)
= ([Rec (extras = [Rec pairs']
++
binders `zip` rhss')],
and (zipWith leakFree binders rhss'),
length extras
)
where where
(binders, rhss) = unzip pairs pairs' = concat [ let
(binds_s, rhss') = mapAndUnzip fltRhs rhss (binds, rhs') = fltRhs rhs
extras = concat (map get_pairs (concat binds_s)) in
foldr get_pairs [(bndr, rhs')] binds
get_pairs (NonRec bndr rhs) = [(bndr,rhs)] | (bndr, rhs) <- pairs
get_pairs (Rec pairs) = pairs ]
get_pairs (NonRec bndr rhs) rest = (bndr,rhs) : rest
get_pairs (Rec pairs) rest = pairs ++ rest
-- fltRhs has same invariant as fltBind -- fltRhs has same invariant as fltBind
fltRhs rhs fltRhs rhs
...@@ -1322,12 +1319,19 @@ floatBind env top_level bind ...@@ -1322,12 +1319,19 @@ floatBind env top_level bind
-- fltExpr guarantees not to return leaky floats -- fltExpr guarantees not to return leaky floats
= (binds' ++ body_binds, body') = (binds' ++ body_binds, body')
where where
(body_binds, body') = fltExpr body binds_wont_leak = all leakFreeBind binds'
(binds', binds_wont_leak, _) = fltBind bind (body_binds, body') = fltExpr body
binds' = fltBind (un_demandify_bind bind)
fltExpr expr = ([], expr) fltExpr expr = ([], expr)
-- Crude but effective -- Crude but effective
no_of_binds (NonRec _ _) = 1
no_of_binds (Rec pairs) = length pairs
leakFreeBind (NonRec bndr rhs) = leakFree bndr rhs
leakFreeBind (Rec pairs) = and [leakFree bndr rhs | (bndr, rhs) <- pairs]
leakFree (id,_) rhs = case getIdArity id of leakFree (id,_) rhs = case getIdArity id of
ArityAtLeast n | n > 0 -> True ArityAtLeast n | n > 0 -> True
ArityExactly n | n > 0 -> True ArityExactly n | n > 0 -> True
...@@ -1358,16 +1362,14 @@ simplArg env (VarArg id) = lookupId env id ...@@ -1358,16 +1362,14 @@ simplArg env (VarArg id) = lookupId env id
\begin{code} \begin{code}
-- fix_up_demandedness switches off the willBeDemanded Info field -- un_demandify_bind switches off the willBeDemanded Info field
-- for bindings floated out of a non-demanded let -- for bindings floated out of a non-demanded let
fix_up_demandedness True {- Will be demanded -} bind un_demandify_bind (NonRec binder rhs)
= bind -- Simple; no change to demand info needed = NonRec (un_demandify_bndr binder) rhs
fix_up_demandedness False {- May not be demanded -} (NonRec binder rhs) un_demandify_bind (Rec pairs)
= NonRec (un_demandify binder) rhs = Rec [(un_demandify_bndr binder, rhs) | (binder,rhs) <- pairs]
fix_up_demandedness False {- May not be demanded -} (Rec pairs)
= Rec [(un_demandify binder, rhs) | (binder,rhs) <- pairs] un_demandify_bndr (id, occ_info) = (id `addIdDemandInfo` noDemandInfo, occ_info)
un_demandify (id, occ_info) = (id `addIdDemandInfo` noDemandInfo, occ_info)
is_cheap_prim_app (Prim op _) = primOpOkForSpeculation op is_cheap_prim_app (Prim op _) = primOpOkForSpeculation op
is_cheap_prim_app other = False is_cheap_prim_app other = False
......
...@@ -99,7 +99,7 @@ tcExpr :: RenamedHsExpr -- Expession to type check ...@@ -99,7 +99,7 @@ tcExpr :: RenamedHsExpr -- Expession to type check
\begin{code} \begin{code}
tcExpr (HsVar name) res_ty tcExpr (HsVar name) res_ty
= tcId name `thenNF_Tc` \ (expr', lie, id_ty) -> = tcId name `thenNF_Tc` \ (expr', lie, id_ty) ->
unifyTauTy id_ty res_ty `thenTc_` unifyTauTy res_ty id_ty `thenTc_`
-- Check that the result type doesn't have any nested for-alls. -- Check that the result type doesn't have any nested for-alls.
-- For example, a "build" on its own is no good; it must be -- For example, a "build" on its own is no good; it must be
...@@ -306,16 +306,24 @@ tcExpr (HsLet binds expr) res_ty ...@@ -306,16 +306,24 @@ tcExpr (HsLet binds expr) res_ty
returnTc (expr', lie) returnTc (expr', lie)
combiner is_rec bind expr = HsLet (MonoBind bind [] is_rec) expr combiner is_rec bind expr = HsLet (MonoBind bind [] is_rec) expr
tcExpr in_expr@(HsCase expr matches src_loc) res_ty tcExpr in_expr@(HsCase scrut matches src_loc) res_ty
= tcAddSrcLoc src_loc $ = tcAddSrcLoc src_loc $
newTyVarTy mkTypeKind `thenNF_Tc` \ expr_ty -> tcAddErrCtxt (caseCtxt in_expr) $
tcExpr expr expr_ty `thenTc` \ (expr',lie1) ->
-- Typecheck the case alternatives first.
-- The case patterns tend to give good type info to use
-- when typechecking the scrutinee. For example
-- case (map f) of
-- (x:xs) -> ...
-- will report that map is applied to too few arguments
tcAddErrCtxt (caseCtxt in_expr) $ tcMatchesCase res_ty matches `thenTc` \ (scrut_ty, matches', lie2) ->
tcMatchesCase (mkFunTy expr_ty res_ty) matches
`thenTc` \ (matches',lie2) ->
returnTc (HsCase expr' matches' src_loc, plusLIE lie1 lie2) tcAddErrCtxt (caseScrutCtxt scrut) (
tcExpr scrut scrut_ty
) `thenTc` \ (scrut',lie1) ->
returnTc (HsCase scrut' matches' src_loc, plusLIE lie1 lie2)
tcExpr (HsIf pred b1 b2 src_loc) res_ty tcExpr (HsIf pred b1 b2 src_loc) res_ty
= tcAddSrcLoc src_loc $ = tcAddSrcLoc src_loc $
...@@ -357,7 +365,7 @@ tcExpr (RecordCon con_name _ rbinds) res_ty ...@@ -357,7 +365,7 @@ tcExpr (RecordCon con_name _ rbinds) res_ty
in in
-- Con is syntactically constrained to be a data constructor -- Con is syntactically constrained to be a data constructor
ASSERT( maybeToBool (splitAlgTyConApp_maybe record_ty ) ) ASSERT( maybeToBool (splitAlgTyConApp_maybe record_ty ) )
unifyTauTy record_ty res_ty `thenTc_` unifyTauTy res_ty record_ty `thenTc_`
-- Check that the record bindings match the constructor -- Check that the record bindings match the constructor
let let
...@@ -432,7 +440,7 @@ tcExpr (RecordUpd record_expr rbinds) res_ty ...@@ -432,7 +440,7 @@ tcExpr (RecordUpd record_expr rbinds) res_ty
let let
result_record_ty = mkTyConApp tycon result_inst_tys result_record_ty = mkTyConApp tycon result_inst_tys
in in
unifyTauTy result_record_ty res_ty `thenTc_` unifyTauTy res_ty result_record_ty `thenTc_`
tcRecordBinds result_record_ty rbinds `thenTc` \ (rbinds', rbinds_lie) -> tcRecordBinds result_record_ty rbinds `thenTc` \ (rbinds', rbinds_lie) ->
-- STEP 4 -- STEP 4
...@@ -1034,6 +1042,9 @@ arithSeqCtxt expr ...@@ -1034,6 +1042,9 @@ arithSeqCtxt expr
caseCtxt expr caseCtxt expr
= hang (ptext SLIT("In the case expression:")) 4 (ppr expr) = hang (ptext SLIT("In the case expression:")) 4 (ppr expr)
caseScrutCtxt expr
= hang (ptext SLIT("In the scrutinee of a case expression:")) 4 (ppr expr)
exprSigCtxt expr exprSigCtxt expr
= hang (ptext SLIT("In an expression with a type signature:")) = hang (ptext SLIT("In an expression with a type signature:"))
4 (ppr expr) 4 (ppr expr)
......
...@@ -21,7 +21,7 @@ import TcMonad ...@@ -21,7 +21,7 @@ import TcMonad
import Inst ( Inst, LIE, plusLIE ) import Inst ( Inst, LIE, plusLIE )
import TcEnv ( TcIdOcc(..), newMonoIds ) import TcEnv ( TcIdOcc(..), newMonoIds )
import TcPat ( tcPat ) import TcPat ( tcPat )
import TcType ( TcType, TcMaybe, zonkTcType ) import TcType ( TcType, TcMaybe, zonkTcType, newTyVarTy )
import TcSimplify ( bindInstsOfLocalFuns ) import TcSimplify ( bindInstsOfLocalFuns )
import Unify ( unifyTauTy, unifyTauTyList, unifyFunTy ) import Unify ( unifyTauTy, unifyTauTyList, unifyFunTy )
import Name ( Name {- instance Outputable -} ) import Name ( Name {- instance Outputable -} )
...@@ -78,8 +78,16 @@ tcMatchesFun fun_name expected_ty matches@(first_match:_) ...@@ -78,8 +78,16 @@ tcMatchesFun fun_name expected_ty matches@(first_match:_)
parser guarantees that each equation has exactly one argument. parser guarantees that each equation has exactly one argument.
\begin{code} \begin{code}
tcMatchesCase :: TcType s -> [RenamedMatch] -> TcM s ([TcMatch s], LIE s) tcMatchesCase :: TcType s -- Type of whole case expressions
tcMatchesCase expected_ty matches = tcMatchesExpected expected_ty MCase matches -> [RenamedMatch] -- The case alternatives
-> TcM s (TcType s, -- Inferred type of the scrutinee
[TcMatch s], -- Translated alternatives
LIE s)
tcMatchesCase expr_ty matches
= newTyVarTy mkTypeKind `thenNF_Tc` \ scrut_ty ->
tcMatchesExpected (mkFunTy scrut_ty expr_ty) MCase matches `thenTc` \ (matches', lie) ->
returnTc (scrut_ty, matches', lie)
\end{code} \end{code}
......
...@@ -311,7 +311,7 @@ unifyFunTy ty ...@@ -311,7 +311,7 @@ unifyFunTy ty
unify_fun_ty_help ty -- Special cases failed, so revert to ordinary unification unify_fun_ty_help ty -- Special cases failed, so revert to ordinary unification
= newTyVarTy mkTypeKind `thenNF_Tc` \ arg -> = newTyVarTy mkTypeKind `thenNF_Tc` \ arg ->
newTyVarTy mkTypeKind `thenNF_Tc` \ res -> newTyVarTy mkTypeKind `thenNF_Tc` \ res ->
unifyTauTy (mkFunTy arg res) ty `thenTc_` unifyTauTy ty (mkFunTy arg res) `thenTc_`
returnTc (arg,res) returnTc (arg,res)
\end{code} \end{code}
...@@ -332,7 +332,7 @@ unifyListTy ty ...@@ -332,7 +332,7 @@ unifyListTy ty
unify_list_ty_help ty -- Revert to ordinary unification unify_list_ty_help ty -- Revert to ordinary unification
= newTyVarTy mkBoxedTypeKind `thenNF_Tc` \ elt_ty -> = newTyVarTy mkBoxedTypeKind `thenNF_Tc` \ elt_ty ->
unifyTauTy (mkListTy elt_ty) ty `thenTc_` unifyTauTy ty (mkListTy elt_ty) `thenTc_`
returnTc elt_ty returnTc elt_ty
\end{code} \end{code}
...@@ -353,7 +353,7 @@ unifyTupleTy arity ty ...@@ -353,7 +353,7 @@ unifyTupleTy arity ty
unify_tuple_ty_help arity ty unify_tuple_ty_help arity ty
= mapNF_Tc (\ _ -> newTyVarTy mkBoxedTypeKind) [1..arity] `thenNF_Tc` \ arg_tys -> = mapNF_Tc (\ _ -> newTyVarTy mkBoxedTypeKind) [1..arity] `thenNF_Tc` \ arg_tys ->
unifyTauTy (mkTupleTy arity arg_tys) ty `thenTc_` unifyTauTy ty (mkTupleTy arity arg_tys) `thenTc_`
returnTc arg_tys returnTc arg_tys
\end{code} \end{code}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment