@@ -6,19 +6,14 @@ module Type.Constrain.Expression
9−import Control.Arrow (second)
10−import qualified Control.Monad as Monad
11import qualified Data.Map.Strict as Map
9import qualified Data.Map.Strict as Map
12−import Data.Text (Text)
14import qualified AST.Canonical as Can
11import qualified AST.Canonical as Can
15import qualified AST.Module.Name as ModuleName
12import qualified AST.Module.Name as ModuleName
16import qualified AST.Utils.Shader as Shader
13import qualified AST.Utils.Shader as Shader
17−import qualified Data.Bag as Bag
18import qualified Data.Index as Index
14import qualified Data.Index as Index
19import qualified Elm.Name as N
15import qualified Elm.Name as N
20import qualified Reporting.Annotation as A
16import qualified Reporting.Annotation as A
21−import qualified Reporting.Error.Type as Error
22import qualified Reporting.Region as R
17import qualified Reporting.Region as R
23import Type.Constraint
18import Type.Constraint
24import qualified Type.Constrain.Pattern as Pattern
19import qualified Type.Constrain.Pattern as Pattern
@@ -29,73 +24,78 @@ import Type.Type as Type hiding (Descriptor(..))
29-- CONSTRAIN
24-- CONSTRAIN
32−-- The environment contains all known type variables.
27+-- As we step past type annotations, the free type variables are added to
28+-- the "rigid type variables" dict. Allowing sharing of rigid variables
29+-- between nested type annotations.
34−-- So if you have a top-level type annotation like (func : a -> b) then
31+-- So if you have a top-level type annotation like (func : a -> b) the RTV
35−-- the environment will hold variables for `a` and `b`
32+-- dictionary will hold variables for `a` and `b`
37−type Env = Map.Map N.Name Variable
35+ Map.Map N.Name Type
40−constrain :: Env -> R.Region -> Error.Context -> Can.Expr -> Type -> IO Constraint
38+constrain :: RTV -> Can.Expr -> Expectation -> IO Constraint
41−constrain env parentRegion context (A.A region expression) tipe =
39+constrain rtv (A.A region expression) expectation =
42 case expression of
40 case expression of
43 Can.VarLocal name ->
41 Can.VarLocal name ->
44− return (CLookup parentRegion context region name tipe)
42+ return (CLookup region name expectation)
46 Can.VarTopLevel _ name ->
44 Can.VarTopLevel _ name ->
47− return (CLookup parentRegion context region name tipe)
45+ return (CLookup region name expectation)
49 Can.VarKernel _ _ ->
47 Can.VarKernel _ _ ->
50 return CTrue
48 return CTrue
52 Can.VarForeign _ name annotation ->
50 Can.VarForeign _ name annotation ->
53− error "TODO figure out foreign types"
51+ return $ CInstance region (FuncName name) annotation expectation
55 Can.VarOperator op _ _ annotation ->
53 Can.VarOperator op _ _ annotation ->
56− error "TODO figure out foreign types"
54+ return $ CInstance region (OpName op) annotation expectation
58 Can.Str _ ->
56 Can.Str _ ->
59− return $ CEqual parentRegion context Error.String region Type.string tipe
57+ return $ CEqual region String Type.string expectation
61 Can.Chr _ ->
59 Can.Chr _ ->
62− return $ CEqual parentRegion context Error.Char region Type.char tipe
60+ return $ CEqual region Char Type.char expectation
64 Can.Int _ ->
62 Can.Int _ ->
65 do var <- mkFlexNumber
63 do var <- mkFlexNumber
66− return $ ex [var] $
64+ return $ ex [var] $ CEqual region Number (VarN var) expectation
67− CEqual parentRegion context Error.Number region (VarN var) tipe
69 Can.Float _ ->
66 Can.Float _ ->
70− return $ CEqual parentRegion context Error.Float region Type.float tipe
67+ return $ CEqual region Float Type.float expectation
72 Can.List elements ->
69 Can.List elements ->
73− constrainList env parentRegion context region elements tipe
70+ constrainList rtv region elements expectation
75 Can.Negate expr ->
72 Can.Negate expr ->
76 do numberVar <- mkFlexNumber
73 do numberVar <- mkFlexNumber
77 let numberType = VarN numberVar
74 let numberType = VarN numberVar
78− numberCon <- constrain env region Error.Negate expr numberType
75+ numberCon <- constrain rtv expr (FromContext region Negate numberType)
79− let negateCon = CEqual parentRegion context Error.Number region numberType tipe
76+ let negateCon = CEqual region Number numberType expectation
80 return $ ex [numberVar] $ CAnd [ numberCon, negateCon ]
77 return $ ex [numberVar] $ CAnd [ numberCon, negateCon ]
82− Can.Binop op home name annotation leftExpr rightExpr ->
79+ Can.Binop op _ _ annotation leftExpr rightExpr ->
83− constrainBinop env parentRegion context region op annotation leftExpr rightExpr tipe
80+ constrainBinop rtv region op annotation leftExpr rightExpr expectation
85− Can.Lambda args body ->
82+ Can.Lambda args _ body ->
86− constrainLambda parentRegion context env region args body tipe
83+ do (lambdaType, resultType, scheme) <- Pattern.constrainArgs args
84+ bodyCon <- constrain rtv body (NoExpectation resultType)
85+ let lambdaCon = CEqual region Lambda lambdaType expectation
86+ return $ CLet [scheme] $ CAnd [ bodyCon, lambdaCon ]
88 Can.Call func args ->
88 Can.Call func args ->
89− constrainCall env parentRegion context region func args tipe
89+ constrainCall rtv region func args expectation
91 Can.If branches finally ->
91 Can.If branches finally ->
92− constrainIf env parentRegion context region branches finally tipe
92+ constrainIf rtv region branches finally expectation
94 Can.Case expr branches ->
94 Can.Case expr branches ->
95− constrainCase env parentRegion context region expr branches tipe
95+ constrainCase rtv region expr branches expectation
97 Can.Let def body ->
97 Can.Let def body ->
98− constrainLet env parentRegion context region def body tipe
98+ constrainDef rtv def =<< constrain rtv body expectation
100 Can.LetRec defs body ->
100 Can.LetRec defs body ->
101 error "TODO let rec" defs body
101 error "TODO let rec" defs body
@@ -110,7 +110,7 @@ constrain env parentRegion context (A.A region expression) tipe =
110 let fieldType = VarN fieldVar
110 let fieldType = VarN fieldVar
111 let recordType = RecordN (Map.singleton field fieldType) extType
111 let recordType = RecordN (Map.singleton field fieldType) extType
112 return $ ex [ fieldVar, extVar ] $
112 return $ ex [ fieldVar, extVar ] $
113− CEqual parentRegion context (Error.Accessor field) region (FunN recordType fieldType) tipe
113+ CEqual region (Accessor field) (FunN recordType fieldType) expectation
115 Can.Access expr field ->
115 Can.Access expr field ->
116 do extVar <- mkFlexVar
116 do extVar <- mkFlexVar
@@ -118,179 +118,134 @@ constrain env parentRegion context (A.A region expression) tipe =
118 let extType = VarN extVar
118 let extType = VarN extVar
119 let fieldType = VarN fieldVar
119 let fieldType = VarN fieldVar
120 let recordType = RecordN (Map.singleton field fieldType) extType
120 let recordType = RecordN (Map.singleton field fieldType) extType
121− recordCon <- constrain env region (Error.RecordAccess field) expr recordType
123+ constrain rtv expr (FromContext region (RecordAccess field) recordType)
122 return $ ex [ fieldVar, extVar ] $
125 return $ ex [ fieldVar, extVar ] $
124 [ recordCon
127 [ recordCon
125− , CEqual parentRegion context (Error.Access field) region recordType tipe
128+ , CEqual region (Access field) recordType expectation
128 Can.Update expr fields ->
131 Can.Update expr fields ->
129− constrainUpdate env parentRegion context region expr fields tipe
132+ constrainUpdate rtv region expr fields expectation
131 Can.Record fields ->
134 Can.Record fields ->
132− constrainRecord env parentRegion context region fields tipe
135+ constrainRecord rtv region fields expectation
134 Can.Unit ->
137 Can.Unit ->
135− return $ CEqual parentRegion context Error.Unit region UnitN tipe
138+ return $ CEqual region Unit UnitN expectation
137 Can.Tuple a b maybeC ->
140 Can.Tuple a b maybeC ->
138− constrainTuple env parentRegion context region a b maybeC tipe
141+ constrainTuple rtv region a b maybeC expectation
140 Can.Shader _uid _src glType ->
143 Can.Shader _uid _src glType ->
141− constrainShader env parentRegion context region glType tipe
144+ constrainShader region glType expectation
145−-- CONSTRAIN LAMBDA
148+-- CONSTRAIN CALL
148−constrainLambda :: R.Region -> Error.Context -> Env -> R.Region -> Can.Args -> Can.Expr -> Type -> IO Constraint
151+constrainCall :: RTV -> R.Region -> Can.Expr -> [Can.Expr] -> Expectation -> IO Constraint
149−constrainLambda parentRegion context env lambdaRegion (Can.Args args _) body tipe =
152+constrainCall rtv region func args expectation =
150− constrainLambdaHelp parentRegion context env lambdaRegion args body [] Pattern.emptyState tipe
153+ do let maybeFuncName = getFuncName func
155+ funcVar <- mkFlexVar
156+ resultVar <- mkFlexVar
157+ let funcType = VarN funcVar
158+ let resultType = VarN resultVar
153−constrainLambdaHelp :: R.Region -> Error.Context -> Env -> R.Region -> [Can.Arg] -> Can.Expr -> [Type] -> Pattern.State -> Type -> IO Constraint
160+ funcCon <- constrain rtv func (NoExpectation funcType)
154−constrainLambdaHelp parentRegion context env lambdaRegion args body revArgTypes state tipe =
156− (Can.Arg index pattern) : otherArgs ->
157− do argVar <- mkFlexVar
158− let argType = VarN argVar
159− let newTypes = argType : revArgTypes
160− let lambdaContext = Error.PatternArg Error.UnknownCall index
161− newState <- Pattern.addConstraints lambdaRegion lambdaContext pattern argType state
162− constrainLambdaHelp parentRegion context env lambdaRegion otherArgs body newTypes newState tipe
164− [] ->
162+ (argVars, argTypes, argCons) <-
165− do resultVar <- mkFlexVar
163+ unzip3 <$> Index.indexedTraverse (constrainArg rtv region maybeFuncName) args
166− let resultType = VarN resultVar
167− let lambdaType = foldr (==>) resultType revArgTypes
168− let lambdaCon = CEqual parentRegion context Error.Lambda lambdaRegion lambdaType tipe
169− bodyCon <- constrain env lambdaRegion Error.LambdaBody body resultType
171− let (Pattern.State headers vars revCons) = state
165+ let arityType = foldr FunN resultType argTypes
172− let scheme = Scheme [] (resultVar : Bag.toList vars) headers (CAnd (reverse revCons))
166+ let resultCon = CEqual region (CallResult maybeFuncName) resultType expectation
174− return $ CLet [scheme] $ CAnd [ bodyCon, lambdaCon ]
168+ return $ ex (funcVar:resultVar:argVars) $
174+ , _eq = CAnd [ CAnd argCons, resultCon ]
175+ , _neq = constrainCallBackup rtv region maybeFuncName func args
180+constrainArg :: RTV -> R.Region -> Maybe FuncName -> Index.ZeroBased -> Can.Expr -> IO (Variable, Type, Constraint)
181+constrainArg rtv region maybeFuncName index arg =
182+ do argVar <- mkFlexVar
183+ let argType = VarN argVar
184+ argCon <- constrain rtv arg (FromContext region (CallArg maybeFuncName index) argType)
185+ return (argVar, argType, argCon)
188+constrainCallBackup :: RTV -> R.Region -> Maybe FuncName -> Can.Expr -> [Can.Expr] -> IO Constraint
189+constrainCallBackup rtv region maybeFuncName func args =
190+ do (argVars, argTypes, argCons) <-
191+ unzip3 <$> Index.indexedTraverse (constrainArg rtv region maybeFuncName) args
181−constrainCall :: Env -> R.Region -> Error.Context -> R.Region -> Can.Expr -> [Can.Expr] -> Type -> IO Constraint
193+ resultVar <- mkFlexVar
182−constrainCall env parentRegion context callRegion func args tipe =
194+ let resultType = VarN resultVar
183− do let callName = toCallName func
195+ let arityType = foldr FunN resultType argTypes
184− let (A.A lastArgRegion _) = last args
186− funcVar <- mkFlexVar
197+ funcCon <- constrain rtv func (FromContext region BadArity arityType)
187− let funcType = VarN funcVar
198+
188− funcCon <- constrain env callRegion Error.Whatever func funcType
199+ return $ ex (resultVar:argVars) $ CAnd [ CAnd argCons, funcCon ]
190− (vars, revCons, resultType) <-
201+
191− constrainCallHelp env callRegion callName lastArgRegion args Index.first [funcVar] funcType [funcCon]
202+getFuncName :: Can.Expr -> Maybe FuncName
193− let callCon = CEqual parentRegion context (Error.CallResult callName) callRegion resultType tipe
195− return $ ex vars $ CAnd (reverse (callCon:revCons))
208− -> IO ([Variable], [Constraint], Type)
209−constrainCallHelp env callRegion callName lastArgRegion args index vars funcType revCons =
212− return (vars, revCons, funcType)
214− arg@(A.A argRegion _) : otherArgs ->
215− do argVar <- mkFlexVar
216− resultVar <- mkFlexVar
217− let argType = VarN argVar
218− let resultType = VarN resultVar
221− let aRegion = R.merge argRegion lastArgRegion
222− let aContext = Error.CallArity callName index
223− let aCategory = Error.Call callName
224− let arityCon = CEqual callRegion aContext aCategory aRegion funcType (argType ==> resultType)
227− argCon <- constrain env callRegion (Error.CallArg callName index) arg argType
229− let newIndex = Index.next index
230− let newVars = argVar : resultVar : vars
231− let newCons = argCon : arityCon : revCons
232− constrainCallHelp env callRegion callName lastArgRegion otherArgs newIndex newVars resultType newCons
235−toCallName :: Can.Expr -> Error.CallName
236−toCallName (A.A _ expr) =
203+getFuncName (A.A _ expr) =
237 case expr of
204 case expr of
238 Can.VarLocal name ->
205 Can.VarLocal name ->
239− Error.FuncCall name
206+ Just (FuncName name)
241 Can.VarTopLevel _ name ->
208 Can.VarTopLevel _ name ->
242− Error.FuncCall name
209+ Just (FuncName name)
244 Can.VarKernel _ name ->
211 Can.VarKernel _ name ->
245− Error.FuncCall name
212+ Just (FuncName name)
247 Can.VarForeign _ name _ ->
214 Can.VarForeign _ name _ ->
248− Error.FuncCall name
215+ Just (FuncName name)
250 Can.VarOperator op _ _ _ ->
217 Can.VarOperator op _ _ _ ->
251− Error.OpCall op
218+ Just (OpName op)
253− Can.Accessor field ->
254− Error.AccessCall field
257− Error.UnknownCall
221+ Nothing
261-- CONSTRAIN BINOP
225-- CONSTRAIN BINOP
264−constrainBinop
228+constrainBinop :: RTV -> R.Region -> N.Name -> Can.Annotation -> Can.Expr -> Can.Expr -> Expectation -> IO Constraint
275−constrainBinop env parentRegion context opRegion op srcType leftExpr rightExpr tipe =
229+constrainBinop rtv region op annotation leftExpr rightExpr expectation =
276 do leftVar <- mkFlexVar
230 do leftVar <- mkFlexVar
277 rightVar <- mkFlexVar
231 rightVar <- mkFlexVar
278 answerVar <- mkFlexVar
232 answerVar <- mkFlexVar
279 let leftType = VarN leftVar
233 let leftType = VarN leftVar
280 let rightType = VarN rightVar
234 let rightType = VarN rightVar
281 let answerType = VarN answerVar
235 let answerType = VarN answerVar
236+ let binopType = leftType ==> rightType ==> answerType
283− let opCon = error "TODO CInstance" srcType (leftType ==> rightType ==> answerType)
238+ let opCon = CInstance region (OpName op) annotation (NoExpectation binopType)
285− leftCon <- constrain env opRegion (Error.OpLeft op) leftExpr leftType
240+ leftCon <- constrain rtv leftExpr (FromContext region (OpLeft op) leftType)
286− rightCon <- constrain env opRegion (Error.OpRight op) rightExpr rightType
241+ rightCon <- constrain rtv rightExpr (FromContext region (OpRight op) rightType)
288 return $ ex [ leftVar, rightVar, answerVar ] $
243 return $ ex [ leftVar, rightVar, answerVar ] $
291 , leftCon
246 , leftCon
292 , rightCon
247 , rightCon
293− , CEqual parentRegion context (Error.Call (Error.OpCall op)) opRegion answerType tipe
248+ , CEqual region (CallResult (Just (OpName op))) answerType expectation
@@ -298,96 +253,118 @@ constrainBinop env parentRegion context opRegion op srcType leftExpr rightExpr t
298-- CONSTRAIN LISTS
253-- CONSTRAIN LISTS
301−constrainList :: Env -> R.Region -> Error.Context -> R.Region -> [Can.Expr] -> Type -> IO Constraint
256+constrainList :: RTV -> R.Region -> [Can.Expr] -> Expectation -> IO Constraint
302−constrainList env parentRegion context listRegion entries tipe =
257+constrainList rtv region entries expectation =
303 do entryVar <- mkFlexVar
258 do entryVar <- mkFlexVar
304 let entryType = VarN entryVar
259 let entryType = VarN entryVar
305− entryCons <- Index.indexedTraverse (constrainListEntry env listRegion entryType) entries
306 let listType = AppN ModuleName.list N.list [entryType]
260 let listType = AppN ModuleName.list N.list [entryType]
263+ Index.indexedTraverse (constrainListEntry rtv region entryType) entries
307 return $ ex [entryVar] $
265 return $ ex [entryVar] $
309 [ CAnd entryCons
267 [ CAnd entryCons
310− , CEqual parentRegion context Error.List listRegion listType tipe
268+ , CEqual region List listType expectation
314−constrainListEntry :: Env -> R.Region -> Type -> Index.ZeroBased -> Can.Expr -> IO Constraint
272+constrainListEntry :: RTV -> R.Region -> Type -> Index.ZeroBased -> Can.Expr -> IO Constraint
315−constrainListEntry env listRegion tipe index expr =
273+constrainListEntry rtv region tipe index expr =
316− constrain env listRegion (Error.ListEntry index) expr tipe
274+ constrain rtv expr (FromContext region (ListEntry index) tipe)
321-- CONSTRAIN IF EXPRESSIONS
278-- CONSTRAIN IF EXPRESSIONS
324−constrainIf :: Env -> R.Region -> Error.Context -> R.Region -> [(Can.Expr, Can.Expr)] -> Can.Expr -> Type -> IO Constraint
281+constrainIf :: RTV -> R.Region -> [(Can.Expr, Can.Expr)] -> Can.Expr -> Expectation -> IO Constraint
325−constrainIf env parentRegion context ifRegion branches final tipe =
282+constrainIf rtv region branches final expectation =
326− do branchVar <- mkFlexVar
283+ do let boolExpect = FromContext region IfCondition Type.bool
327− let branchType = VarN branchVar
284+ let (conditions, exprs) = foldr (\(c,e) (cs,es) -> (c:cs,e:es)) ([],[final]) branches
329− branchCons <- Index.indexedTraverse (constrainIfBranch env ifRegion branchType) branches
286+ condCons <-
330− finalCon <- constrain env ifRegion (Error.IfBranchFinal (length branches)) final branchType
287+ traverse (\c -> constrain rtv c boolExpect) conditions
332− return $ ex [branchVar] $
289+ case expectation of
333− CAnd
290+ FromAnnotation name arity _ tipe ->
334− [ CAnd branchCons
291+ do branchCons <- Index.indexedForA exprs $ \index expr ->
335− , finalCon
292+ constrain rtv expr (FromAnnotation name arity (TypedIfBranch index) tipe)
336− , CEqual parentRegion context Error.If ifRegion branchType tipe
293+ return $
300+ do branchVar <- mkFlexVar
301+ let branchType = VarN branchVar
303+ branchCons <- Index.indexedForA exprs $ \index expr ->
304+ constrain rtv expr (FromContext region (IfBranch index) branchType)
306+ return $ ex [branchVar] $
310+ , CEqual region If branchType expectation
340−constrainIfBranch :: Env -> R.Region -> Type -> Index.ZeroBased -> (Can.Expr, Can.Expr) -> IO Constraint
341−constrainIfBranch env ifRegion branchType index (condition, branch) =
342− do condCon <- constrain env ifRegion Error.IfCondition condition Type.bool
343− branchCon <- constrain env ifRegion (Error.IfBranch index) branch branchType
344− return $ CAnd [ condCon, branchCon ]
347-- CONSTRAIN CASE EXPRESSIONS
315-- CONSTRAIN CASE EXPRESSIONS
350−constrainCase :: Env -> R.Region -> Error.Context -> R.Region -> Can.Expr -> [Can.CaseBranch] -> Type -> IO Constraint
318+constrainCase :: RTV -> R.Region -> Can.Expr -> [Can.CaseBranch] -> Expectation -> IO Constraint
351−constrainCase env parentRegion context caseRegion expr branches tipe =
319+constrainCase rtv region expr branches expectation =
352− do exprVar <- mkFlexVar
353− branchVar <- mkFlexVar
320+ do ptrnVar <- mkFlexVar
354− let exprType = VarN exprVar
321+ let ptrnType = VarN ptrnVar
355− let branchType = VarN branchVar
322+ exprCon <- constrain rtv expr (NoExpectation ptrnType)
357− exprCon <- constrain env caseRegion Error.CaseExpr expr exprType
324+ case expectation of
358− revCons <- constrainCaseHelp env caseRegion branches exprType branchType [exprCon]
325+ FromAnnotation name arity _ tipe ->
359− let caseCon = CEqual parentRegion context Error.Case caseRegion branchType tipe
326+ do branchCons <- Index.indexedForA branches $ \index branch ->
327+ constrainCaseBranch rtv branch
328+ (PatternExpectation region (PCaseMatch index) ptrnType)
329+ (FromAnnotation name arity (TypedCaseBranch index) tipe)
361− return $ ex [ exprVar, branchVar ] $ CAnd (reverse (caseCon:revCons))
331+ return $ ex [ptrnVar] $ CAnd (exprCon:branchCons)
334+ do branchVar <- mkFlexVar
335+ let branchType = VarN branchVar
337+ branchCons <- Index.indexedForA branches $ \index branch ->
338+ constrainCaseBranch rtv branch
339+ (PatternExpectation region (PCaseMatch index) ptrnType)
340+ (FromContext region (CaseBranch index) branchType)
365−constrainCaseHelp :: Env -> R.Region -> [Can.CaseBranch] -> Type -> Type -> [Constraint] -> IO [Constraint]
342+ return $ ex [ptrnVar,branchVar] $
366−constrainCaseHelp env caseRegion branches patternType exprType revCons =
343+ CAnd
367− case branches of
344+ [ exprCon
368− [] ->
345+ , CAnd branchCons
369− return revCons
346+ , CEqual region Case branchType expectation
371− (Can.CaseBranch index pattern destructors expr) : otherBranches ->
372− do (Pattern.State headers vars revCons) <-
373− Pattern.addConstraints caseRegion (Error.PatternCaseMatch index) pattern patternType Pattern.emptyState
375− exprCon <- constrain env caseRegion (Error.CaseBranch index) expr exprType
350+constrainCaseBranch :: RTV -> Can.CaseBranch -> PatternExpectation -> Expectation -> IO Constraint
376− let branchCon = CLet [ Scheme [] (Bag.toList vars) headers (CAnd (reverse revCons)) ] exprCon
351+constrainCaseBranch rtv (Can.CaseBranch pattern _ expr) pExpect bExpect =
377− constrainCaseHelp env caseRegion otherBranches patternType exprType (branchCon:revCons)
352+ do scheme <- Pattern.constrain pattern pExpect
353+ constraint <- constrain rtv expr bExpect
354+ return $ CLet [scheme] constraint
381-- CONSTRAIN RECORD
358-- CONSTRAIN RECORD
384−constrainRecord :: Env -> R.Region -> Error.Context -> R.Region -> Map.Map N.Name Can.Expr -> Type -> IO Constraint
361+constrainRecord :: RTV -> R.Region -> Map.Map N.Name Can.Expr -> Expectation -> IO Constraint
385−constrainRecord env parentRegion context recordRegion fields tipe =
362+constrainRecord rtv region fields expectation =
386− do dict <- Map.traverseWithKey (constrainField env recordRegion) fields
363+ do dict <- traverse (constrainField rtv) fields
388 let getType (_, t, _) = t
365 let getType (_, t, _) = t
389 let recordType = RecordN (Map.map getType dict) EmptyRecordN
366 let recordType = RecordN (Map.map getType dict) EmptyRecordN
390− let recordCon = CEqual parentRegion context Error.Record recordRegion recordType tipe
367+ let recordCon = CEqual region Record recordType expectation
392 let vars = Map.foldr (\(v,_,_) vs -> v:vs) [] dict
369 let vars = Map.foldr (\(v,_,_) vs -> v:vs) [] dict
393 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [recordCon] dict
370 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [recordCon] dict
@@ -395,11 +372,11 @@ constrainRecord env parentRegion context recordRegion fields tipe =
395 return $ ex vars (CAnd cons)
372 return $ ex vars (CAnd cons)
398−constrainField :: Env -> R.Region -> N.Name -> Can.Expr -> IO (Variable, Type, Constraint)
375+constrainField :: RTV -> Can.Expr -> IO (Variable, Type, Constraint)
399−constrainField env recordRegion name expr =
376+constrainField rtv expr =
400 do var <- mkFlexVar
377 do var <- mkFlexVar
401 let tipe = VarN var
378 let tipe = VarN var
402− con <- constrain env recordRegion (Error.RecordField name) expr tipe
379+ con <- constrain rtv expr (NoExpectation tipe)
403 return (var, tipe, con)
380 return (var, tipe, con)
@@ -407,21 +384,21 @@ constrainField env recordRegion name expr =
407-- CONSTRAIN RECORD UPDATE
384-- CONSTRAIN RECORD UPDATE
410−constrainUpdate :: Env -> R.Region -> Error.Context -> R.Region -> Can.Expr -> Map.Map N.Name Can.Expr -> Type -> IO Constraint
387+constrainUpdate :: RTV -> R.Region -> Can.Expr -> Map.Map N.Name Can.Expr -> Expectation -> IO Constraint
411−constrainUpdate env parentRegion context recordRegion expr fields tipe =
388+constrainUpdate rtv region expr fields expectation =
412 do sharedVar <- mkFlexVar
389 do sharedVar <- mkFlexVar
413 let sharedType = VarN sharedVar
390 let sharedType = VarN sharedVar
415 oldVars <- traverse (\_ -> mkFlexVar) fields
392 oldVars <- traverse (\_ -> mkFlexVar) fields
416 let oldTypes = Map.map VarN oldVars
393 let oldTypes = Map.map VarN oldVars
417 let oldRecordType = RecordN oldTypes sharedType
394 let oldRecordType = RecordN oldTypes sharedType
418− oldCon <- constrain env recordRegion Error.RecordUpdate expr oldRecordType
395+ oldCon <- constrain rtv expr (FromContext region RecordUpdate oldRecordType)
420− newDict <- Map.traverseWithKey (constrainField env recordRegion) fields
397+ newDict <- traverse (constrainField rtv) fields
422 let getType (_, t, _) = t
399 let getType (_, t, _) = t
423 let newRecordType = RecordN (Map.map getType newDict) sharedType
400 let newRecordType = RecordN (Map.map getType newDict) sharedType
424− let newCon = CEqual parentRegion context Error.Record recordRegion newRecordType tipe
401+ let newCon = CEqual region Record newRecordType expectation
426 let vars = Map.foldr (\(v,_,_) vs -> v:vs) (sharedVar : Map.elems oldVars) newDict
403 let vars = Map.foldr (\(v,_,_) vs -> v:vs) (sharedVar : Map.elems oldVars) newDict
427 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [newCon] newDict
404 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [newCon] newDict
@@ -433,30 +410,30 @@ constrainUpdate env parentRegion context recordRegion expr fields tipe =
433-- CONSTRAIN TUPLE
410-- CONSTRAIN TUPLE
436−constrainTuple :: Env -> R.Region -> Error.Context -> R.Region -> Can.Expr -> Can.Expr -> Maybe Can.Expr -> Type -> IO Constraint
413+constrainTuple :: RTV -> R.Region -> Can.Expr -> Can.Expr -> Maybe Can.Expr -> Expectation -> IO Constraint
437−constrainTuple env parentRegion context tupleRegion a b maybeC tipe =
414+constrainTuple rtv region a b maybeC expectation =
438 do aVar <- mkFlexVar
415 do aVar <- mkFlexVar
439 bVar <- mkFlexVar
416 bVar <- mkFlexVar
440 let aType = VarN aVar
417 let aType = VarN aVar
441 let bType = VarN bVar
418 let bType = VarN bVar
443− aCon <- constrain env tupleRegion Error.Whatever a aType
420+ aCon <- constrain rtv a (NoExpectation aType)
444− bCon <- constrain env tupleRegion Error.Whatever b bType
421+ bCon <- constrain rtv b (NoExpectation bType)
446 case maybeC of
423 case maybeC of
447 Nothing ->
424 Nothing ->
448 do let tupleType = TupleN aType bType Nothing
425 do let tupleType = TupleN aType bType Nothing
449− let tupleCon = CEqual parentRegion context Error.Tuple tupleRegion tupleType tipe
426+ let tupleCon = CEqual region Tuple tupleType expectation
450 return $ ex [ aVar, bVar ] $ CAnd [ aCon, bCon, tupleCon ]
427 return $ ex [ aVar, bVar ] $ CAnd [ aCon, bCon, tupleCon ]
452 Just c ->
429 Just c ->
453 do cVar <- mkFlexVar
430 do cVar <- mkFlexVar
454 let cType = VarN cVar
431 let cType = VarN cVar
456− cCon <- constrain env tupleRegion Error.Whatever c cType
433+ cCon <- constrain rtv c (NoExpectation cType)
458 let tupleType = TupleN aType bType (Just cType)
435 let tupleType = TupleN aType bType (Just cType)
459− let tupleCon = CEqual parentRegion context Error.Tuple tupleRegion tupleType tipe
436+ let tupleCon = CEqual region Tuple tupleType expectation
461 return $ ex [ aVar, bVar, cVar ] $ CAnd [ aCon, bCon, cCon, tupleCon ]
438 return $ ex [ aVar, bVar, cVar ] $ CAnd [ aCon, bCon, cCon, tupleCon ]
@@ -465,8 +442,8 @@ constrainTuple env parentRegion context tupleRegion a b maybeC tipe =
465-- CONSTRAIN SHADER
442-- CONSTRAIN SHADER
468−constrainShader :: Env -> R.Region -> Error.Context -> R.Region -> Shader.Shader -> Type -> IO Constraint
445+constrainShader :: R.Region -> Shader.Shader -> Expectation -> IO Constraint
469−constrainShader env parentRegion context shaderRegion (Shader.Shader attributes uniforms varyings) tipe =
446+constrainShader region (Shader.Shader attributes uniforms varyings) expectation =
470 do attrVar <- mkFlexVar
447 do attrVar <- mkFlexVar
471 unifVar <- mkFlexVar
448 unifVar <- mkFlexVar
472 let attrType = VarN attrVar
449 let attrType = VarN attrVar
@@ -480,7 +457,7 @@ constrainShader env parentRegion context shaderRegion (Shader.Shader attributes
482 return $ ex [ attrVar, unifVar ] $
459 return $ ex [ attrVar, unifVar ] $
483− CEqual parentRegion context Error.Shader shaderRegion shaderType tipe
460+ CEqual region Shader shaderType expectation
486toShaderRecord :: Map.Map N.Name Shader.Type -> Type -> Type
463toShaderRecord :: Map.Map N.Name Shader.Type -> Type -> Type
@@ -507,11 +484,30 @@ glToType glType =
507-- CONSTRAIN LET
484-- CONSTRAIN LET
510−constrainLet :: Env -> R.Region -> Error.Context -> R.Region -> Can.Def -> Can.Expr -> Type -> IO Constraint
487+constrainDef :: RTV -> Can.Def -> Constraint -> IO Constraint
511−constrainLet env parentRegion context letRegion (Can.Def (A.A _ name) (Can.Args args _) expr maybeType) body tipe =
488+constrainDef rtv def bodyCon =
512− case maybeType of
489+ case def of
513− Nothing ->
490+ Can.Def (A.A region name) args _ expr ->
514− error "TODO"
491+ do (lambdaType, resultType, scheme) <-
492+ Pattern.constrainArgs args
495+ CLet [scheme] <$> constrain rtv expr (NoExpectation resultType)
497+ let headers = Map.singleton name (A.A region lambdaType)
498+ return $ CLet [Scheme [] [] headers defCon] bodyCon
500+ Can.TypedDef (A.A region name) freeVars typedArgs _ expr srcResultType ->
501+ do let newNames = Map.difference freeVars rtv
502+ newRigids <- Map.traverseWithKey (\n _ -> nameToRigid n) newNames
503+ let newRtv = Map.union rtv (Map.map VarN newRigids)
505+ (lambdaType, resultType, scheme) <-
506+ Pattern.constrainTypedArgs newRtv typedArgs srcResultType
508+ let expectation = FromAnnotation name (length typedArgs) TypedBody resultType
510+ CLet [scheme] <$> constrain newRtv expr expectation
516− Just srcType ->
512+ let headers = Map.singleton name (A.A region lambdaType)
517− error "TODO"
513+ return $ CLet [ Scheme (Map.elems newRigids) [] headers defCon ] bodyCon