on f4401ac help sign in
elk/compiler/src/Type/Constrain/Expression.hs
746 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
11import qualified Data.Name as Name
13import qualified AST.Canonical as Can
14import qualified AST.Utils.Shader as Shader
15import qualified Data.Index as Index
16import qualified Elm.ModuleName as ModuleName
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 Type.Constrain.Pattern as Pattern
21import qualified Type.Instantiate as Instantiate
22import Type.Type as Type hiding (Descriptor(..))
26-- CONSTRAIN
29-- As we step past type annotations, the free type variables are added to
30-- the "rigid type variables" dict. Allowing sharing of rigid variables
31-- between nested type annotations.
32--
33-- So if you have a top-level type annotation like (func : a -> b) the RTV
34-- dictionary will hold variables for `a` and `b`
35--
36type RTV =
37 Map.Map Name.Name Type
40constrain :: RTV -> Can.Expr -> Expected Type -> IO Constraint
41constrain rtv (A.At region expression) expected =
42 case expression of
43 Can.VarLocal name ->
44 return (CLocal region name expected)
46 Can.VarTopLevel _ name ->
47 return (CLocal region name expected)
49 Can.VarKernel _ _ ->
50 return CTrue
52 Can.VarForeign _ name annotation ->
53 return $ CForeign region name annotation expected
55 Can.VarCtor _ _ name _ annotation ->
56 return $ CForeign region name annotation expected
58 Can.VarDebug _ name annotation ->
59 return $ CForeign region name annotation expected
61 Can.VarOperator op _ _ annotation ->
62 return $ CForeign region op annotation expected
64 Can.Str _ ->
65 return $ CEqual region String Type.string expected
67 Can.Chr _ ->
68 return $ CEqual region Char Type.char expected
70 Can.Int _ ->
71 do var <- mkFlexNumber
72 return $ exists [var] $ CEqual region E.Number (VarN var) expected
74 Can.Float _ ->
75 return $ CEqual region Float Type.float expected
77 Can.List elements ->
78 constrainList rtv region elements expected
80 Can.Negate expr ->
81 do numberVar <- mkFlexNumber
82 let numberType = VarN numberVar
83 numberCon <- constrain rtv expr (FromContext region Negate numberType)
84 let negateCon = CEqual region E.Number numberType expected
85 return $ exists [numberVar] $ CAnd [ numberCon, negateCon ]
87 Can.Binop op _ _ annotation leftExpr rightExpr ->
88 constrainBinop rtv region op annotation leftExpr rightExpr expected
90 Can.Lambda args body ->
91 constrainLambda rtv region args body expected
93 Can.Call func args ->
94 constrainCall rtv region func args expected
96 Can.If branches finally ->
97 constrainIf rtv region branches finally expected
99 Can.Case expr branches ->
100 constrainCase rtv region expr branches expected
102 Can.Let def body ->
103 constrainDef rtv def
104 =<< constrain rtv body expected
106 Can.LetRec defs body ->
107 constrainRecursiveDefs rtv defs
108 =<< constrain rtv body expected
110 Can.LetDestruct pattern expr body ->
111 constrainDestruct rtv region pattern expr
112 =<< constrain rtv body expected
114 Can.Accessor field ->
115 do extVar <- mkFlexVar
116 fieldVar <- mkFlexVar
117 let extType = VarN extVar
118 let fieldType = VarN fieldVar
119 let recordType = RecordN (Map.singleton field fieldType) extType
120 return $ exists [ fieldVar, extVar ] $
121 CEqual region (Accessor field) (FunN recordType fieldType) expected
123 Can.Access expr (A.At accessRegion field) ->
124 do extVar <- mkFlexVar
125 fieldVar <- mkFlexVar
126 let extType = VarN extVar
127 let fieldType = VarN fieldVar
128 let recordType = RecordN (Map.singleton field fieldType) extType
130 let context = RecordAccess (A.toRegion expr) (getAccessName expr) accessRegion field
131 recordCon <- constrain rtv expr (FromContext region context recordType)
133 return $ exists [ fieldVar, extVar ] $
134 CAnd
135 [ recordCon
136 , CEqual region (Access field) fieldType expected
137 ]
139 Can.Update name expr fields ->
140 constrainUpdate rtv region name expr fields expected
142 Can.Record fields ->
143 constrainRecord rtv region fields expected
145 Can.Unit ->
146 return $ CEqual region Unit UnitN expected
148 Can.Tuple a b maybeC ->
149 constrainTuple rtv region a b maybeC expected
151 Can.Shader _src types ->
152 constrainShader region types expected
156-- CONSTRAIN LAMBDA
159constrainLambda :: RTV -> A.Region -> [Can.Pattern] -> Can.Expr -> Expected Type -> IO Constraint
160constrainLambda rtv region args body expected =
161 do (Args vars tipe resultType (Pattern.State headers pvars revCons)) <-
162 constrainArgs args
164 bodyCon <-
165 constrain rtv body (NoExpectation resultType)
167 return $ exists vars $
168 CAnd
169 [ CLet
170 { _rigidVars = []
171 , _flexVars = pvars
172 , _header = headers
173 , _headerCon = CAnd (reverse revCons)
174 , _bodyCon = bodyCon
175 }
176 , CEqual region Lambda tipe expected
177 ]
181-- CONSTRAIN CALL
184constrainCall :: RTV -> A.Region -> Can.Expr -> [Can.Expr] -> Expected Type -> IO Constraint
185constrainCall rtv region func@(A.At funcRegion _) args expected =
186 do let maybeName = getName func
188 funcVar <- mkFlexVar
189 resultVar <- mkFlexVar
190 let funcType = VarN funcVar
191 let resultType = VarN resultVar
193 funcCon <- constrain rtv func (NoExpectation funcType)
195 (argVars, argTypes, argCons) <-
196 unzip3 <$> Index.indexedTraverse (constrainArg rtv region maybeName) args
198 let arityType = foldr FunN resultType argTypes
199 let category = CallResult maybeName
201 return $ exists (funcVar:resultVar:argVars) $
202 CAnd
203 [ funcCon
204 , CEqual funcRegion category funcType (FromContext region (CallArity maybeName (length args)) arityType)
205 , CAnd argCons
206 , CEqual region category resultType expected
207 ]
210constrainArg :: RTV -> A.Region -> MaybeName -> Index.ZeroBased -> Can.Expr -> IO (Variable, Type, Constraint)
211constrainArg rtv region maybeName index arg =
212 do argVar <- mkFlexVar
213 let argType = VarN argVar
214 argCon <- constrain rtv arg (FromContext region (CallArg maybeName index) argType)
215 return (argVar, argType, argCon)
218getName :: Can.Expr -> MaybeName
219getName (A.At _ expr) =
220 case expr of
221 Can.VarLocal name -> FuncName name
222 Can.VarTopLevel _ name -> FuncName name
223 Can.VarForeign _ name _ -> FuncName name
224 Can.VarCtor _ _ name _ _ -> CtorName name
225 Can.VarOperator op _ _ _ -> OpName op
226 Can.VarKernel _ name -> FuncName name
227 _ -> NoName
230getAccessName :: Can.Expr -> Maybe Name.Name
231getAccessName (A.At _ expr) =
232 case expr of
233 Can.VarLocal name -> Just name
234 Can.VarTopLevel _ name -> Just name
235 Can.VarForeign _ name _ -> Just name
236 _ -> Nothing
240-- CONSTRAIN BINOP
243constrainBinop :: RTV -> A.Region -> Name.Name -> Can.Annotation -> Can.Expr -> Can.Expr -> Expected Type -> IO Constraint
244constrainBinop rtv region op annotation leftExpr rightExpr expected =
245 do leftVar <- mkFlexVar
246 rightVar <- mkFlexVar
247 answerVar <- mkFlexVar
248 let leftType = VarN leftVar
249 let rightType = VarN rightVar
250 let answerType = VarN answerVar
251 let binopType = leftType ==> rightType ==> answerType
253 let opCon = CForeign region op annotation (NoExpectation binopType)
255 leftCon <- constrain rtv leftExpr (FromContext region (OpLeft op) leftType)
256 rightCon <- constrain rtv rightExpr (FromContext region (OpRight op) rightType)
258 return $ exists [ leftVar, rightVar, answerVar ] $
259 CAnd
260 [ opCon
261 , leftCon
262 , rightCon
263 , CEqual region (CallResult (OpName op)) answerType expected
264 ]
268-- CONSTRAIN LISTS
271constrainList :: RTV -> A.Region -> [Can.Expr] -> Expected Type -> IO Constraint
272constrainList rtv region entries expected =
273 do entryVar <- mkFlexVar
274 let entryType = VarN entryVar
275 let listType = AppN ModuleName.list Name.list [entryType]
277 entryCons <-
278 Index.indexedTraverse (constrainListEntry rtv region entryType) entries
280 return $ exists [entryVar] $
281 CAnd
282 [ CAnd entryCons
283 , CEqual region List listType expected
284 ]
287constrainListEntry :: RTV -> A.Region -> Type -> Index.ZeroBased -> Can.Expr -> IO Constraint
288constrainListEntry rtv region tipe index expr =
289 constrain rtv expr (FromContext region (ListEntry index) tipe)
293-- CONSTRAIN IF EXPRESSIONS
296constrainIf :: RTV -> A.Region -> [(Can.Expr, Can.Expr)] -> Can.Expr -> Expected Type -> IO Constraint
297constrainIf rtv region branches final expected =
298 do let boolExpect = FromContext region IfCondition Type.bool
299 let (conditions, exprs) = foldr (\(c,e) (cs,es) -> (c:cs,e:es)) ([],[final]) branches
301 condCons <-
302 traverse (\c -> constrain rtv c boolExpect) conditions
304 case expected of
305 FromAnnotation name arity _ tipe ->
306 do branchCons <- Index.indexedForA exprs $ \index expr ->
307 constrain rtv expr (FromAnnotation name arity (TypedIfBranch index) tipe)
308 return $
309 CAnd
310 [ CAnd condCons
311 , CAnd branchCons
312 ]
314 _ ->
315 do branchVar <- mkFlexVar
316 let branchType = VarN branchVar
318 branchCons <- Index.indexedForA exprs $ \index expr ->
319 constrain rtv expr (FromContext region (IfBranch index) branchType)
321 return $ exists [branchVar] $
322 CAnd
323 [ CAnd condCons
324 , CAnd branchCons
325 , CEqual region If branchType expected
326 ]
330-- CONSTRAIN CASE EXPRESSIONS
333constrainCase :: RTV -> A.Region -> Can.Expr -> [Can.CaseBranch] -> Expected Type -> IO Constraint
334constrainCase rtv region expr branches expected =
335 do ptrnVar <- mkFlexVar
336 let ptrnType = VarN ptrnVar
337 exprCon <- constrain rtv expr (NoExpectation ptrnType)
339 case expected of
340 FromAnnotation name arity _ tipe ->
341 do branchCons <- Index.indexedForA branches $ \index branch ->
342 constrainCaseBranch rtv branch
343 (PFromContext region (PCaseMatch index) ptrnType)
344 (FromAnnotation name arity (TypedCaseBranch index) tipe)
346 return $ exists [ptrnVar] $ CAnd (exprCon:branchCons)
348 _ ->
349 do branchVar <- mkFlexVar
350 let branchType = VarN branchVar
352 branchCons <- Index.indexedForA branches $ \index branch ->
353 constrainCaseBranch rtv branch
354 (PFromContext region (PCaseMatch index) ptrnType)
355 (FromContext region (CaseBranch index) branchType)
357 return $ exists [ptrnVar,branchVar] $
358 CAnd
359 [ exprCon
360 , CAnd branchCons
361 , CEqual region Case branchType expected
362 ]
365constrainCaseBranch :: RTV -> Can.CaseBranch -> PExpected Type -> Expected Type -> IO Constraint
366constrainCaseBranch rtv (Can.CaseBranch pattern expr) pExpect bExpect =
367 do (Pattern.State headers pvars revCons) <-
368 Pattern.add pattern pExpect Pattern.emptyState
370 CLet [] pvars headers (CAnd (reverse revCons))
371 <$> constrain rtv expr bExpect
375-- CONSTRAIN RECORD
378constrainRecord :: RTV -> A.Region -> Map.Map Name.Name Can.Expr -> Expected Type -> IO Constraint
379constrainRecord rtv region fields expected =
380 do dict <- traverse (constrainField rtv) fields
382 let getType (_, t, _) = t
383 let recordType = RecordN (Map.map getType dict) EmptyRecordN
384 let recordCon = CEqual region Record recordType expected
386 let vars = Map.foldr (\(v,_,_) vs -> v:vs) [] dict
387 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [recordCon] dict
389 return $ exists vars (CAnd cons)
392constrainField :: RTV -> Can.Expr -> IO (Variable, Type, Constraint)
393constrainField rtv expr =
394 do var <- mkFlexVar
395 let tipe = VarN var
396 con <- constrain rtv expr (NoExpectation tipe)
397 return (var, tipe, con)
401-- CONSTRAIN RECORD UPDATE
404constrainUpdate :: RTV -> A.Region -> Name.Name -> Can.Expr -> Map.Map Name.Name Can.FieldUpdate -> Expected Type -> IO Constraint
405constrainUpdate rtv region name expr fields expected =
406 do extVar <- mkFlexVar
407 fieldDict <- Map.traverseWithKey (constrainUpdateField rtv region) fields
409 recordVar <- mkFlexVar
410 let recordType = VarN recordVar
411 let fieldsType = RecordN (Map.map (\(_,t,_) -> t) fieldDict) (VarN extVar)
413 -- NOTE: fieldsType is separate so that Error propagates better
414 let fieldsCon = CEqual region Record recordType (NoExpectation fieldsType)
415 let recordCon = CEqual region Record recordType expected
417 let vars = Map.foldr (\(v,_,_) vs -> v:vs) [recordVar,extVar] fieldDict
418 let cons = Map.foldr (\(_,_,c) cs -> c:cs) [recordCon] fieldDict
420 con <- constrain rtv expr (FromContext region (RecordUpdateKeys name fields) recordType)
422 return $ exists vars $ CAnd (fieldsCon:con:cons)
425constrainUpdateField :: RTV -> A.Region -> Name.Name -> Can.FieldUpdate -> IO (Variable, Type, Constraint)
426constrainUpdateField rtv region field (Can.FieldUpdate _ expr) =
427 do var <- mkFlexVar
428 let tipe = VarN var
429 con <- constrain rtv expr (FromContext region (RecordUpdateValue field) tipe)
430 return (var, tipe, con)
434-- CONSTRAIN TUPLE
437constrainTuple :: RTV -> A.Region -> Can.Expr -> Can.Expr -> Maybe Can.Expr -> Expected Type -> IO Constraint
438constrainTuple rtv region a b maybeC expected =
439 do aVar <- mkFlexVar
440 bVar <- mkFlexVar
441 let aType = VarN aVar
442 let bType = VarN bVar
444 aCon <- constrain rtv a (NoExpectation aType)
445 bCon <- constrain rtv b (NoExpectation bType)
447 case maybeC of
448 Nothing ->
449 do let tupleType = TupleN aType bType Nothing
450 let tupleCon = CEqual region Tuple tupleType expected
451 return $ exists [ aVar, bVar ] $ CAnd [ aCon, bCon, tupleCon ]
453 Just c ->
454 do cVar <- mkFlexVar
455 let cType = VarN cVar
457 cCon <- constrain rtv c (NoExpectation cType)
459 let tupleType = TupleN aType bType (Just cType)
460 let tupleCon = CEqual region Tuple tupleType expected
462 return $ exists [ aVar, bVar, cVar ] $ CAnd [ aCon, bCon, cCon, tupleCon ]
466-- CONSTRAIN SHADER
469constrainShader :: A.Region -> Shader.Types -> Expected Type -> IO Constraint
470constrainShader region (Shader.Types attributes uniforms varyings) expected =
471 do attrVar <- mkFlexVar
472 unifVar <- mkFlexVar
473 let attrType = VarN attrVar
474 let unifType = VarN unifVar
476 let shaderType =
477 AppN ModuleName.webgl Name.shader
478 [ toShaderRecord attributes attrType
479 , toShaderRecord uniforms unifType
480 , toShaderRecord varyings EmptyRecordN
481 ]
483 return $ exists [ attrVar, unifVar ] $
484 CEqual region Shader shaderType expected
487toShaderRecord :: Map.Map Name.Name Shader.Type -> Type -> Type
488toShaderRecord types baseRecType =
489 if Map.null types then
490 baseRecType
491 else
492 RecordN (Map.map glToType types) baseRecType
495glToType :: Shader.Type -> Type
496glToType glType =
497 case glType of
498 Shader.V2 -> Type.vec2
499 Shader.V3 -> Type.vec3
500 Shader.V4 -> Type.vec4
501 Shader.M4 -> Type.mat4
502 Shader.Int -> Type.int
503 Shader.Float -> Type.float
504 Shader.Texture -> Type.texture
508-- CONSTRAIN DESTRUCTURES
511constrainDestruct :: RTV -> A.Region -> Can.Pattern -> Can.Expr -> Constraint -> IO Constraint
512constrainDestruct rtv region pattern expr bodyCon =
513 do patternVar <- mkFlexVar
514 let patternType = VarN patternVar
516 (Pattern.State headers pvars revCons) <-
517 Pattern.add pattern (PNoExpectation patternType) Pattern.emptyState
519 exprCon <-
520 constrain rtv expr (FromContext region Destructure patternType)
522 return $ CLet [] (patternVar:pvars) headers (CAnd (reverse (exprCon:revCons))) bodyCon
526-- CONSTRAIN DEF
529constrainDef :: RTV -> Can.Def -> Constraint -> IO Constraint
530constrainDef rtv def bodyCon =
531 case def of
532 Can.Def (A.At region name) args expr ->
533 do (Args vars tipe resultType (Pattern.State headers pvars revCons)) <-
534 constrainArgs args
536 exprCon <-
537 constrain rtv expr (NoExpectation resultType)
539 return $
540 CLet
541 { _rigidVars = []
542 , _flexVars = vars
543 , _header = Map.singleton name (A.At region tipe)
544 , _headerCon =
545 CLet
546 { _rigidVars = []
547 , _flexVars = pvars
548 , _header = headers
549 , _headerCon = CAnd (reverse revCons)
550 , _bodyCon = exprCon
551 }
552 , _bodyCon = bodyCon
553 }
555 Can.TypedDef (A.At region name) freeVars typedArgs expr srcResultType ->
556 do let newNames = Map.difference freeVars rtv
557 newRigids <- Map.traverseWithKey (\n _ -> nameToRigid n) newNames
558 let newRtv = Map.union rtv (Map.map VarN newRigids)
560 (TypedArgs tipe resultType (Pattern.State headers pvars revCons)) <-
561 constrainTypedArgs newRtv name typedArgs srcResultType
563 let expected = FromAnnotation name (length typedArgs) TypedBody resultType
564 exprCon <-
565 constrain newRtv expr expected
567 return $
568 CLet
569 { _rigidVars = Map.elems newRigids
570 , _flexVars = []
571 , _header = Map.singleton name (A.At region tipe)
572 , _headerCon =
573 CLet
574 { _rigidVars = []
575 , _flexVars = pvars
576 , _header = headers
577 , _headerCon = CAnd (reverse revCons)
578 , _bodyCon = exprCon
579 }
580 , _bodyCon = bodyCon
581 }
585-- CONSTRAIN RECURSIVE DEFS
588data Info =
589 Info
590 { _vars :: [Variable]
591 , _cons :: [Constraint]
592 , _headers :: Map.Map Name.Name (A.Located Type)
593 }
596{-# NOINLINE emptyInfo #-}
597emptyInfo :: Info
598emptyInfo =
599 Info [] [] Map.empty
602constrainRecursiveDefs :: RTV -> [Can.Def] -> Constraint -> IO Constraint
603constrainRecursiveDefs rtv defs bodyCon =
604 recDefsHelp rtv defs bodyCon emptyInfo emptyInfo
607recDefsHelp :: RTV -> [Can.Def] -> Constraint -> Info -> Info -> IO Constraint
608recDefsHelp rtv defs bodyCon rigidInfo flexInfo =
609 case defs of
610 [] ->
611 do let (Info rigidVars rigidCons rigidHeaders) = rigidInfo
612 let (Info flexVars flexCons flexHeaders ) = flexInfo
613 return $
614 CLet rigidVars [] rigidHeaders CTrue $
615 CLet [] flexVars flexHeaders (CLet [] [] flexHeaders CTrue (CAnd flexCons)) $
616 CAnd [ CAnd rigidCons, bodyCon ]
618 def : otherDefs ->
619 case def of
620 Can.Def (A.At region name) args expr ->
621 do let (Info flexVars flexCons flexHeaders) = flexInfo
623 (Args newFlexVars tipe resultType (Pattern.State headers pvars revCons)) <-
624 argsHelp args (Pattern.State Map.empty flexVars [])
626 exprCon <-
627 constrain rtv expr (NoExpectation resultType)
629 let defCon =
630 CLet
631 { _rigidVars = []
632 , _flexVars = pvars
633 , _header = headers
634 , _headerCon = CAnd (reverse revCons)
635 , _bodyCon = exprCon
636 }
638 recDefsHelp rtv otherDefs bodyCon rigidInfo $
639 Info
640 { _vars = newFlexVars
641 , _cons = defCon : flexCons
642 , _headers = Map.insert name (A.At region tipe) flexHeaders
643 }
645 Can.TypedDef (A.At region name) freeVars typedArgs expr srcResultType ->
646 do let newNames = Map.difference freeVars rtv
647 newRigids <- Map.traverseWithKey (\n _ -> nameToRigid n) newNames
648 let newRtv = Map.union rtv (Map.map VarN newRigids)
650 (TypedArgs tipe resultType (Pattern.State headers pvars revCons)) <-
651 constrainTypedArgs newRtv name typedArgs srcResultType
653 exprCon <-
654 constrain newRtv expr $
655 FromAnnotation name (length typedArgs) TypedBody resultType
657 let defCon =
658 CLet
659 { _rigidVars = []
660 , _flexVars = pvars
661 , _header = headers
662 , _headerCon = CAnd (reverse revCons)
663 , _bodyCon = exprCon
664 }
666 let (Info rigidVars rigidCons rigidHeaders) = rigidInfo
667 recDefsHelp rtv otherDefs bodyCon
668 ( Info
669 { _vars = Map.foldr (:) rigidVars newRigids
670 , _cons = CLet (Map.elems newRigids) [] Map.empty defCon CTrue : rigidCons
671 , _headers = Map.insert name (A.At region tipe) rigidHeaders
672 }
673 )
674 flexInfo
678-- CONSTRAIN ARGS
681data Args =
682 Args
683 { _a_vars :: [Variable]
684 , _a_type :: Type
685 , _a_result :: Type
686 , _a_state :: Pattern.State
687 }
690constrainArgs :: [Can.Pattern] -> IO Args
691constrainArgs args =
692 argsHelp args Pattern.emptyState
695argsHelp :: [Can.Pattern] -> Pattern.State -> IO Args
696argsHelp args state =
697 case args of
698 [] ->
699 do resultVar <- mkFlexVar
700 let resultType = VarN resultVar
701 return $ Args [resultVar] resultType resultType state
703 pattern : otherArgs ->
704 do argVar <- mkFlexVar
705 let argType = VarN argVar
707 (Args vars tipe result newState) <-
708 argsHelp otherArgs =<<
709 Pattern.add pattern (PNoExpectation argType) state
711 return (Args (argVar:vars) (FunN argType tipe) result newState)
715-- CONSTRAIN TYPED ARGS
718data TypedArgs =
719 TypedArgs
720 { _t_type :: Type
721 , _t_result :: Type
722 , _t_state :: Pattern.State
723 }
726constrainTypedArgs :: Map.Map Name.Name Type -> Name.Name -> [(Can.Pattern, Can.Type)] -> Can.Type -> IO TypedArgs
727constrainTypedArgs rtv name args srcResultType =
728 typedArgsHelp rtv name Index.first args srcResultType Pattern.emptyState
731typedArgsHelp :: Map.Map Name.Name Type -> Name.Name -> Index.ZeroBased -> [(Can.Pattern, Can.Type)] -> Can.Type -> Pattern.State -> IO TypedArgs
732typedArgsHelp rtv name index args srcResultType state =
733 case args of
734 [] ->
735 do resultType <- Instantiate.fromSrcType rtv srcResultType
736 return $ TypedArgs resultType resultType state
738 (pattern@(A.At region _), srcType) : otherArgs ->
739 do argType <- Instantiate.fromSrcType rtv srcType
740 let expected = PFromContext region (PTypedArg name index) argType
742 (TypedArgs tipe resultType newState) <-
743 typedArgsHelp rtv name (Index.next index) otherArgs srcResultType =<<
744 Pattern.add pattern expected state
746 return (TypedArgs (FunN argType tipe) resultType newState)