@@ -3,6 +3,7 @@ mod flow;
33pub mod function;
44mod lower;
55mod operator;
6+ mod pfc;
67pub mod registry;
78pub mod schema;
89mod shell;
@@ -19,6 +20,7 @@ use crate::typing::flow::{ascribe_control, ascribe_while};
1920use crate :: typing:: function:: Function ;
2021use crate :: typing:: lower:: { ascribe_template_string, coerce_condition} ;
2122use crate :: typing:: operator:: ascribe_binary;
23+ use crate :: typing:: pfc:: ascribe_pfc;
2224use crate :: typing:: registry:: { FunctionId , Registry , SchemaId } ;
2325use crate :: typing:: schema:: Schema ;
2426use crate :: typing:: shell:: {
@@ -490,186 +492,8 @@ fn ascribe_type(
490492 Expr :: Parenthesis ( paren) => {
491493 ascribe_type ( & paren. expression , table, checker, storage, ctx, errors)
492494 }
493- Expr :: ProgrammaticCall ( ProgrammaticCall {
494- path,
495- arguments,
496- type_parameters,
497- segment : span,
498- } ) => {
499- let arguments = arguments
500- . iter ( )
501- . map ( |expr| ascribe_type ( expr, table, checker, storage, ctx, errors) )
502- . collect :: < Vec < _ > > ( ) ;
503- let ty = lookup_path (
504- path,
505- SymbolRegistry :: Function ,
506- table,
507- checker,
508- modules,
509- errors,
510- ) ;
511- if ty. is_err ( ) {
512- return TypedExpr {
513- kind : ExprKind :: Noop ,
514- span : span. clone ( ) ,
515- ty : ERROR_TYPE ,
516- } ;
517- }
518- let mut type_parameters = type_parameters
519- . iter ( )
520- . map ( |type_param| lookup_type ( type_param, table, checker, modules, errors) )
521- . collect :: < Vec < TypeId > > ( ) ;
522- let UserType :: Function ( function) = checker. types [ ty] else {
523- panic ! (
524- "function should have a function type {ty:?} {:?}" ,
525- & checker. types[ ty]
526- ) ;
527- } ;
528- let Function {
529- ref declared_at,
530- fqn : _,
531- ref generic_variables,
532- ref param_types,
533- return_type,
534- kind : _,
535- } = checker. registry [ function] ;
536- let mut return_type = return_type;
537- if type_parameters. is_empty ( ) && !generic_variables. is_empty ( ) {
538- // Try to infer the generic types from the actual arguments
539- type_parameters = vec ! [ UNKNOWN_TYPE ; generic_variables. len( ) ] ;
540- for ( arg, param) in arguments. iter ( ) . zip ( param_types. iter ( ) ) {
541- if let Some ( generic_variable) =
542- generic_variables. iter ( ) . position ( |& ty| ty == param. ty )
543- {
544- if type_parameters[ generic_variable] != UNKNOWN_TYPE
545- && type_parameters[ generic_variable] != arg. ty
546- {
547- errors. push ( TypeError :: new (
548- TypeErrorKind :: TypeMismatch {
549- expected : checker. display ( type_parameters[ generic_variable] ) ,
550- expected_due_to : None ,
551- actual : checker. display ( arg. ty ) ,
552- } ,
553- SourceLocation :: new ( table. path ( ) . to_owned ( ) , arg. span . clone ( ) ) ,
554- ) ) ;
555- } else {
556- type_parameters[ generic_variable] = arg. ty ;
557- }
558- } else if let UserType :: Parametrized {
559- schema : param_schema,
560- params : param_params,
561- ..
562- } = & checker. types [ param. ty ]
563- {
564- if let UserType :: Parametrized {
565- schema,
566- params : arg_params,
567- } = & checker. types [ arg. ty ]
568- {
569- if schema == param_schema {
570- for param_param in param_params {
571- if let Some ( idx) =
572- generic_variables. iter ( ) . position ( |& ty| ty == * param_param)
573- {
574- type_parameters[ idx] . define_if_absent ( arg_params[ idx] ) ;
575- }
576- }
577- }
578- }
579- }
580- }
581- if let TypeHint :: Required ( expected_return_ty) = hint {
582- if let Some ( idx) = generic_variables. iter ( ) . position ( |& ty| ty == return_type) {
583- type_parameters[ idx] . define_if_absent ( expected_return_ty) ;
584- } else if let UserType :: Parametrized {
585- schema : expected_schema,
586- params : expected_params,
587- ..
588- } = & checker. types [ expected_return_ty]
589- {
590- if let UserType :: Parametrized {
591- schema,
592- params : fn_return_params,
593- } = & checker. types [ return_type]
594- {
595- if schema == expected_schema {
596- // First, get the index of the generic_variables in the return_params list
597- for ( fn_return_param, fn_actual) in
598- fn_return_params. iter ( ) . zip ( expected_params)
599- {
600- if let Some ( generic_idx) = generic_variables
601- . iter ( )
602- . position ( |& ty| ty == * fn_return_param)
603- {
604- type_parameters[ generic_idx] . define_if_absent ( * fn_actual) ;
605- }
606- }
607- }
608- }
609- }
610- }
611- if type_parameters. iter ( ) . any ( |ty| * ty == UNKNOWN_TYPE ) {
612- errors. push ( TypeError :: new (
613- TypeErrorKind :: TypeAnnotationRequired {
614- types : generic_variables
615- . iter ( )
616- . map ( |ty| checker. display ( * ty) )
617- . collect ( ) ,
618- insert_at : path
619- . last ( )
620- . expect ( "path should have at least one item" )
621- . segment ( )
622- . end ,
623- } ,
624- SourceLocation :: new ( table. path ( ) . to_owned ( ) , span. clone ( ) ) ,
625- ) ) ;
626- return_type = ERROR_TYPE ;
627- }
628- }
629-
630- if arguments. len ( ) != param_types. len ( ) {
631- errors. push ( TypeError :: new (
632- TypeErrorKind :: ArityMismatch {
633- expected : param_types. len ( ) ,
634- received : arguments. len ( ) ,
635- } ,
636- SourceLocation :: new ( table. path ( ) . to_owned ( ) , span. clone ( ) ) ,
637- ) ) ;
638- } else {
639- for ( arg, param) in arguments. iter ( ) . zip ( param_types. iter ( ) ) {
640- let param_ty =
641- checker
642- . types
643- . concretize ( param. ty , generic_variables, & type_parameters) ;
644- if let Err ( _) = checker. types . unify ( arg. ty , param_ty) {
645- errors. push ( TypeError :: new (
646- TypeErrorKind :: TypeMismatch {
647- expected : checker. display ( param_ty) ,
648- expected_due_to : Some ( SourceLocation :: new (
649- declared_at. clone ( ) ,
650- param. span . clone ( ) ,
651- ) ) ,
652- actual : checker. display ( arg. ty ) ,
653- } ,
654- SourceLocation :: new ( table. path ( ) . to_owned ( ) , arg. span . clone ( ) ) ,
655- ) ) ;
656- }
657- }
658- }
659- return_type =
660- checker
661- . types
662- . concretize ( return_type, generic_variables, & type_parameters) ;
663- TypedExpr {
664- kind : ExprKind :: FunctionCall ( FunctionCall {
665- arguments,
666- function_id : function,
667- } ) ,
668- span : span. clone ( ) ,
669- ty : return_type,
670- }
671- }
672495 Expr :: StructDeclaration ( decl) => TypedExpr :: noop ( decl. segment . clone ( ) ) ,
496+ Expr :: ProgrammaticCall ( call) => ascribe_pfc ( call, table, checker, storage, ctx, errors) ,
673497 Expr :: FieldAccess ( FieldAccess {
674498 expr,
675499 field,
0 commit comments