@@ -1,5 +1,4 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2−{-# LANGUAGE OverloadedStrings #-}
3module Type.Constrain.Expression
2module Type.Constrain.Expression
4 ( constrain
3 ( constrain
@@ -17,6 +16,7 @@ import qualified Reporting.Annotation as A
17import qualified Reporting.Region as R
16import qualified Reporting.Region as R
18import Type.Constraint
17import Type.Constraint
19import qualified Type.Constrain.Pattern as Pattern
18import qualified Type.Constrain.Pattern as Pattern
19+import qualified Type.Instantiate as Instantiate
20import Type.Type as Type hiding (Descriptor(..))
20import Type.Type as Type hiding (Descriptor(..))
@@ -61,7 +61,7 @@ constrain rtv (A.A region expression) expectation =
62 Can.Int _ ->
62 Can.Int _ ->
63 do var <- mkFlexNumber
63 do var <- mkFlexNumber
64− return $ ex [var] $ CEqual region Number (VarN var) expectation
64+ return $ exists [var] $ CEqual region Number (VarN var) expectation
66 Can.Float _ ->
66 Can.Float _ ->
67 return $ CEqual region Float Type.float expectation
67 return $ CEqual region Float Type.float expectation
@@ -74,16 +74,13 @@ constrain rtv (A.A region expression) expectation =
74 let numberType = VarN numberVar
74 let numberType = VarN numberVar
75 numberCon <- constrain rtv expr (FromContext region Negate numberType)
75 numberCon <- constrain rtv expr (FromContext region Negate numberType)
76 let negateCon = CEqual region Number numberType expectation
76 let negateCon = CEqual region Number numberType expectation
77− return $ ex [numberVar] $ CAnd [ numberCon, negateCon ]
77+ return $ exists [numberVar] $ CAnd [ numberCon, negateCon ]
79 Can.Binop op _ _ annotation leftExpr rightExpr ->
79 Can.Binop op _ _ annotation leftExpr rightExpr ->
80 constrainBinop rtv region op annotation leftExpr rightExpr expectation
80 constrainBinop rtv region op annotation leftExpr rightExpr expectation
82 Can.Lambda args _ body ->
82 Can.Lambda args _ body ->
83− do (lambdaType, resultType, scheme) <- Pattern.constrainArgs args
83+ constrainLambda rtv region args body expectation
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 ->
85 Can.Call func args ->
89 constrainCall rtv region func args expectation
86 constrainCall rtv region func args expectation
@@ -95,13 +92,16 @@ constrain rtv (A.A region expression) expectation =
95 constrainCase rtv region expr branches expectation
92 constrainCase rtv region expr branches expectation
97 Can.Let def body ->
94 Can.Let def body ->
98− constrainDef rtv def =<< constrain rtv body expectation
96+ =<< constrain rtv body expectation
100 Can.LetRec defs body ->
98 Can.LetRec defs body ->
101− error "TODO let rec" defs body
99+ constrainRecursiveDefs rtv defs
100+ =<< constrain rtv body expectation
103− Can.LetDestruct pattern destructors expr body ->
102+ Can.LetDestruct pattern _ expr body ->
104− error "TODO let destruct" pattern destructors expr body
103+ constrainDestruct rtv region pattern expr
104+ =<< constrain rtv body expectation
106 Can.Accessor field ->
106 Can.Accessor field ->
107 do extVar <- mkFlexVar
107 do extVar <- mkFlexVar
@@ -109,7 +109,7 @@ constrain rtv (A.A region expression) expectation =
109 let extType = VarN extVar
109 let extType = VarN extVar
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 $ exists [ fieldVar, extVar ] $
113 CEqual region (Accessor field) (FunN recordType fieldType) expectation
113 CEqual region (Accessor field) (FunN recordType fieldType) expectation
115 Can.Access expr field ->
115 Can.Access expr field ->
@@ -122,7 +122,7 @@ constrain rtv (A.A region expression) expectation =
122 recordCon <-
122 recordCon <-
123 constrain rtv expr (FromContext region (RecordAccess field) recordType)
123 constrain rtv expr (FromContext region (RecordAccess field) recordType)
125− return $ ex [ fieldVar, extVar ] $
125+ return $ exists [ fieldVar, extVar ] $
127 [ recordCon
127 [ recordCon
128 , CEqual region (Access field) recordType expectation
128 , CEqual region (Access field) recordType expectation
@@ -145,6 +145,31 @@ constrain rtv (A.A region expression) expectation =
151+constrainLambda :: RTV -> R.Region -> [Can.Arg] -> Can.Expr -> Expectation -> IO Constraint
152+constrainLambda rtv region args body expectation =
153+ do (Args vars tipe resultType (Pattern.State headers pvars revCons)) <-
157+ constrain rtv body (NoExpectation resultType)
159+ return $ exists vars $
165+ , _headerCon = CAnd (reverse revCons)
166+ , _bodyCon = bodyCon
168+ , CEqual region Lambda tipe expectation
148-- CONSTRAIN CALL
173-- CONSTRAIN CALL
@@ -165,7 +190,7 @@ constrainCall rtv region func args expectation =
165 let arityType = foldr FunN resultType argTypes
190 let arityType = foldr FunN resultType argTypes
166 let resultCon = CEqual region (CallResult maybeFuncName) resultType expectation
191 let resultCon = CEqual region (CallResult maybeFuncName) resultType expectation
168− return $ ex (funcVar:resultVar:argVars) $
193+ return $ exists (funcVar:resultVar:argVars) $
170 [ funcCon
195 [ funcCon
171 , CBranch
196 , CBranch
@@ -196,7 +221,7 @@ constrainCallBackup rtv region maybeFuncName func args =
197 funcCon <- constrain rtv func (FromContext region BadArity arityType)
222 funcCon <- constrain rtv func (FromContext region BadArity arityType)
199− return $ ex (resultVar:argVars) $ CAnd [ CAnd argCons, funcCon ]
224+ return $ exists (resultVar:argVars) $ CAnd [ CAnd argCons, funcCon ]
202getFuncName :: Can.Expr -> Maybe FuncName
227getFuncName :: Can.Expr -> Maybe FuncName
@@ -240,7 +265,7 @@ constrainBinop rtv region op annotation leftExpr rightExpr expectation =
240 leftCon <- constrain rtv leftExpr (FromContext region (OpLeft op) leftType)
265 leftCon <- constrain rtv leftExpr (FromContext region (OpLeft op) leftType)
241 rightCon <- constrain rtv rightExpr (FromContext region (OpRight op) rightType)
266 rightCon <- constrain rtv rightExpr (FromContext region (OpRight op) rightType)
243− return $ ex [ leftVar, rightVar, answerVar ] $
268+ return $ exists [ leftVar, rightVar, answerVar ] $
246 , leftCon
271 , leftCon
@@ -262,7 +287,7 @@ constrainList rtv region entries expectation =
262 entryCons <-
287 entryCons <-
263 Index.indexedTraverse (constrainListEntry rtv region entryType) entries
288 Index.indexedTraverse (constrainListEntry rtv region entryType) entries
265− return $ ex [entryVar] $
290+ return $ exists [entryVar] $
267 [ CAnd entryCons
292 [ CAnd entryCons
268 , CEqual region List listType expectation
293 , CEqual region List listType expectation
@@ -303,7 +328,7 @@ constrainIf rtv region branches final expectation =
303 branchCons <- Index.indexedForA exprs $ \index expr ->
328 branchCons <- Index.indexedForA exprs $ \index expr ->
304 constrain rtv expr (FromContext region (IfBranch index) branchType)
329 constrain rtv expr (FromContext region (IfBranch index) branchType)
306− return $ ex [branchVar] $
331+ return $ exists [branchVar] $
308 [ CAnd condCons
333 [ CAnd condCons
309 , CAnd branchCons
334 , CAnd branchCons
@@ -328,7 +353,7 @@ constrainCase rtv region expr branches expectation =
328 (PatternExpectation region (PCaseMatch index) ptrnType)
353 (PatternExpectation region (PCaseMatch index) ptrnType)
329 (FromAnnotation name arity (TypedCaseBranch index) tipe)
354 (FromAnnotation name arity (TypedCaseBranch index) tipe)
331− return $ ex [ptrnVar] $ CAnd (exprCon:branchCons)
356+ return $ exists [ptrnVar] $ CAnd (exprCon:branchCons)
334 do branchVar <- mkFlexVar
359 do branchVar <- mkFlexVar
@@ -339,7 +364,7 @@ constrainCase rtv region expr branches expectation =
339 (PatternExpectation region (PCaseMatch index) ptrnType)
364 (PatternExpectation region (PCaseMatch index) ptrnType)
340 (FromContext region (CaseBranch index) branchType)
365 (FromContext region (CaseBranch index) branchType)
342− return $ ex [ptrnVar,branchVar] $
367+ return $ exists [ptrnVar,branchVar] $
344 [ exprCon
369 [ exprCon
345 , CAnd branchCons
370 , CAnd branchCons
@@ -349,9 +374,11 @@ constrainCase rtv region expr branches expectation =
350constrainCaseBranch :: RTV -> Can.CaseBranch -> PatternExpectation -> Expectation -> IO Constraint
375constrainCaseBranch :: RTV -> Can.CaseBranch -> PatternExpectation -> Expectation -> IO Constraint
351constrainCaseBranch rtv (Can.CaseBranch pattern _ expr) pExpect bExpect =
376constrainCaseBranch rtv (Can.CaseBranch pattern _ expr) pExpect bExpect =
377+ do (Pattern.State headers pvars revCons) <-
352− do scheme <- Pattern.constrain pattern pExpect
378+ Pattern.add pattern pExpect Pattern.emptyState
353− constraint <- constrain rtv expr bExpect
379+
354− return $ CLet [scheme] constraint
380+ CLet [] pvars headers (CAnd (reverse revCons))
381+ <$> constrain rtv expr bExpect
@@ -369,7 +396,7 @@ constrainRecord rtv region fields expectation =
369 let vars = Map.foldr (\(v,_,_) vs -> v:vs) [] dict
396 let vars = Map.foldr (\(v,_,_) vs -> v:vs) [] dict
370 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [recordCon] dict
397 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [recordCon] dict
372− return $ ex vars (CAnd cons)
399+ return $ exists vars (CAnd cons)
375constrainField :: RTV -> Can.Expr -> IO (Variable, Type, Constraint)
402constrainField :: RTV -> Can.Expr -> IO (Variable, Type, Constraint)
@@ -403,7 +430,7 @@ constrainUpdate rtv region expr fields expectation =
403 let vars = Map.foldr (\(v,_,_) vs -> v:vs) (sharedVar : Map.elems oldVars) newDict
430 let vars = Map.foldr (\(v,_,_) vs -> v:vs) (sharedVar : Map.elems oldVars) newDict
404 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [newCon] newDict
431 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [newCon] newDict
406− return $ ex vars (CAnd (oldCon:cons))
433+ return $ exists vars (CAnd (oldCon:cons))
@@ -424,7 +451,7 @@ constrainTuple rtv region a b maybeC expectation =
424 Nothing ->
451 Nothing ->
425 do let tupleType = TupleN aType bType Nothing
452 do let tupleType = TupleN aType bType Nothing
426 let tupleCon = CEqual region Tuple tupleType expectation
453 let tupleCon = CEqual region Tuple tupleType expectation
427− return $ ex [ aVar, bVar ] $ CAnd [ aCon, bCon, tupleCon ]
454+ return $ exists [ aVar, bVar ] $ CAnd [ aCon, bCon, tupleCon ]
429 Just c ->
456 Just c ->
430 do cVar <- mkFlexVar
457 do cVar <- mkFlexVar
@@ -435,7 +462,7 @@ constrainTuple rtv region a b maybeC expectation =
435 let tupleType = TupleN aType bType (Just cType)
462 let tupleType = TupleN aType bType (Just cType)
436 let tupleCon = CEqual region Tuple tupleType expectation
463 let tupleCon = CEqual region Tuple tupleType expectation
438− return $ ex [ aVar, bVar, cVar ] $ CAnd [ aCon, bCon, cCon, tupleCon ]
465+ return $ exists [ aVar, bVar, cVar ] $ CAnd [ aCon, bCon, cCon, tupleCon ]
@@ -456,7 +483,7 @@ constrainShader region (Shader.Shader attributes uniforms varyings) expectation
456 , toShaderRecord varyings EmptyRecordN
483 , toShaderRecord varyings EmptyRecordN
459− return $ ex [ attrVar, unifVar ] $
486+ return $ exists [ attrVar, unifVar ] $
460 CEqual region Shader shaderType expectation
487 CEqual region Shader shaderType expectation
@@ -481,33 +508,242 @@ glToType glType =
484−-- CONSTRAIN LET
511+-- CONSTRAIN DESTRUCTURES
514+constrainDestruct :: RTV -> R.Region -> Can.Pattern -> Can.Expr -> Constraint -> IO Constraint
515+constrainDestruct rtv region pattern expr bodyCon =
516+ do patternVar <- mkFlexVar
517+ let patternType = VarN patternVar
519+ (Pattern.State headers pvars revCons) <-
520+ Pattern.add pattern (NoPatternExpectation patternType) Pattern.emptyState
523+ constrain rtv expr (FromContext region Destructure patternType)
525+ return $ CLet [] pvars headers (CAnd (reverse (exprCon:revCons))) bodyCon
487constrainDef :: RTV -> Can.Def -> Constraint -> IO Constraint
532constrainDef :: RTV -> Can.Def -> Constraint -> IO Constraint
488constrainDef rtv def bodyCon =
533constrainDef rtv def bodyCon =
489 case def of
534 case def of
490 Can.Def (A.A region name) args _ expr ->
535 Can.Def (A.A region name) args _ expr ->
491− do (lambdaType, resultType, scheme) <-
536+ do (Args vars tipe resultType (Pattern.State headers pvars revCons)) <-
492− Pattern.constrainArgs args
537+ constrainArgs args
494− defCon <-
539+ exprCon <-
495− CLet [scheme] <$> constrain rtv expr (NoExpectation resultType)
540+ constrain rtv expr (NoExpectation resultType)
497− let headers = Map.singleton name (A.A region lambdaType)
546+ , _header = Map.singleton name (A.A region tipe)
498− return $ CLet [Scheme [] [] headers defCon] bodyCon
547+ , _headerCon =
552+ , _headerCon = CAnd (reverse revCons)
553+ , _bodyCon = exprCon
555+ , _bodyCon = bodyCon
500 Can.TypedDef (A.A region name) freeVars typedArgs _ expr srcResultType ->
558 Can.TypedDef (A.A region name) freeVars typedArgs _ expr srcResultType ->
501 do let newNames = Map.difference freeVars rtv
559 do let newNames = Map.difference freeVars rtv
502 newRigids <- Map.traverseWithKey (\n _ -> nameToRigid n) newNames
560 newRigids <- Map.traverseWithKey (\n _ -> nameToRigid n) newNames
503 let newRtv = Map.union rtv (Map.map VarN newRigids)
561 let newRtv = Map.union rtv (Map.map VarN newRigids)
505− (lambdaType, resultType, scheme) <-
563+ (TypedArgs tipe resultType (Pattern.State headers pvars revCons)) <-
506− Pattern.constrainTypedArgs newRtv typedArgs srcResultType
564+ constrainTypedArgs newRtv name typedArgs srcResultType
508 let expectation = FromAnnotation name (length typedArgs) TypedBody resultType
566 let expectation = FromAnnotation name (length typedArgs) TypedBody resultType
509− defCon <-
567+ exprCon <-
510− CLet [scheme] <$> constrain newRtv expr expectation
568+ constrain newRtv expr expectation
572+ { _rigidVars = Map.elems newRigids
574+ , _header = Map.singleton name (A.A region tipe)
580+ , _headerCon = CAnd (reverse revCons)
581+ , _bodyCon = exprCon
583+ , _bodyCon = bodyCon
588+-- CONSTRAIN RECURSIVE DEFS
593+ { _vars :: [Variable]
594+ , _cons :: [Constraint]
595+ , _headers :: Map.Map N.Name (A.Located Type)
599+{-# NOINLINE emptyInfo #-}
602+ Info [] [] Map.empty
605+constrainRecursiveDefs :: RTV -> [Can.Def] -> Constraint -> IO Constraint
606+constrainRecursiveDefs rtv defs bodyCon =
607+ recDefsHelp rtv defs bodyCon emptyInfo emptyInfo
610+recDefsHelp :: RTV -> [Can.Def] -> Constraint -> Info -> Info -> IO Constraint
611+recDefsHelp rtv defs bodyCon rigidInfo flexInfo =
614+ do let (Info rigidVars rigidCons rigidHeaders) = rigidInfo
615+ let (Info flexVars flexCons flexHeaders ) = flexInfo
617+ CLet rigidVars [] rigidHeaders CTrue $
618+ CLet [] flexVars flexHeaders (CLet [] [] flexHeaders CTrue (CAnd flexCons)) $
619+ CAnd [ CAnd rigidCons, bodyCon ]
623+ Can.Def (A.A region name) args _ expr ->
624+ do let (Info flexVars flexCons flexHeaders) = flexInfo
626+ (Args newFlexVars tipe resultType (Pattern.State headers pvars revCons)) <-
627+ argsHelp args (Pattern.State Map.empty flexVars [])
630+ constrain rtv expr (NoExpectation resultType)
637+ , _headerCon = CAnd (reverse revCons)
638+ , _bodyCon = exprCon
641+ recDefsHelp rtv otherDefs bodyCon rigidInfo $
643+ { _vars = newFlexVars
644+ , _cons = defCon : flexCons
645+ , _headers = Map.insert name (A.A region tipe) flexHeaders
648+ Can.TypedDef (A.A region name) freeVars typedArgs _ expr srcResultType ->
649+ do let newNames = Map.difference freeVars rtv
650+ newRigids <- Map.traverseWithKey (\n _ -> nameToRigid n) newNames
651+ let newRtv = Map.union rtv (Map.map VarN newRigids)
653+ (TypedArgs tipe resultType (Pattern.State headers pvars revCons)) <-
654+ constrainTypedArgs newRtv name typedArgs srcResultType
657+ constrain newRtv expr $
658+ FromAnnotation name (length typedArgs) TypedBody resultType
665+ , _headerCon = CAnd (reverse revCons)
666+ , _bodyCon = exprCon
669+ let (Info rigidVars rigidCons rigidHeaders) = rigidInfo
670+ recDefsHelp rtv otherDefs bodyCon
672+ { _vars = Map.foldr (:) rigidVars newRigids
673+ , _cons = defCon : rigidCons
674+ , _headers = Map.insert name (A.A region tipe) rigidHeaders
686+ { _a_vars :: [Variable]
689+ , _a_state :: Pattern.State
693+constrainArgs :: [Can.Arg] -> IO Args
695+ argsHelp args Pattern.emptyState
698+argsHelp :: [Can.Arg] -> Pattern.State -> IO Args
699+argsHelp args state =
702+ do resultVar <- mkFlexVar
703+ let resultType = VarN resultVar
704+ return $ Args [resultVar] resultType resultType state
706+ (Can.Arg _ pattern) : otherArgs ->
707+ do argVar <- mkFlexVar
708+ let argType = VarN argVar
710+ (Args vars tipe result newState) <-
711+ argsHelp otherArgs =<<
712+ Pattern.add pattern (NoPatternExpectation argType) state
714+ return (Args (argVar:vars) (FunN argType tipe) result newState)
718+-- CONSTRAIN TYPED ARGS
725+ , _t_state :: Pattern.State
729+constrainTypedArgs :: Map.Map N.Name Type -> N.Name -> [Can.TypedArg] -> Can.Type -> IO TypedArgs
730+constrainTypedArgs rtv name args srcResultType =
731+ do resultType <- Instantiate.fromSrcType rtv srcResultType
732+ typedArgsHelp rtv name args resultType Pattern.emptyState
735+typedArgsHelp :: Map.Map N.Name Type -> N.Name -> [Can.TypedArg] -> Type -> Pattern.State -> IO TypedArgs
736+typedArgsHelp rtv name args resultType state =
739+ return $ TypedArgs resultType resultType state
741+ (Can.TypedArg index srcType pattern@(A.A region _)) : otherArgs ->
742+ do argType <- Instantiate.fromSrcType rtv srcType
743+ let expect = PatternExpectation region (PTypedArg name index) argType
745+ (TypedArgs tipe result newState) <-
746+ typedArgsHelp rtv name otherArgs resultType =<<
747+ Pattern.add pattern expect state
512− let headers = Map.singleton name (A.A region lambdaType)
749+ return (TypedArgs (FunN argType tipe) result newState)
513− return $ CLet [ Scheme (Map.elems newRigids) [] headers defCon ] bodyCon