summaryrefslogtreecommitdiff
path: root/ghc
diff options
context:
space:
mode:
authorsimonpj <unknown>1999-06-28 16:23:28 +0000
committersimonpj <unknown>1999-06-28 16:23:28 +0000
commit960223bfc3fd1c2ac4608b837fb83f3bc6b5fd16 (patch)
tree126460989881ffe3910df3c155f547bd940c9ba1 /ghc
parent9956bafe44c39e07dff0c569dedc5cef3b41dbc7 (diff)
downloadhaskell-960223bfc3fd1c2ac4608b837fb83f3bc6b5fd16.tar.gz
[project @ 1999-06-28 16:23:28 by simonpj]
Fix lost specialisations. There were two problems {-# SPECIALISE f :: Int -> Rational #-} fromIntegral = fromInteger . toInteger This generates fromIntegral_spec = fromIntegral d for some suitable dictionary d. But since fromIntegral is small, it got inlined into fromIntegral_spec, thus losing the specialised call (fromIntegral d) that was the whole raison d'etre of fromIntegral_spec. Haskish solution: add an inlne pragma for the _spec things: fromIntegral_spec = _inline_me (fromIntegral d) Now we won't inline inside. But this showed up a related problem. The typechecker tries to common up overloaded things, so it actually generates m = fromIntegral d fromIntegral_spec = _inline_me m which is pretty stupid. Using tcSimplifyToDicts (instead of tcSimplify) in TcBinds.tcSpecSigs fixes this.
Diffstat (limited to 'ghc')
-rw-r--r--ghc/compiler/typecheck/TcBinds.lhs11
1 files changed, 7 insertions, 4 deletions
diff --git a/ghc/compiler/typecheck/TcBinds.lhs b/ghc/compiler/typecheck/TcBinds.lhs
index a3177a29bd..3fb4cdf072 100644
--- a/ghc/compiler/typecheck/TcBinds.lhs
+++ b/ghc/compiler/typecheck/TcBinds.lhs
@@ -16,7 +16,7 @@ import HsSyn ( HsExpr(..), HsBinds(..), MonoBinds(..), Sig(..), InPat(..), Stmt
collectMonoBinders, andMonoBindList, andMonoBinds
)
import RnHsSyn ( RenamedHsBinds, RenamedSig, RenamedMonoBinds )
-import TcHsSyn ( TcHsBinds, TcMonoBinds, TcId, zonkId )
+import TcHsSyn ( TcHsBinds, TcMonoBinds, TcId, zonkId, mkHsLet )
import TcMonad
import Inst ( Inst, LIE, emptyLIE, mkLIE, plusLIE, plusLIEs, InstOrigin(..),
@@ -27,7 +27,7 @@ import TcEnv ( tcExtendLocalValEnv,
tcLookupTyCon,
tcGetGlobalTyVars, tcExtendGlobalTyVars
)
-import TcSimplify ( tcSimplify, tcSimplifyAndCheck )
+import TcSimplify ( tcSimplify, tcSimplifyAndCheck, tcSimplifyToDicts )
import TcMonoType ( tcHsType, checkSigTyVars,
TcSigInfo(..), tcTySig, maybeSig, sigCtxt
)
@@ -837,6 +837,9 @@ tcSpecSigs (SpecSig name poly_ty src_loc : sigs)
-- the spec-pragma-id at the same time
tcExpr (HsVar name) sig_ty `thenTc` \ (spec_expr, spec_lie) ->
+ -- Squeeze out any Methods (see comments with tcSimplifyToDicts)
+ tcSimplifyToDicts spec_lie `thenTc` \ (spec_lie1, spec_binds) ->
+
-- Just specialise "f" by building a SpecPragmaId binding
-- It is the thing that makes sure we don't prematurely
-- dead-code-eliminate the binding we are really interested in.
@@ -844,8 +847,8 @@ tcSpecSigs (SpecSig name poly_ty src_loc : sigs)
-- Do the rest and combine
tcSpecSigs sigs `thenTc` \ (binds_rest, lie_rest) ->
- returnTc (binds_rest `andMonoBinds` VarMonoBind spec_id spec_expr,
- lie_rest `plusLIE` spec_lie)
+ returnTc (binds_rest `andMonoBinds` VarMonoBind spec_id (mkHsLet spec_binds spec_expr),
+ lie_rest `plusLIE` spec_lie1)
tcSpecSigs (other_sig : sigs) = tcSpecSigs sigs
tcSpecSigs [] = returnTc (EmptyMonoBinds, emptyLIE)