on master help sign in
First draft of cross-module type checking

Currently, all top-level types are imported. No alias resolution happens so you need to use "import open M" atm.

commitc140d690fcde3f511ddc62743531116c2acdb215 authorEvan Czaplicki <info@elm-lang.org> dateSun 21 Jul 2013, 22:50 (13 years ago) parent4bcde7e
4 files changed+25−14
compiler/Initialize.hs+7−7 compiler/SourceSyntax/Module.hs+3−1 compiler/Type/Environment.hs+5−2 compiler/Type/Inference.hs+10−4
compiler/Initialize.hs+7−7
@@ -1,4 +1,4 @@
1−module Initialize (buildFromSource, getSortedModuleNames, TypeLibrary) where
1+module Initialize (buildFromSource, getSortedModuleNames, Interfaces) where
22
33import qualified Data.Map as Map
44import Data.Data
@@ -17,15 +17,14 @@ import qualified Transform.SortDefinitions as SD
1717import qualified Type.Inference as TI
1818import qualified Type.Constrain.Declaration as TcDecl
1919
20−
21−type TypeLibrary = Map.Map String ModuleInterface
20+import System.IO.Unsafe
2221
2322buildFromSource ::
2423 (Data t, Data v) =>
25− TypeLibrary ->
24+ Interfaces ->
2625 String ->
2726 Either [Doc] (MetadataModule t v)
28−buildFromSource typeLibrary source =
27+buildFromSource interfaces source =
2928 do modul@(Module _ _ _ decls') <- Parse.program source
3029
3130 -- check for structural errors
@@ -42,14 +41,15 @@ buildFromSource typeLibrary source =
4241 -- reorder AST into strongly connected components
4342 program = SD.sortDefs . dummyLet $ TcDecl.toExpr decls,
4443 types = Map.empty,
45− datatypes = [ (name, vars, ctors) | Datatype name vars ctors <- decls ],
44+ datatypes = [ (name, vars, ctors) | Datatype name vars ctors <- decls ] ++
45+ concatMap iAdts (Map.elems interfaces),
4646 fixities = [ (assoc,level,op) | Fixity assoc level op <- decls ],
4747 aliases = [ (name,tvs,tipe) | TypeAlias name tvs tipe <- decls ],
4848 foreignImports = [ (evt,v,name,typ) | ImportEvent evt v name typ <- decls ],
4949 foreignExports = [ (evt,name,typ) | ExportEvent evt name typ <- decls ]
5050 }
5151
52− types <- TI.infer metaModule
52+ types <- TI.infer interfaces metaModule
5353
5454 return $ metaModule { types = types }
5555
compiler/SourceSyntax/Module.hs+3−1
@@ -37,9 +37,11 @@ data MetadataModule t v = MetadataModule {
3737 foreignExports :: [(String, String, Type)]
3838}
3939
40+type Interfaces = Map.Map String ModuleInterface
41+
4042data ModuleInterface = ModuleInterface {
4143 iTypes :: Map.Map String Type,
42− iAdts :: Map.Map String (Int, [String])
44+ iAdts :: [(String, [String], [(String,[Type])])]
4345} deriving Show
4446
4547instance Binary ModuleInterface where
compiler/Type/Environment.hs+5−2
@@ -22,11 +22,12 @@ initialEnvironment datatypes = do
2222 types <- makeTypes datatypes
2323
2424 return $ Environment {
25− constructor = makeConstructors types datatypes,
25+ constructor = makeConstructors types,
2626 types = types,
2727 value = Map.empty
2828 }
2929
30+makeTypes :: [(String, [String], [(String, [Src.Type])])] -> IO (Map.Map String Type)
3031makeTypes datatypes =
3132 Map.fromList <$> mapM makeCtor (builtins ++ map nameAndKind datatypes)
3233 where
@@ -46,7 +47,9 @@ makeTypes datatypes =
4647 , kind 0 ["Int","Float","Char","Bool","Element"]
4748 ]
4849
49−makeConstructors types datatypes = Map.fromList builtins
50+
51+makeConstructors :: Map.Map String Type -> Map.Map String (IO (Int, [Variable], Type))
52+makeConstructors types = Map.fromList builtins
5053 where
5154 list t = (types ! "_List") <| t
5255 maybe t = (types ! "Maybe") <| t
compiler/Type/Inference.hs+10−4
@@ -21,18 +21,24 @@ import System.IO.Unsafe -- Possible to switch over to the ST monad instead of
2121 -- the IO monad. Not sure if that'd be worthwhile.
2222
2323
24−infer :: MetadataModule t v -> Either [Doc] (Map.Map String T.Variable)
25−infer modul = unsafePerformIO $ do
24+infer :: Interfaces -> MetadataModule t v -> Either [Doc] (Map.Map String T.Variable)
25+infer interfaces modul = unsafePerformIO $ do
2626 env <- Env.initialEnvironment (datatypes modul)
2727 var <- T.flexibleVar
2828 ctors <- forM (Map.keys (Env.constructor env)) $ \name ->
2929 do (_, vars, tipe) <- Env.freshDataScheme env name
3030 return (name, (vars, tipe))
3131
32− let vars = concatMap (fst . snd) ctors
33− header = Map.map snd (Map.fromList ctors)
32+ importedVars <-
33+ forM (concatMap (Map.toList . iTypes) $ Map.elems interfaces) $ \(name,tipe) ->
34+ (,) name `fmap` Env.instantiateTypeWithContext env tipe Map.empty
35+
36+ let allTypes = ctors ++ importedVars
37+ vars = concatMap (fst . snd) allTypes
38+ header = Map.map snd (Map.fromList allTypes)
3439 environ = T.CLet [ T.Scheme vars [] T.CTrue header ]
3540 constraint <- environ `fmap` TcExpr.constrain env (program modul) (T.VarN var)
41+-- print =<< T.extraPretty constraint
3642 state <- execStateT (Solve.solve constraint) TS.initialState
3743 let errors = TS.sErrors state
3844 if null errors