summaryrefslogtreecommitdiff
path: root/compiler/rename/RnExpr.lhs
diff options
context:
space:
mode:
authorsimonpj@microsoft.com <unknown>2010-10-07 11:10:51 +0000
committersimonpj@microsoft.com <unknown>2010-10-07 11:10:51 +0000
commit92267aa26adb1ab5a6d8004a80fdf6aa06ea4e44 (patch)
tree11ada6374af97f3a65b327221aec17368f3344b0 /compiler/rename/RnExpr.lhs
parent861e1d55126391785e93493080d3c7516812675e (diff)
downloadhaskell-92267aa26adb1ab5a6d8004a80fdf6aa06ea4e44.tar.gz
Implement auto-specialisation of imported Ids
This big-ish patch arranges that if an Id 'f' is * Type-class overloaded f :: Ord a => [a] -> [a] * Defined with an INLINABLE pragma {-# INLINABLE f #-} * Exported from its defining module 'D' then in any module 'U' that imports D 1. Any call of 'f' at a fixed type will generate (a) a specialised version of f in U (b) a RULE that rewrites unspecialised calls to the specialised on e.g. if the call is (f Int dOrdInt xs) then the specialiser will generate $sfInt :: [Int] -> [Int] $sfInt = <code for f, imported from D, specialised> {-# RULE forall d. f Int d = $sfInt #-} 2. In addition, you can give an explicit {-# SPECIALISE -#} pragma for the imported Id {-# SPECIALISE f :: [Bool] -> [Bool] #-} This too generates a local specialised definition, and the corresponding RULE The new RULES are exported from module 'U', so that any module importing U will see the specialised versions of 'f', and will not re-specialise them. There's a flag -fwarn-auto-orphan that warns you if the auto-generated RULES are orphan rules. It's not in -Wall, mainly to avoid lots of error messages with existing packages. Main implementation changes - A new flag on a CoreRule to say if it was auto-generated. This is persisted across interface files, so there's a small change in interface file format. - Quite a bit of fiddling with plumbing, to get the {-# SPECIALISE #-} pragmas for imported Ids. In particular, a new field tgc_imp_specs in TcGblEnv, to keep the specialise pragmas for imported Ids between the typechecker and the desugarer. - Some new code (although surprisingly little) in Specialise, to deal with calls of imported Ids
Diffstat (limited to 'compiler/rename/RnExpr.lhs')
-rw-r--r--compiler/rename/RnExpr.lhs6
1 files changed, 3 insertions, 3 deletions
diff --git a/compiler/rename/RnExpr.lhs b/compiler/rename/RnExpr.lhs
index 5598cc0580..4e8219555e 100644
--- a/compiler/rename/RnExpr.lhs
+++ b/compiler/rename/RnExpr.lhs
@@ -21,7 +21,7 @@ import {-# SOURCE #-} TcSplice( runQuasiQuoteExpr )
#endif /* GHCI */
import RnSource ( rnSrcDecls, findSplice )
-import RnBinds ( rnLocalBindsAndThen, rnValBindsLHS, rnValBindsRHS,
+import RnBinds ( rnLocalBindsAndThen, rnLocalValBindsLHS, rnLocalValBindsRHS,
rnMatchGroup, makeMiniFixityEnv)
import HsSyn
import TcRnMonad
@@ -931,7 +931,7 @@ rn_rec_stmt_lhs _ (L _ (LetStmt binds@(HsIPBinds _)))
= failWith (badIpBinds (ptext (sLit "an mdo expression")) binds)
rn_rec_stmt_lhs fix_env (L loc (LetStmt (HsValBinds binds)))
- = do (_bound_names, binds') <- rnValBindsLHS fix_env binds
+ = do (_bound_names, binds') <- rnLocalValBindsLHS fix_env binds
return [(L loc (LetStmt (HsValBinds binds')),
-- Warning: this is bogus; see function invariant
emptyFVs
@@ -995,7 +995,7 @@ rn_rec_stmt _ (L _ (LetStmt binds@(HsIPBinds _))) _
rn_rec_stmt all_bndrs (L loc (LetStmt (HsValBinds binds'))) _ = do
(binds', du_binds) <-
-- fixities and unused are handled above in rn_rec_stmts_and_then
- rnValBindsRHS (mkNameSet all_bndrs) binds'
+ rnLocalValBindsRHS (mkNameSet all_bndrs) binds'
return [(duDefs du_binds, allUses du_binds,
emptyNameSet, L loc (LetStmt (HsValBinds binds')))]