Commit 5b746f52 authored by ian@well-typed.com's avatar ian@well-typed.com
Browse files

Merge branch 'master' of darcs.haskell.org:/srv/darcs//ghc

parents 3fc453af b0626b63
......@@ -14,7 +14,7 @@ module LoadIface (
-- IfM functions
loadInterface, loadWiredInHomeIface,
loadSysInterface, loadUserInterface,
loadSysInterface, loadUserInterface, loadPluginInterface,
findAndReadIface, readIface, -- Used when reading the module's old interface
loadDecls, -- Should move to TcIface and be renamed
initExternalPackageState,
......@@ -159,6 +159,10 @@ loadUserInterface :: Bool -> SDoc -> Module -> IfM lcl ModIface
loadUserInterface is_boot doc mod_name
= loadInterfaceWithException doc mod_name (ImportByUser is_boot)
loadPluginInterface :: SDoc -> Module -> IfM lcl ModIface
loadPluginInterface doc mod_name
= loadInterfaceWithException doc mod_name ImportByPlugin
------------------
-- | A wrapper for 'loadInterface' that throws an exception if it fails
loadInterfaceWithException :: SDoc -> Module -> WhereFrom -> IfM lcl ModIface
......@@ -267,32 +271,36 @@ loadInterface doc_str mod from
; updateEps_ $ \ eps ->
if elemModuleEnv mod (eps_PIT eps) then eps else
eps {
eps_PIT = extendModuleEnv (eps_PIT eps) mod final_iface,
eps_PTE = addDeclsToPTE (eps_PTE eps) new_eps_decls,
eps_rule_base = extendRuleBaseList (eps_rule_base eps)
new_eps_rules,
eps_inst_env = extendInstEnvList (eps_inst_env eps)
new_eps_insts,
eps_fam_inst_env = extendFamInstEnvList (eps_fam_inst_env eps)
new_eps_fam_insts,
eps_vect_info = plusVectInfo (eps_vect_info eps)
new_eps_vect_info,
eps_ann_env = extendAnnEnvList (eps_ann_env eps)
new_eps_anns,
eps_mod_fam_inst_env
= let
fam_inst_env =
extendFamInstEnvList emptyFamInstEnv
new_eps_fam_insts
in
extendModuleEnv (eps_mod_fam_inst_env eps)
mod
fam_inst_env,
eps_stats = addEpsInStats (eps_stats eps)
(length new_eps_decls)
(length new_eps_insts)
(length new_eps_rules) }
case from of -- See Note [Care with plugin imports]
ImportByPlugin -> eps {
eps_PIT = extendModuleEnv (eps_PIT eps) mod final_iface,
eps_PTE = addDeclsToPTE (eps_PTE eps) new_eps_decls}
_ -> eps {
eps_PIT = extendModuleEnv (eps_PIT eps) mod final_iface,
eps_PTE = addDeclsToPTE (eps_PTE eps) new_eps_decls,
eps_rule_base = extendRuleBaseList (eps_rule_base eps)
new_eps_rules,
eps_inst_env = extendInstEnvList (eps_inst_env eps)
new_eps_insts,
eps_fam_inst_env = extendFamInstEnvList (eps_fam_inst_env eps)
new_eps_fam_insts,
eps_vect_info = plusVectInfo (eps_vect_info eps)
new_eps_vect_info,
eps_ann_env = extendAnnEnvList (eps_ann_env eps)
new_eps_anns,
eps_mod_fam_inst_env
= let
fam_inst_env =
extendFamInstEnvList emptyFamInstEnv
new_eps_fam_insts
in
extendModuleEnv (eps_mod_fam_inst_env eps)
mod
fam_inst_env,
eps_stats = addEpsInStats (eps_stats eps)
(length new_eps_decls)
(length new_eps_insts)
(length new_eps_rules) }
; return (Succeeded final_iface)
}}}}
......@@ -307,6 +315,9 @@ wantHiBootFile dflags eps mod from
-> Failed (badSourceImport mod)
| otherwise -> Succeeded usr_boot
ImportByPlugin
-> Succeeded False
ImportBySystem
| not this_package -- If the module to be imported is not from this package
-> Succeeded False -- don't look it up in eps_is_boot, because that is keyed
......@@ -329,16 +340,25 @@ badSourceImport mod
<+> quotes (ppr (modulePackageId mod)))
\end{code}
{-
Used to be used for the loadInterface sanity check on system imports. That has been removed, but I'm leaving this in pending
review of this decision by SPJ - MCB 10/2008
Note [Care with plugin imports]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When dynamically loading a plugin (via loadPluginInterface) we
populate the same External Package State (EPS), even though plugin
modules are to link with the compiler itself, and not with the
compiled program. That's fine: mostly the EPS is just a cache for
the interace files on disk.
But it's NOT ok for the RULES or instance environment. We do not want
to fire a RULE from the plugin on the code we are compiling, otherwise
the code we are compiling will have a reference to a RHS of the rule
that exists only in the compiler! This actually happened to Daniel,
via a RULE arising from a specialisation of (^) in the plugin.
Solution: when loading plugins, do not extend the rule and instance
environments. We are only interested in the type environment, so that
we can check that the plugin exports a function with the type that the
compiler expects.
badDepMsg :: Module -> SDoc
badDepMsg mod
= hang (ptext (sLit "Interface file inconsistency:"))
2 (sep [ptext (sLit "home-package module") <+> quotes (ppr mod) <+> ptext (sLit "is needed,"),
ptext (sLit "but is not listed in the dependencies of the interfaces directly imported by the module being compiled")])
-}
\begin{code}
-----------------------------------------------------
......
......@@ -20,9 +20,8 @@ import Linker ( linkModule, getHValue )
import SrcLoc ( noSrcSpan )
import Finder ( findImportedModule, cannotFindModule )
import DriverPhases ( HscSource(HsSrcFile) )
import TcRnDriver ( getModuleInterface )
import TcRnMonad ( initTc, initIfaceTcRn )
import LoadIface ( loadUserInterface )
import LoadIface ( loadPluginInterface )
import RdrName ( RdrName, Provenance(..), ImportSpec(..), ImpDeclSpec(..)
, ImpItemSpec(..), mkGlobalRdrEnv, lookupGRE_RdrName, gre_name )
import RnNames ( gresFromAvails )
......@@ -50,7 +49,7 @@ import GHC.Exts ( unsafeCoerce# )
-- for debugging (@-ddump-if-trace@) only: it is shown as the reason why the module is being loaded.
forceLoadModuleInterfaces :: HscEnv -> SDoc -> [Module] -> IO ()
forceLoadModuleInterfaces hsc_env doc modules
= (initTc hsc_env HsSrcFile False iNTERACTIVE $ initIfaceTcRn $ mapM_ (loadUserInterface False doc) modules) >> return ()
= (initTc hsc_env HsSrcFile False iNTERACTIVE $ initIfaceTcRn $ mapM_ (loadPluginInterface doc) modules) >> return ()
-- | Force the interface for the module containing the name to be loaded. The 'SDoc' parameter is used
-- for debugging (@-ddump-if-trace@) only: it is shown as the reason why the module is being loaded.
......@@ -138,7 +137,7 @@ lookupRdrNameInModule hsc_env mod_name rdr_name = do
case found_module of
Found _ mod -> do
-- Find the exports of the module
(_, mb_iface) <- getModuleInterface hsc_env mod
(_, mb_iface) <- initTc hsc_env HsSrcFile False iNTERACTIVE $ initIfaceTcRn $ loadPluginInterface (ptext (sLit "contains a name used in an invocation of lookupRdrNameInModule")) mod
case mb_iface of
Just iface -> do
-- Try and find the required name in the exports
......
......@@ -836,11 +836,14 @@ The @WhereFrom@ type controls where the renamer looks for an interface file
data WhereFrom
= ImportByUser IsBootInterface -- Ordinary user import (perhaps {-# SOURCE #-})
| ImportBySystem -- Non user import.
| ImportByPlugin -- Importing a plugin;
-- See Note [Care with plugin imports] in LoadIface
instance Outputable WhereFrom where
ppr (ImportByUser is_boot) | is_boot = ptext (sLit "{- SOURCE -}")
| otherwise = empty
ppr ImportBySystem = ptext (sLit "{- SYSTEM -}")
ppr ImportByPlugin = ptext (sLit "{- PLUGIN -}")
\end{code}
%************************************************************************
......
......@@ -447,6 +447,7 @@ uf will get unified *once more* to (F Int).
\begin{code}
newtype Untouchables = Untouchables Int
-- See Note [Untouchable type variables] for what this Int is
noUntouchables :: Untouchables
noUntouchables = Untouchables 0 -- 0 = outermost level
......
......@@ -5530,8 +5530,9 @@ The following restrictions apply to promotion:
higher-kinded datatypes such as <literal>data Fix f = In (f (Fix f))</literal>,
or datatypes whose kinds involve promoted types such as
<literal>Vec :: * -> Nat -> *</literal>.</para></listitem>
<listitem><para>We do not promote datatypes whose constructors are kind
polymorphic, involve constraints, or use existential quantification.
<listitem><para>We do not promote data constructors that are kind
polymorphic, involve constraints, mention type or data families, or involve types that
are not promotable.
</para></listitem>
<listitem><para>We do not promote data family instances (<xref linkend="data-families"/>).
</para></listitem>
......@@ -5586,7 +5587,7 @@ Note that this requires <option>-XTypeOperators</option>.
<sect2 id="promoted-literals">
<title>Promoted Literals</title>
<para>
Numeric and string literals are prmoted to the type level, giving convenient
Numeric and string literals are promoted to the type level, giving convenient
access to a large number of predefined type-level constants. Numeric literals
are of kind <literal>Nat</literal>, while string literals are of kind
<literal>Symbol</literal>. These kinds are defined in the module
......@@ -5627,6 +5628,46 @@ example = from (Point 1 2) (Get :: Label "x")
</para>
</sect2>
<sect2 id="promotion-existentials">
<title>Promoting existential data constructors</title>
<para>
Note that we do promote existential data constructors that are otherwise suitable.
For example, consider the following:
<programlisting>
data Ex :: * where
MkEx :: forall a. a -> Ex
</programlisting>
Both the type <literal>Ex</literal> and the data constructor <literal>MkEx</literal>
get promoted, with the polymorphic kind <literal>'MkEx :: forall k. k -> Ex</literal>.
Somewhat surprisingly, you can write a type family to extract the member
of a type-level existential:
<programlisting>
type family UnEx (ex :: Ex) :: k
type instance UnEx (MkEx x) = x
</programlisting>
At first blush, <literal>UnEx</literal> seems poorly-kinded. The return kind
<literal>k</literal> is not mentioned in the arguments, and thus it would seem
that an instance would have to return a member of <literal>k</literal>
<emphasis>for any</emphasis> <literal>k</literal>. However, this is not the
case. The type family <literal>UnEx</literal> is a kind-indexed type family.
The return kind <literal>k</literal> is an implicit parameter to <literal>UnEx</literal>.
The elaborated definitions are as follows:
<programlisting>
type family UnEx (k :: BOX) (ex :: Ex) :: k
type instance UnEx k (MkEx k x) = x
</programlisting>
Thus, the instance triggers only when the implicit parameter to <literal>UnEx</literal>
matches the implicit parameter to <literal>MkEx</literal>. Because <literal>k</literal>
is actually a parameter to <literal>UnEx</literal>, the kind is not escaping the
existential, and the above code is valid.
</para>
<para>
See also <ulink url="http://hackage.haskell.org/trac/ghc/ticket/7347">Trac #7347</ulink>.
</para>
</sect2>
</sect1>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment