on 0bdfd73 help sign in
elk/src/Type/Constrain/Expression.hs
761 lines 24 kB history raw
1{-# OPTIONS_GHC -Wall #-}
2module Type.Constrain.Expression
3 ( constrain
4 , constrainDef
5 , constrainRecursiveDefs
6 )
7 where
10import qualified Data.Map.Strict as Map
12import qualified AST.Canonical as Can
13import qualified AST.Module.Name as ModuleName
14import qualified AST.Utils.Shader as Shader
15import qualified Data.Index as Index
16import qualified Elm.Name as N
17import qualified Reporting.Annotation as A
18import qualified Reporting.Error.Type as E
19import Reporting.Error.Type (Expected(..), Context(..), SubContext(..), MaybeName(..), Category(..), PExpected(..), PContext(..))
20import qualified Reporting.Region as R
21import qualified Type.Constrain.Pattern as Pattern
22import qualified Type.Instantiate as Instantiate
23import Type.Type as Type hiding (Descriptor(..))
27-- CONSTRAIN
30-- As we step past type annotations, the free type variables are added to
31-- the "rigid type variables" dict. Allowing sharing of rigid variables
32-- between nested type annotations.
33--
34-- So if you have a top-level type annotation like (func : a -> b) the RTV
35-- dictionary will hold variables for `a` and `b`
36--
37type RTV =
38 Map.Map N.Name Type
41constrain :: RTV -> Can.Expr -> Expected Type -> IO Constraint
42constrain rtv (A.At region expression) expected =
43 case expression of
44 Can.VarLocal name ->
45 return (CLocal region name expected)
47 Can.VarTopLevel _ name ->
48 return (CLocal region name expected)
50 Can.VarKernel _ _ ->
51 return CTrue
53 Can.VarForeign _ name annotation ->
54 return $ CForeign region name annotation expected
56 Can.VarCtor _ _ name _ annotation ->
57 return $ CForeign region name annotation expected
59 Can.VarDebug _ name annotation ->
60 return $ CForeign region name annotation expected
62 Can.VarOperator op _ _ annotation ->
63 return $ CForeign region op annotation expected
65 Can.Str _ ->
66 return $ CEqual region String Type.string expected
68 Can.Chr _ ->
69 return $ CEqual region Char Type.char expected
71 Can.Int _ ->
72 do var <- mkFlexNumber
73 return $ exists [var] $ CEqual region E.Number (VarN var) expected
75 Can.Float _ ->
76 return $ CEqual region Float Type.float expected
78 Can.List elements ->
79 constrainList rtv region elements expected
81 Can.Negate expr ->
82 do numberVar <- mkFlexNumber
83 let numberType = VarN numberVar
84 numberCon <- constrain rtv expr (FromContext region Negate numberType)
85 let negateCon = CEqual region E.Number numberType expected
86 return $ exists [numberVar] $ CAnd [ numberCon, negateCon ]
88 Can.Binop op _ _ annotation leftExpr rightExpr ->
89 constrainBinop rtv region op annotation leftExpr rightExpr expected
91 Can.Lambda args body ->
92 constrainLambda rtv region args body expected
94 Can.Call func args ->
95 constrainCall rtv region func args expected
97 Can.If branches finally ->
98 constrainIf rtv region branches finally expected
100 Can.Case expr branches ->
101 constrainCase rtv region expr branches expected
103 Can.Let def body ->
104 constrainDef rtv def
105 =<< constrain rtv body expected
107 Can.LetRec defs body ->
108 constrainRecursiveDefs rtv defs
109 =<< constrain rtv body expected
111 Can.LetDestruct pattern expr body ->
112 constrainDestruct rtv region pattern expr
113 =<< constrain rtv body expected
115 Can.Accessor field ->
116 do extVar <- mkFlexVar
117 fieldVar <- mkFlexVar
118 let extType = VarN extVar
119 let fieldType = VarN fieldVar
120 let recordType = RecordN (Map.singleton field fieldType) extType
121 return $ exists [ fieldVar, extVar ] $
122 CEqual region (Accessor field) (FunN recordType fieldType) expected
124 Can.Access expr field ->
125 do extVar <- mkFlexVar
126 fieldVar <- mkFlexVar
127 let extType = VarN extVar
128 let fieldType = VarN fieldVar
129 let recordType = RecordN (Map.singleton field fieldType) extType
131 recordCon <-
132 constrain rtv expr (FromContext region (RecordAccess field) recordType)
134 return $ exists [ fieldVar, extVar ] $
135 CAnd
136 [ recordCon
137 , CEqual region (Access field) fieldType expected
138 ]
140 Can.Update expr fields ->
141 constrainUpdate rtv region expr fields expected
143 Can.Record fields ->
144 constrainRecord rtv region fields expected
146 Can.Unit ->
147 return $ CEqual region Unit UnitN expected
149 Can.Tuple a b maybeC ->
150 constrainTuple rtv region a b maybeC expected
152 Can.Shader _uid _src glType ->
153 constrainShader region glType expected
157-- CONSTRAIN LAMBDA
160constrainLambda :: RTV -> R.Region -> [Can.Pattern] -> Can.Expr -> Expected Type -> IO Constraint
161constrainLambda rtv region args body expected =
162 do (Args vars tipe resultType (Pattern.State headers pvars revCons)) <-
163 constrainArgs args
165 bodyCon <-
166 constrain rtv body (NoExpectation resultType)
168 return $ exists vars $
169 CAnd
170 [ CLet
171 { _rigidVars = []
172 , _flexVars = pvars
173 , _header = headers
174 , _headerCon = CAnd (reverse revCons)
175 , _bodyCon = bodyCon
176 }
177 , CEqual region Lambda tipe expected
178 ]
182-- CONSTRAIN CALL
185constrainCall :: RTV -> R.Region -> Can.Expr -> [Can.Expr] -> Expected Type -> IO Constraint
186constrainCall rtv region func args expected =
187 do let maybeName = getName func
189 funcVar <- mkFlexVar
190 resultVar <- mkFlexVar
191 let funcType = VarN funcVar
192 let resultType = VarN resultVar
194 funcCon <- constrain rtv func (NoExpectation funcType)
196 (argVars, argTypes, argCons) <-
197 unzip3 <$> Index.indexedTraverse (constrainArg rtv region maybeName) args
199 let arityType = foldr FunN resultType argTypes
200 let resultCon = CEqual region (CallResult maybeName) resultType expected
202 return $ exists (funcVar:resultVar:argVars) $
203 CAnd
204 [ funcCon
205 , CBranch
206 { _a = funcType
207 , _b = arityType
208 , _eq = CAnd [ CAnd argCons, resultCon ]
209 , _neq = constrainCallBackup rtv region maybeName func args
210 }
211 ]
214constrainArg :: RTV -> R.Region -> MaybeName -> Index.ZeroBased -> Can.Expr -> IO (Variable, Type, Constraint)
215constrainArg rtv region maybeName index arg =
216 do argVar <- mkFlexVar
217 let argType = VarN argVar
218 argCon <- constrain rtv arg (FromContext region (CallArg maybeName index) argType)
219 return (argVar, argType, argCon)
222constrainCallBackup :: RTV -> R.Region -> MaybeName -> Can.Expr -> [Can.Expr] -> IO Constraint
223constrainCallBackup rtv region maybeName func args =
224 do (argVars, argTypes, argCons) <-
225 unzip3 <$> Index.indexedTraverse (constrainArg rtv region maybeName) args
227 resultVar <- mkFlexVar
228 let resultType = VarN resultVar
229 let arityType = foldr FunN resultType argTypes
231 funcCon <- constrain rtv func (FromContext region (TooManyArgs maybeName (length args)) arityType)
233 return $ exists (resultVar:argVars) $ CAnd [ CAnd argCons, funcCon ]
236getName :: Can.Expr -> MaybeName
237getName (A.At _ expr) =
238 case expr of
239 Can.VarLocal name ->
240 FuncName name
242 Can.VarTopLevel _ name ->
243 FuncName name
245 Can.VarForeign _ name _ ->
246 FuncName name
248 Can.VarCtor _ _ name _ _ ->
249 CtorName name
251 Can.VarOperator op _ _ _ ->
252 OpName op
254 Can.VarKernel _ name ->
255 FuncName name
257 _ ->
258 NoName
262-- CONSTRAIN BINOP
265constrainBinop :: RTV -> R.Region -> N.Name -> Can.Annotation -> Can.Expr -> Can.Expr -> Expected Type -> IO Constraint
266constrainBinop rtv region op annotation leftExpr rightExpr expected =
267 do leftVar <- mkFlexVar
268 rightVar <- mkFlexVar
269 answerVar <- mkFlexVar
270 let leftType = VarN leftVar
271 let rightType = VarN rightVar
272 let answerType = VarN answerVar
273 let binopType = leftType ==> rightType ==> answerType
275 let opCon = CForeign region op annotation (NoExpectation binopType)
277 leftCon <- constrain rtv leftExpr (FromContext region (OpLeft op) leftType)
278 rightCon <- constrain rtv rightExpr (FromContext region (OpRight op) rightType)
280 return $ exists [ leftVar, rightVar, answerVar ] $
281 CAnd
282 [ opCon
283 , leftCon
284 , rightCon
285 , CEqual region (CallResult (OpName op)) answerType expected
286 ]
290-- CONSTRAIN LISTS
293constrainList :: RTV -> R.Region -> [Can.Expr] -> Expected Type -> IO Constraint
294constrainList rtv region entries expected =
295 do entryVar <- mkFlexVar
296 let entryType = VarN entryVar
297 let listType = AppN ModuleName.list N.list [entryType]
299 entryCons <-
300 Index.indexedTraverse (constrainListEntry rtv region entryType) entries
302 return $ exists [entryVar] $
303 CAnd
304 [ CAnd entryCons
305 , CEqual region List listType expected
306 ]
309constrainListEntry :: RTV -> R.Region -> Type -> Index.ZeroBased -> Can.Expr -> IO Constraint
310constrainListEntry rtv region tipe index expr =
311 constrain rtv expr (FromContext region (ListEntry index) tipe)
315-- CONSTRAIN IF EXPRESSIONS
318constrainIf :: RTV -> R.Region -> [(Can.Expr, Can.Expr)] -> Can.Expr -> Expected Type -> IO Constraint
319constrainIf rtv region branches final expected =
320 do let boolExpect = FromContext region IfCondition Type.bool
321 let (conditions, exprs) = foldr (\(c,e) (cs,es) -> (c:cs,e:es)) ([],[final]) branches
323 condCons <-
324 traverse (\c -> constrain rtv c boolExpect) conditions
326 case expected of
327 FromAnnotation name arity _ tipe ->
328 do branchCons <- Index.indexedForA exprs $ \index expr ->
329 constrain rtv expr (FromAnnotation name arity (TypedIfBranch index) tipe)
330 return $
331 CAnd
332 [ CAnd condCons
333 , CAnd branchCons
334 ]
336 _ ->
337 do branchVar <- mkFlexVar
338 let branchType = VarN branchVar
340 branchCons <- Index.indexedForA exprs $ \index expr ->
341 constrain rtv expr (FromContext region (IfBranch index) branchType)
343 return $ exists [branchVar] $
344 CAnd
345 [ CAnd condCons
346 , CAnd branchCons
347 , CEqual region If branchType expected
348 ]
352-- CONSTRAIN CASE EXPRESSIONS
355constrainCase :: RTV -> R.Region -> Can.Expr -> [Can.CaseBranch] -> Expected Type -> IO Constraint
356constrainCase rtv region expr branches expected =
357 do ptrnVar <- mkFlexVar
358 let ptrnType = VarN ptrnVar
359 exprCon <- constrain rtv expr (NoExpectation ptrnType)
361 case expected of
362 FromAnnotation name arity _ tipe ->
363 do branchCons <- Index.indexedForA branches $ \index branch ->
364 constrainCaseBranch rtv branch
365 (PFromContext region (PCaseMatch index) ptrnType)
366 (FromAnnotation name arity (TypedCaseBranch index) tipe)
368 return $ exists [ptrnVar] $ CAnd (exprCon:branchCons)
370 _ ->
371 do branchVar <- mkFlexVar
372 let branchType = VarN branchVar
374 branchCons <- Index.indexedForA branches $ \index branch ->
375 constrainCaseBranch rtv branch
376 (PFromContext region (PCaseMatch index) ptrnType)
377 (FromContext region (CaseBranch index) branchType)
379 return $ exists [ptrnVar,branchVar] $
380 CAnd
381 [ exprCon
382 , CAnd branchCons
383 , CEqual region Case branchType expected
384 ]
387constrainCaseBranch :: RTV -> Can.CaseBranch -> PExpected Type -> Expected Type -> IO Constraint
388constrainCaseBranch rtv (Can.CaseBranch pattern expr) pExpect bExpect =
389 do (Pattern.State headers pvars revCons) <-
390 Pattern.add pattern pExpect Pattern.emptyState
392 CLet [] pvars headers (CAnd (reverse revCons))
393 <$> constrain rtv expr bExpect
397-- CONSTRAIN RECORD
400constrainRecord :: RTV -> R.Region -> Map.Map N.Name Can.Expr -> Expected Type -> IO Constraint
401constrainRecord rtv region fields expected =
402 do dict <- traverse (constrainField rtv) fields
404 let getType (_, t, _) = t
405 let recordType = RecordN (Map.map getType dict) EmptyRecordN
406 let recordCon = CEqual region Record recordType expected
408 let vars = Map.foldr (\(v,_,_) vs -> v:vs) [] dict
409 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [recordCon] dict
411 return $ exists vars (CAnd cons)
414constrainField :: RTV -> Can.Expr -> IO (Variable, Type, Constraint)
415constrainField rtv expr =
416 do var <- mkFlexVar
417 let tipe = VarN var
418 con <- constrain rtv expr (NoExpectation tipe)
419 return (var, tipe, con)
423-- CONSTRAIN RECORD UPDATE
426constrainUpdate :: RTV -> R.Region -> Can.Expr -> Map.Map N.Name Can.Expr -> Expected Type -> IO Constraint
427constrainUpdate rtv region expr fields expected =
428 do sharedVar <- mkFlexVar
429 let sharedType = VarN sharedVar
431 oldVars <- traverse (\_ -> mkFlexVar) fields
432 let oldTypes = Map.map VarN oldVars
433 let oldRecordType = RecordN oldTypes sharedType
434 oldCon <- constrain rtv expr (FromContext region RecordUpdate oldRecordType)
436 newDict <- traverse (constrainField rtv) fields
438 let getType (_, t, _) = t
439 let newRecordType = RecordN (Map.map getType newDict) sharedType
440 let newCon = CEqual region Record newRecordType expected
442 let vars = Map.foldr (\(v,_,_) vs -> v:vs) (sharedVar : Map.elems oldVars) newDict
443 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [newCon] newDict
445 return $ exists vars (CAnd (oldCon:cons))
449-- CONSTRAIN TUPLE
452constrainTuple :: RTV -> R.Region -> Can.Expr -> Can.Expr -> Maybe Can.Expr -> Expected Type -> IO Constraint
453constrainTuple rtv region a b maybeC expected =
454 do aVar <- mkFlexVar
455 bVar <- mkFlexVar
456 let aType = VarN aVar
457 let bType = VarN bVar
459 aCon <- constrain rtv a (NoExpectation aType)
460 bCon <- constrain rtv b (NoExpectation bType)
462 case maybeC of
463 Nothing ->
464 do let tupleType = TupleN aType bType Nothing
465 let tupleCon = CEqual region Tuple tupleType expected
466 return $ exists [ aVar, bVar ] $ CAnd [ aCon, bCon, tupleCon ]
468 Just c ->
469 do cVar <- mkFlexVar
470 let cType = VarN cVar
472 cCon <- constrain rtv c (NoExpectation cType)
474 let tupleType = TupleN aType bType (Just cType)
475 let tupleCon = CEqual region Tuple tupleType expected
477 return $ exists [ aVar, bVar, cVar ] $ CAnd [ aCon, bCon, cCon, tupleCon ]
481-- CONSTRAIN SHADER
484constrainShader :: R.Region -> Shader.Shader -> Expected Type -> IO Constraint
485constrainShader region (Shader.Shader attributes uniforms varyings) expected =
486 do attrVar <- mkFlexVar
487 unifVar <- mkFlexVar
488 let attrType = VarN attrVar
489 let unifType = VarN unifVar
491 let shaderType =
492 AppN ModuleName.webgl N.shader
493 [ toShaderRecord attributes attrType
494 , toShaderRecord uniforms unifType
495 , toShaderRecord varyings EmptyRecordN
496 ]
498 return $ exists [ attrVar, unifVar ] $
499 CEqual region Shader shaderType expected
502toShaderRecord :: Map.Map N.Name Shader.Type -> Type -> Type
503toShaderRecord types baseRecType =
504 if Map.null types then
505 baseRecType
506 else
507 RecordN (Map.map glToType types) baseRecType
510glToType :: Shader.Type -> Type
511glToType glType =
512 case glType of
513 Shader.V2 -> Type.vec2
514 Shader.V3 -> Type.vec3
515 Shader.V4 -> Type.vec4
516 Shader.M4 -> Type.mat4
517 Shader.Int -> Type.int
518 Shader.Float -> Type.float
519 Shader.Texture -> Type.texture
523-- CONSTRAIN DESTRUCTURES
526constrainDestruct :: RTV -> R.Region -> Can.Pattern -> Can.Expr -> Constraint -> IO Constraint
527constrainDestruct rtv region pattern expr bodyCon =
528 do patternVar <- mkFlexVar
529 let patternType = VarN patternVar
531 (Pattern.State headers pvars revCons) <-
532 Pattern.add pattern (PNoExpectation patternType) Pattern.emptyState
534 exprCon <-
535 constrain rtv expr (FromContext region Destructure patternType)
537 return $ CLet [] (patternVar:pvars) headers (CAnd (reverse (exprCon:revCons))) bodyCon
541-- CONSTRAIN DEF
544constrainDef :: RTV -> Can.Def -> Constraint -> IO Constraint
545constrainDef rtv def bodyCon =
546 case def of
547 Can.Def (A.At region name) args expr ->
548 do (Args vars tipe resultType (Pattern.State headers pvars revCons)) <-
549 constrainArgs args
551 exprCon <-
552 constrain rtv expr (NoExpectation resultType)
554 return $
555 CLet
556 { _rigidVars = []
557 , _flexVars = vars
558 , _header = Map.singleton name (A.At region tipe)
559 , _headerCon =
560 CLet
561 { _rigidVars = []
562 , _flexVars = pvars
563 , _header = headers
564 , _headerCon = CAnd (reverse revCons)
565 , _bodyCon = exprCon
566 }
567 , _bodyCon = bodyCon
568 }
570 Can.TypedDef (A.At region name) freeVars typedArgs expr srcResultType ->
571 do let newNames = Map.difference freeVars rtv
572 newRigids <- Map.traverseWithKey (\n _ -> nameToRigid n) newNames
573 let newRtv = Map.union rtv (Map.map VarN newRigids)
575 (TypedArgs tipe resultType (Pattern.State headers pvars revCons)) <-
576 constrainTypedArgs newRtv name typedArgs srcResultType
578 let expected = FromAnnotation name (length typedArgs) TypedBody resultType
579 exprCon <-
580 constrain newRtv expr expected
582 return $
583 CLet
584 { _rigidVars = Map.elems newRigids
585 , _flexVars = []
586 , _header = Map.singleton name (A.At region tipe)
587 , _headerCon =
588 CLet
589 { _rigidVars = []
590 , _flexVars = pvars
591 , _header = headers
592 , _headerCon = CAnd (reverse revCons)
593 , _bodyCon = exprCon
594 }
595 , _bodyCon = bodyCon
596 }
600-- CONSTRAIN RECURSIVE DEFS
603data Info =
604 Info
605 { _vars :: [Variable]
606 , _cons :: [Constraint]
607 , _headers :: Map.Map N.Name (A.Located Type)
608 }
611{-# NOINLINE emptyInfo #-}
612emptyInfo :: Info
613emptyInfo =
614 Info [] [] Map.empty
617constrainRecursiveDefs :: RTV -> [Can.Def] -> Constraint -> IO Constraint
618constrainRecursiveDefs rtv defs bodyCon =
619 recDefsHelp rtv defs bodyCon emptyInfo emptyInfo
622recDefsHelp :: RTV -> [Can.Def] -> Constraint -> Info -> Info -> IO Constraint
623recDefsHelp rtv defs bodyCon rigidInfo flexInfo =
624 case defs of
625 [] ->
626 do let (Info rigidVars rigidCons rigidHeaders) = rigidInfo
627 let (Info flexVars flexCons flexHeaders ) = flexInfo
628 return $
629 CLet rigidVars [] rigidHeaders CTrue $
630 CLet [] flexVars flexHeaders (CLet [] [] flexHeaders CTrue (CAnd flexCons)) $
631 CAnd [ CAnd rigidCons, bodyCon ]
633 def : otherDefs ->
634 case def of
635 Can.Def (A.At region name) args expr ->
636 do let (Info flexVars flexCons flexHeaders) = flexInfo
638 (Args newFlexVars tipe resultType (Pattern.State headers pvars revCons)) <-
639 argsHelp args (Pattern.State Map.empty flexVars [])
641 exprCon <-
642 constrain rtv expr (NoExpectation resultType)
644 let defCon =
645 CLet
646 { _rigidVars = []
647 , _flexVars = pvars
648 , _header = headers
649 , _headerCon = CAnd (reverse revCons)
650 , _bodyCon = exprCon
651 }
653 recDefsHelp rtv otherDefs bodyCon rigidInfo $
654 Info
655 { _vars = newFlexVars
656 , _cons = defCon : flexCons
657 , _headers = Map.insert name (A.At region tipe) flexHeaders
658 }
660 Can.TypedDef (A.At region name) freeVars typedArgs expr srcResultType ->
661 do let newNames = Map.difference freeVars rtv
662 newRigids <- Map.traverseWithKey (\n _ -> nameToRigid n) newNames
663 let newRtv = Map.union rtv (Map.map VarN newRigids)
665 (TypedArgs tipe resultType (Pattern.State headers pvars revCons)) <-
666 constrainTypedArgs newRtv name typedArgs srcResultType
668 exprCon <-
669 constrain newRtv expr $
670 FromAnnotation name (length typedArgs) TypedBody resultType
672 let defCon =
673 CLet
674 { _rigidVars = []
675 , _flexVars = pvars
676 , _header = headers
677 , _headerCon = CAnd (reverse revCons)
678 , _bodyCon = exprCon
679 }
681 let (Info rigidVars rigidCons rigidHeaders) = rigidInfo
682 recDefsHelp rtv otherDefs bodyCon
683 ( Info
684 { _vars = Map.foldr (:) rigidVars newRigids
685 , _cons = defCon : rigidCons
686 , _headers = Map.insert name (A.At region tipe) rigidHeaders
687 }
688 )
689 flexInfo
693-- CONSTRAIN ARGS
696data Args =
697 Args
698 { _a_vars :: [Variable]
699 , _a_type :: Type
700 , _a_result :: Type
701 , _a_state :: Pattern.State
702 }
705constrainArgs :: [Can.Pattern] -> IO Args
706constrainArgs args =
707 argsHelp args Pattern.emptyState
710argsHelp :: [Can.Pattern] -> Pattern.State -> IO Args
711argsHelp args state =
712 case args of
713 [] ->
714 do resultVar <- mkFlexVar
715 let resultType = VarN resultVar
716 return $ Args [resultVar] resultType resultType state
718 pattern : otherArgs ->
719 do argVar <- mkFlexVar
720 let argType = VarN argVar
722 (Args vars tipe result newState) <-
723 argsHelp otherArgs =<<
724 Pattern.add pattern (PNoExpectation argType) state
726 return (Args (argVar:vars) (FunN argType tipe) result newState)
730-- CONSTRAIN TYPED ARGS
733data TypedArgs =
734 TypedArgs
735 { _t_type :: Type
736 , _t_result :: Type
737 , _t_state :: Pattern.State
738 }
741constrainTypedArgs :: Map.Map N.Name Type -> N.Name -> [(Can.Pattern, Can.Type)] -> Can.Type -> IO TypedArgs
742constrainTypedArgs rtv name args srcResultType =
743 do resultType <- Instantiate.fromSrcType rtv srcResultType
744 typedArgsHelp rtv name Index.first args resultType Pattern.emptyState
747typedArgsHelp :: Map.Map N.Name Type -> N.Name -> Index.ZeroBased -> [(Can.Pattern, Can.Type)] -> Type -> Pattern.State -> IO TypedArgs
748typedArgsHelp rtv name index args resultType state =
749 case args of
750 [] ->
751 return $ TypedArgs resultType resultType state
753 (pattern@(A.At region _), srcType) : otherArgs ->
754 do argType <- Instantiate.fromSrcType rtv srcType
755 let expected = PFromContext region (PTypedArg name index) argType
757 (TypedArgs tipe result newState) <-
758 typedArgsHelp rtv name (Index.next index) otherArgs resultType =<<
759 Pattern.add pattern expected state
761 return (TypedArgs (FunN argType tipe) result newState)